1. 28 Jul, 2010 40 commits
    • Eric Paris's avatar
      fanotify: use merge argument to determine actual event added to queue · 43ed7e16
      Eric Paris authored
      fanotify needs to know the actual event added to queues so it can be
      correctly checked for return values from userspace.  To do this we need to
      pass that information from the merger code back to the main even handling
      routine.  Currently that information is unused, but it will be.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      43ed7e16
    • Eric Paris's avatar
      fsnotify: intoduce a notification merge argument · 6e5f77b3
      Eric Paris authored
      Each group can define their own notification (and secondary_q) merge
      function.  Inotify does tail drop, fanotify does matching and drop which
      can actually allocate a completely new event.  But for fanotify to properly
      deal with permissions events it needs to know the new event which was
      ultimately added to the notification queue.  This patch just implements a
      void ** argument which is passed to the merge function.  fanotify can use
      this field to pass the new event back to higher layers.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      for fanotify to properly deal with permissions events
      6e5f77b3
    • Eric Paris's avatar
      fsnotify: add group priorities · cb2d429f
      Eric Paris authored
      This introduces an ordering to fsnotify groups.  With purely asynchronous
      notification based "things" implementing fsnotify (inotify, dnotify) ordering
      isn't particularly important.  But if people want to use fsnotify for the
      basis of sycronous notification or blocking notification ordering becomes
      important.
      
      eg. A Hierarchical Storage Management listener would need to get its event
      before an AV scanner could get its event (since the HSM would need to
      bring the data in for the AV scanner to scan.)  Typically asynchronous notification
      would want to run after the AV scanner made any relevant access decisions
      so as to not send notification about an event that was denied.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      cb2d429f
    • Eric Paris's avatar
      fanotify: clear all fanotify marks · 4d92604c
      Eric Paris authored
      fanotify listeners may want to clear all marks.  They may want to do this
      to destroy all of their inode marks which have nothing but ignores.
      Realistically this is useful for av vendors who update policy and want to
      clear all of their cached allows.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      4d92604c
    • Eric Paris's avatar
      fanotify: allow ignored_masks to survive modify · c9778a98
      Eric Paris authored
      Some users may want to truely ignore an inode even if it has been modified.
      Say you are wanting a mount which contains a log file and you really don't
      want any notification about that file.  This patch allows the listener to
      do that.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      c9778a98
    • Eric Paris's avatar
      fsnotify: allow ignored_mask to survive modification · c908370f
      Eric Paris authored
      Some inodes a group may want to never hear about a set of events even if
      the inode is modified.  We add a new mark flag which indicates that these
      marks should not have their ignored_mask cleared on modification.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      c908370f
    • Eric Paris's avatar
      fsnotify: clear ignored mask on modify · e8983861
      Eric Paris authored
      On inode modification we clear the ignored mask for all of the marks on the
      inode.  This allows userspace to ignore accesses to inodes until there is
      something different.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      e8983861
    • Eric Paris's avatar
      fanotify: allow users to set an ignored_mask · b9e4e3bd
      Eric Paris authored
      Change the sys_fanotify_mark() system call so users can set ignored_masks
      on inodes.  Remember, if a user new sets a real mask, and only sets ignored
      masks, the ignore will never be pinned in memory.  Thus ignored_masks can
      be lost under memory pressure and the user may again get events they
      previously thought were ignored.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      b9e4e3bd
    • Eric Paris's avatar
      fanotify: ignored_mask to ignore events · 32a4df13
      Eric Paris authored
      When fanotify receives an event it will check event->mask & ~ignored_mask.
      If no bits are left the event will not be sent.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      32a4df13
    • Eric Paris's avatar
      fsnotify: ignored_mask - excluding notification · 33af5e32
      Eric Paris authored
      The ignored_mask is a new mask which is part of fsnotify marks.  A group's
      should_send_event() function can use the ignored mask to determine that
      certain events are not of interest.  In particular if a group registers a
      mask including FS_OPEN on a vfsmount they could add FS_OPEN to the
      ignored_mask for individual inodes and not send open events for those
      inodes.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      33af5e32
    • Eric Paris's avatar
      fsnotify: allow marks to not pin inodes in core · 90b1e7a5
      Eric Paris authored
      inotify marks must pin inodes in core.  dnotify doesn't technically need to
      since they are closed when the directory is closed.  fanotify also need to
      pin inodes in core as it works today.  But the next step is to introduce
      the concept of 'ignored masks' which is actually a mask of events for an
      inode of no interest.  I claim that these should be liberally sent to the
      kernel and should not pin the inode in core.  If the inode is brought back
      in the listener will get an event it may have thought excluded, but this is
      not a serious situation and one any listener should deal with.
      
      This patch lays the ground work for non-pinning inode marks by using lazy
      inode pinning.  We do not pin a mark until it has a non-zero mask entry.  If a
      listener new sets a mask we never pin the inode.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      90b1e7a5
    • Andreas Gruenbacher's avatar
      fanotify: remove outgoing function checks in fanotify.h · 33d3dfff
      Andreas Gruenbacher authored
      A number of validity checks on outgoing data are done in static inlines but
      are only used in one place.  Instead just do them where they are used for
      readability.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      33d3dfff
    • Andreas Gruenbacher's avatar
      fanotify: remove fanotify.h declarations · 88380fe6
      Andreas Gruenbacher authored
      fanotify_mark_validate functions are all needlessly declared in headers as
      static inlines.  Instead just do the checks where they are needed for code
      readability.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      88380fe6
    • Andreas Gruenbacher's avatar
      fanotify: split fanotify_remove_mark · f3640192
      Andreas Gruenbacher authored
      split fanotify_remove_mark into fanotify_remove_inode_mark and
      fanotify_remove_vfsmount_mark.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      f3640192
    • Andreas Gruenbacher's avatar
      fanotify: rename FAN_MARK_ON_VFSMOUNT to FAN_MARK_MOUNT · eac8e9e8
      Andreas Gruenbacher authored
      the term 'vfsmount' isn't sensicle to userspace.  instead call is 'mount.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      eac8e9e8
    • Eric Paris's avatar
      fanotify: hooks the fanotify_mark syscall to the vfsmount code · 0ff21db9
      Eric Paris authored
      Create a new fanotify_mark flag which indicates we should attach the mark
      to the vfsmount holding the object referenced by dfd and pathname rather
      than the inode itself.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      0ff21db9
    • Andreas Gruenbacher's avatar
      fanotify: remove fanotify_add_mark · 90dd201d
      Andreas Gruenbacher authored
      fanotify_add_mark now does nothing useful anymore, drop it.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      90dd201d
    • Andreas Gruenbacher's avatar
      fanotify: do not return pointer from fanotify_add_*_mark · 52202dfb
      Andreas Gruenbacher authored
      No need to return the mark from fanotify_add_*_mark to fanotify_add_mark
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      52202dfb
    • Andreas Gruenbacher's avatar
      fanotify: do not call fanotify_update_object_mask in fanotify_add_mark · 912ee394
      Andreas Gruenbacher authored
      Recalculate masks in fanotify_add_mark, don't use
      fanotify_update_object_mask.  This gets us one step closers to readable
      code.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      912ee394
    • Andreas Gruenbacher's avatar
      fanotify: do not call fanotify_update_object_mask in fanotify_remove_mark · 088b09b0
      Andreas Gruenbacher authored
      Recalculate masks in fanotify_remove_mark, don't use
      fanotify_update_object_mask.  This gets us one step closers to readable
      code.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      088b09b0
    • Andreas Gruenbacher's avatar
      fanotify: remove fanotify_update_mark · c6223f46
      Andreas Gruenbacher authored
      fanotify_update_mark() doesn't do much useful;  remove it.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      c6223f46
    • Eric Paris's avatar
      fanotify: infrastructure to add an remove marks on vfsmounts · 88826276
      Eric Paris authored
      infrastructure work to add and remove marks on vfsmounts.  This should get
      every set up except wiring the functions to the syscalls.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      88826276
    • Eric Paris's avatar
      fanotify: should_send_event needs to handle vfsmounts · 1c529063
      Eric Paris authored
      currently should_send_event in fanotify only cares about marks on inodes.
      This patch extends that interface to indicate that it cares about events
      that happened on vfsmounts.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      1c529063
    • Andreas Gruenbacher's avatar
      fsnotify: Infrastructure for per-mount watches · ca9c726e
      Andreas Gruenbacher authored
      Per-mount watches allow groups to listen to fsnotify events on an entire
      mount.  This patch simply adds and initializes the fields needed in the
      vfsmount struct to make this happen.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      ca9c726e
    • Eric Paris's avatar
      fsnotify: vfsmount marks generic functions · 0d48b7f0
      Eric Paris authored
      Much like inode-mark.c has all of the code dealing with marks on inodes
      this patch adds a vfsmount-mark.c which has similar code but is intended
      for marks on vfsmounts.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      0d48b7f0
    • Andreas Gruenbacher's avatar
      fsnotify/vfsmount: add fsnotify fields to struct vfsmount · 2504c5d6
      Andreas Gruenbacher authored
      This patch adds the list and mask fields needed to support vfsmount marks.
      These are the same fields fsnotify needs on an inode.  They are not used,
      just declared and we note where the cleanup hook should be (the function is
      not yet defined)
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      2504c5d6
    • Eric Paris's avatar
      fsnotify: clear marks to 0 in fsnotify_init_mark · ba643f04
      Eric Paris authored
      Currently fsnotify_init_mark sets some fields to 0/NULL.  Some users
      already used some sorts of zalloc, some didn't.  This patch uses memset to
      explicitly zero everything in the fsnotify_mark when it is initialized so we
      don't have to be careful if fields are later added to marks.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      ba643f04
    • Eric Paris's avatar
      fsnotify: split generic and inode specific mark code · 5444e298
      Eric Paris authored
      currently all marking is done by functions in inode-mark.c.  Some of this
      is pretty generic and should be instead done in a generic function and we
      should only put the inode specific code in inode-mark.c
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      5444e298
    • Andreas Gruenbacher's avatar
      fanotify: Add pids to events · 32c32632
      Andreas Gruenbacher authored
      Pass the process identifiers of the triggering processes to fanotify
      listeners: this information is useful for event filtering and logging.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      32c32632
    • Andreas Gruenbacher's avatar
      fanotify: create_fd cleanup · 22aa425d
      Andreas Gruenbacher authored
      Code cleanup which does the fd creation work seperately from the userspace
      metadata creation.  It fits better with the other code.
      Signed-off-by: default avatarAndreas Gruenbacher <agruen@suse.de>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      22aa425d
    • Heiko Carstens's avatar
      fanotify: CONFIG_HAVE_SYSCALL_WRAPPERS for sys_fanotify_mark · 9bbfc964
      Heiko Carstens authored
      Please note that you need the patch below in addition, otherwise the
      syscall wrapper stuff won't work on those 32 bit architectures which enable
      the wrappers.
      
      When enabled the syscall wrapper defines always take long parameters and then
      cast them to whatever is needed. This approach doesn't work for the 32 bit
      case where the original syscall takes a long long parameter, since we would
      lose the upper 32 bits.
      So syscalls with 64 bit arguments are special cases wrt to syscall wrappers
      and enp up in the ugliness below (see also sys_fallocate). In addition these
      special cased syscall wrappers have the drawback that ftrace syscall tracing
      doesn't work on them, since they don't get defined by using the usual macros.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      9bbfc964
    • Paul Mundt's avatar
      fanotify: select ANON_INODES. · ef601a9c
      Paul Mundt authored
      fanotify references anon_inode_getfd(), which is only available with
      ANON_INODES enabled. Presently this bails out with the following:
      
        LD      vmlinux
      fs/built-in.o: In function `sys_fanotify_init':
      (.text+0x26d1c): undefined reference to `anon_inode_getfd'
      make: *** [vmlinux] Error 1
      
      which is trivially corrected by adding an ANON_INODES select.
      Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      ef601a9c
    • Eric Paris's avatar
      fanotify: send events using read · a1014f10
      Eric Paris authored
      Send events to userspace by reading the file descriptor from fanotify_init().
      One will get blocks of data which look like:
      
      struct fanotify_event_metadata {
      	__u32 event_len;
      	__u32 vers;
      	__s32 fd;
      	__u64 mask;
      	__s64 pid;
      	__u64 cookie;
      } __attribute__ ((packed));
      
      Simple code to retrieve and deal with events is below
      
      	while ((len = read(fan_fd, buf, sizeof(buf))) > 0) {
      		struct fanotify_event_metadata *metadata;
      
      		metadata = (void *)buf;
      		while(FAN_EVENT_OK(metadata, len)) {
      			[PROCESS HERE!!]
      			if (metadata->fd >= 0 && close(metadata->fd) != 0)
      				goto fail;
      			metadata = FAN_EVENT_NEXT(metadata, len);
      		}
      	}
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      a1014f10
    • Eric Paris's avatar
      fanotify: fanotify_mark syscall implementation · 2a3edf86
      Eric Paris authored
      NAME
      	fanotify_mark - add, remove, or modify an fanotify mark on a
      filesystem object
      
      SYNOPSIS
      	int fanotify_mark(int fanotify_fd, unsigned int flags, u64 mask,
      			  int dfd, const char *pathname)
      
      DESCRIPTION
      	fanotify_mark() is used to add remove or modify a mark on a filesystem
      	object.  Marks are used to indicate that the fanotify group is
      	interested in events which occur on that object.  At this point in
      	time marks may only be added to files and directories.
      
      	fanotify_fd must be a file descriptor returned by fanotify_init()
      
      	The flags field must contain exactly one of the following:
      
      	FAN_MARK_ADD - or the bits in mask and ignored mask into the mark
      	FAN_MARK_REMOVE - bitwise remove the bits in mask and ignored mark
      		from the mark
      
      	The following values can be OR'd into the flags field:
      
      	FAN_MARK_DONT_FOLLOW - same meaning as O_NOFOLLOW as described in open(2)
      	FAN_MARK_ONLYDIR - same meaning as O_DIRECTORY as described in open(2)
      
      	dfd may be any of the following:
      	AT_FDCWD: the object will be lookup up based on pathname similar
      		to open(2)
      
      	file descriptor of a directory: if pathname is not NULL the
      		object to modify will be lookup up similar to openat(2)
      
      	file descriptor of the final object: if pathname is NULL the
      		object to modify will be the object referenced by dfd
      
      	The mask is the bitwise OR of the set of events of interest such as:
      	FAN_ACCESS		- object was accessed (read)
      	FAN_MODIFY		- object was modified (write)
      	FAN_CLOSE_WRITE		- object was writable and was closed
      	FAN_CLOSE_NOWRITE	- object was read only and was closed
      	FAN_OPEN		- object was opened
      	FAN_EVENT_ON_CHILD	- interested in objected that happen to
      				  children.  Only relavent when the object
      				  is a directory
      	FAN_Q_OVERFLOW		- event queue overflowed (not implemented)
      
      RETURN VALUE
      	On success, this system call returns 0. On error, -1 is
      	returned, and errno is set to indicate the error.
      
      ERRORS
      	EINVAL An invalid value was specified in flags.
      
      	EINVAL An invalid value was specified in mask.
      
      	EINVAL An invalid value was specified in ignored_mask.
      
      	EINVAL fanotify_fd is not a file descriptor as returned by
      	fanotify_init()
      
      	EBADF fanotify_fd is not a valid file descriptor
      
      	EBADF dfd is not a valid file descriptor and path is NULL.
      
      	ENOTDIR dfd is not a directory and path is not NULL
      
      	EACCESS no search permissions on some part of the path
      
      	ENENT file not found
      
      	ENOMEM Insufficient kernel memory is available.
      
      CONFORMING TO
      	These system calls are Linux-specific.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      2a3edf86
    • Eric Paris's avatar
      fanotify: sys_fanotify_mark declartion · bbaa4168
      Eric Paris authored
      This patch simply declares the new sys_fanotify_mark syscall
      
      int fanotify_mark(int fanotify_fd, unsigned int flags, u64_mask,
      		  int dfd const char *pathname)
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      bbaa4168
    • Eric Paris's avatar
      fanotify: fanotify_init syscall implementation · 52c923dd
      Eric Paris authored
      NAME
      	fanotify_init - initialize an fanotify group
      
      SYNOPSIS
      	int fanotify_init(unsigned int flags, unsigned int event_f_flags, int priority);
      
      DESCRIPTION
      	fanotify_init() initializes a new fanotify instance and returns a file
      	descriptor associated with the new fanotify event queue.
      
      	The following values can be OR'd into the flags field:
      
      	FAN_NONBLOCK Set the O_NONBLOCK file status flag on the new open file description.
      		Using this flag saves extra calls to fcntl(2) to achieve the same
      		result.
      
      	FAN_CLOEXEC Set the close-on-exec (FD_CLOEXEC) flag on the new file descriptor.
      		See the description of the O_CLOEXEC flag in open(2) for reasons why
      		this may be useful.
      
      	The event_f_flags argument is unused and must be set to 0
      
      	The priority argument is unused and must be set to 0
      
      RETURN VALUE
      	On success, this system call return a new file descriptor. On error, -1 is
      	returned, and errno is set to indicate the error.
      
      ERRORS
      	EINVAL An invalid value was specified in flags.
      
      	EINVAL A non-zero valid was passed in event_f_flags or in priority
      
      	ENFILE The system limit on the total number of file descriptors has been reached.
      
      	ENOMEM Insufficient kernel memory is available.
      
      CONFORMING TO
      	These system calls are Linux-specific.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      52c923dd
    • Eric Paris's avatar
      fanotify: fanotify_init syscall declaration · 11637e4b
      Eric Paris authored
      This patch defines a new syscall fanotify_init() of the form:
      
      int sys_fanotify_init(unsigned int flags, unsigned int event_f_flags,
      		      unsigned int priority)
      
      This syscall is used to create and fanotify group.  This is very similar to
      the inotify_init() syscall.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      11637e4b
    • Eric Paris's avatar
      fanotify: do not clone on merge unless needed · 9dced01a
      Eric Paris authored
      Currently if 2 events are going to be merged on the notication queue with
      different masks the second event will be cloned and will replace the first
      event.  However if this notification queue is the only place referencing
      the event in question there is no reason not to just update the event in
      place.  We can tell this if the event->refcnt == 1.  Since we hold a
      reference for each queue this event is on we know that when refcnt == 1
      this is the only queue.  The other concern is that it might be about to be
      added to a new queue, but this can't be the case since fsnotify holds a
      reference on the event until it is finished adding it to queues.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      9dced01a
    • Eric Paris's avatar
      fanotify: merge notification events with different masks · a12a7dd3
      Eric Paris authored
      Instead of just merging fanotify events if they are exactly the same, merge
      notification events with different masks.  To do this we have to clone the
      old event, update the mask in the new event with the new merged mask, and
      put the new event in place of the old event.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      a12a7dd3
    • Eric Paris's avatar
      fanotify:drop notification if they exist in the outgoing queue · 767cd46c
      Eric Paris authored
      fanotify listeners get an open file descriptor to the object in question so
      the ordering of operations is not as important as in other notification
      systems.  inotify will drop events if the last event in the event FIFO is
      the same as the current event.  This patch will drop fanotify events if
      they are the same as another event anywhere in the event FIFO.
      Signed-off-by: default avatarEric Paris <eparis@redhat.com>
      767cd46c