Re: [PATCH v4 06/15] fanotify: encode file identifier for FAN_REPORT_FID

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun 02-12-18 13:38:17, Amir Goldstein wrote:
> When user requests the flag FAN_REPORT_FID in fanotify_init(),
> a unique file indetifier of the event target object will be reported
                ^^^ identifier

> with the event.
> 
> The file identifier includes the filesystem's fsid (i.e. from statfs(2))
> and an NFS file handle of the file (i.e. from name_to_handle_at(2)).
> 
> The file identifier makes holding the path reference and passing a file
> descriptor to user redundant, so those are disabled in a group with
> FAN_REPORT_FID.
> 
> Encode fid and store it in event for a group with FAN_REPORT_FID.
> Up to 12 bytes of file handle on 32bit arch (16 bytes on 64bit arch)
> are stored inline in fanotify_event struct. Larger file handles are
> stored in an extennal allocated buffer.
               ^^^ external

> On failure to encode fid, we print a warning and queue the event
> without the fid information.
> 
> Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>

The patch looks good. Just some nits below:

> +static int fanotify_encode_fid(struct fanotify_event *event,
> +			       const struct path *path, gfp_t gfp)
> +{
> +	struct fanotify_fid *fid = &event->fid;
> +	int dwords, bytes = 0;
> +	struct kstatfs stat;
> +	int err, type;
> +
> +	stat.f_fsid.val[0] = stat.f_fsid.val[1] = 0;
> +	fid->ext_fh = NULL;
> +	dwords = 0;
> +	err = -ENOENT;
> +	type = exportfs_encode_fh(path->dentry, NULL, &dwords,  0);
> +	if (!dwords)
> +		goto out_err;
> +
> +	err = vfs_statfs(path, &stat);
> +	if (err)
> +		goto out_err;
> +
> +	bytes = dwords << 2;
> +	if (!fanotify_inline_fh_len(bytes)) {

I'd just remove this helper. Direct comparison against FANOTIFY_INLINE_FH_LEN
is clearer and I don't see a benefit of the wrapper.

> +		/* Treat failure to allocate fh as failure to allocate event */
> +		err = -ENOMEM;
> +		fid->ext_fh = kmalloc(bytes, gfp);
> +		if (!fid->ext_fh)
> +			goto out_err;
> +	}
> +
> +	type = exportfs_encode_fh(path->dentry, fanotify_fid_fh(fid, bytes),
> +				  &dwords,  0);
> +	err = -EINVAL;
> +	if (!type || type == FILEID_INVALID || bytes != dwords << 2)
> +		goto out_err;
> +
> +	fid->fsid = stat.f_fsid;
> +	event->fh_len = bytes;
> +
> +	return type;
> +
> +out_err:
> +	pr_warn_ratelimited("fanotify: failed to encode fid (fsid=%x.%x, type=%d, bytes=%d, err=%i)\n",
> +			    stat.f_fsid.val[0], stat.f_fsid.val[1],
> +			    type, bytes, err);
> +	kfree(fid->ext_fh);
> +	fid->ext_fh = NULL;
> +	event->fh_len = 0;
> +
> +	return FILEID_INVALID;
> +}
> +
>  struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
>  						 struct inode *inode, u32 mask,
>  						 const struct path *path)
> @@ -181,10 +241,16 @@ init: __maybe_unused
>  		event->pid = get_pid(task_pid(current));
>  	else
>  		event->pid = get_pid(task_tgid(current));
> -	if (path) {
> +	event->fh_len = 0;
> +	if (path && FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
> +		/* Report the event without a file identifier on encode error */
> +		event->fh_type = fanotify_encode_fid(event, path, gfp);
> +	} else if (path) {
> +		event->fh_type = 0;

Maybe using FILEID_ROOT here and in other places like the test in
fanotify_encode_fid(), fanotify_event_has_path(), etc. would make it more
obvious that there cannot be a random clash with some real fh type? At
least I had to look it up in the exportfs code...

>  		event->path = *path;
>  		path_get(&event->path);
>  	} else {
> +		event->fh_type = FILEID_INVALID;
>  		event->path.mnt = NULL;
>  		event->path.dentry = NULL;
>  	}

								Honza
-- 
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux