> However, this behavior change is something that I did ask for,
but it should be
> done is a separate commit:
>
> /* These are NOT bitwise flags. Both bits can be used together. */
> #define FAN_TEST 0x00
> #define FAN_ALLOW 0x01
> #define FAN_DENY 0x02
> #define FANOTIFY_RESPONSE_ACCESS \
> (FAN_TEST|FAN_ALLOW | FAN_DENY)
>
> ...
> int access = response & FANOTIFY_RESPONSE_ACCESS;
>
> 1. Do return EINVAL for access == 0
Going back to the original code will do that.
Oops, this was supposed to be Do NOT return EINVAL for access == 0
this is the case of FAN_TEST.
The patch I posted later explains that better.
> 2. Let all the rest of the EINVAL checks run (including extra type)
> 3. Move if (fd < 0) to last check
> 4. Add if (!access) return 0 before if (fd < 0)
>
> That will provide a mechanism for userspace to probe the
> kernel support for extra types in general and specific types
> that it may respond with.
I'm still resisting the idea of the TEST flag... It seems like an
unneeded extra step and complication...
Please reply to the patch I posted as a reply as point
at said complication. There is no extra step.
The simple presence of the FAN_EXTRA flag should sort it out and could
even make TEST one of the types.
I think you've missed the point of the TEST response code.
The point of the TEST response code is to test whether the
extra type is supported, so TESTS cannot be a type.
You should not think of FAN_TEST as a flag at all, in
fact, it is semantic and can be omitted altogether.
The core of the idea is that:
int access = response & FANOTIFY_RESPONSE_ACCESS;
access is an enum, not a bitwise mask, much like:
unsigned int class = flags & FANOTIFY_CLASS_BITS;
unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
At the moment, userspace must provide a valid access code
either ALLOW or DENY.
Providing no access code (0) is not valid.
I suggest making FAN_EXTRA with no access code a valid
response for testing the EXTRA types support.
(please refer to the patch)
[...]
> > + * size is determined by the extra information type.
> > + *
> > + * If the context type is Rule, then the context following is the rule number
> > + * that triggered the user space decision.
> > + */
> > +
> > +#define FAN_RESPONSE_INFO_NONE 0
> > +#define FAN_RESPONSE_INFO_AUDIT_RULE 1
> > +
> > +union fanotify_response_extra {
> > + __u32 audit_rule;
> > +};
> > +
> > struct fanotify_response {
> > __s32 fd;
> > __u32 response;
> > + __u32 extra_info_type;
> > + union fanotify_response_extra extra_info;
>
> IIRC, Jan wanted this to be a variable size record with info_type and info_len.
Again, the intent was to make it fixed for now and change it later if
needed, but that was a shortsighted approach...
I don't see a need for a len in all response types. _NONE doesn't need
any. _AUDIT_RULE is known to be 32 bits. Other types can define their
size and layout as needed, including a len field if it is needed.
len is part of a common response info header.
It is meant to make writing generic code.
So Jan's email.
> I don't know if we want to make this flexible enough to
allow for multiple
> records in the future like we do in events, but the common wisdom of
> the universe says that if we don't do it, we will need it.
It did occur to me that this could be used for other than audit, hence
the renaming of the ..."_NONE" macro.
We should be able in the future to define a type that is extensible or
has multiple records. We have (2^32) - 2 types left to work with.
The way this was done when we first introduced event info
records was the same. We only allowed one type of record
and a single record to begin with, but the format allowed for
extending to multiple records.
struct fanotify_event_metadata already had event_len and
metadata_len, so that was convenient. Supporting multi
records only required that every record has a header with its
own len.
As far as I can tell, the case of fanotify_response is different
because we have the count argument of write(), which serves
as the total response_len.
If we ever want to be able to extend the base fanotify_response,
add fields to it not as extra info records, then we need to add
response_metadata_len to struct fanotify_response, but I think that
would be over design.
Thanks,
Amir.