Re: [PATCH] fs/xattr: Fix handling of AT_FDCWD in setxattrat(2) and getxattrat(2)

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

 



On Fri 25-04-25 10:45:22, Christian Brauner wrote:
> On Thu, Apr 24, 2025 at 05:45:17PM +0200, Mateusz Guzik wrote:
> > On Thu, Apr 24, 2025 at 03:22:47PM +0200, Jan Kara wrote:
> > > Currently, setxattrat(2) and getxattrat(2) are wrongly handling the
> > > calls of the from setxattrat(AF_FDCWD, NULL, AT_EMPTY_PATH, ...) and
> > > fail with -EBADF error instead of operating on CWD. Fix it.
> > > 
> > > Fixes: 6140be90ec70 ("fs/xattr: add *at family syscalls")
> > > Signed-off-by: Jan Kara <jack@xxxxxxx>
> > > ---
> > >  fs/xattr.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/fs/xattr.c b/fs/xattr.c
> > > index 02bee149ad96..fabb2a04501e 100644
> > > --- a/fs/xattr.c
> > > +++ b/fs/xattr.c
> > > @@ -703,7 +703,7 @@ static int path_setxattrat(int dfd, const char __user *pathname,
> > >  		return error;
> > >  
> > >  	filename = getname_maybe_null(pathname, at_flags);
> > > -	if (!filename) {
> > > +	if (!filename && dfd >= 0) {
> > >  		CLASS(fd, f)(dfd);
> > >  		if (fd_empty(f))
> > >  			error = -EBADF;
> > > @@ -847,7 +847,7 @@ static ssize_t path_getxattrat(int dfd, const char __user *pathname,
> > >  		return error;
> > >  
> > >  	filename = getname_maybe_null(pathname, at_flags);
> > > -	if (!filename) {
> > > +	if (!filename && dfd >= 0) {
> > >  		CLASS(fd, f)(dfd);
> > >  		if (fd_empty(f))
> > >  			return -EBADF;
> > 
> > Is there any code which legitimately does not follow this pattern?
> > 
> > With some refactoring getname_maybe_null() could handle the fd thing,
> > notably return the NULL pointer if the name is empty. This could bring
> > back the invariant that the path argument is not NULL.
> > 
> > Something like this:
> > static inline struct filename *getname_maybe_null(int fd, const char __user *name, int flags)
> > {
> >         if (!(flags & AT_EMPTY_PATH))
> >                 return getname(name);
> > 
> >         if (!name && fd >= 0)
> >                 return NULL;
> >         return __getname_maybe_null(fd, name);
> > }
> > 
> > struct filename *__getname_maybe_null(int fd, const char __user *pathname)
> > {
> >         char c;
> > 
> >         if (fd >= 0) {
> >                 /* try to save on allocations; loss on um, though */
> >                 if (get_user(c, pathname))
> >                         return ERR_PTR(-EFAULT);
> >                 if (!c)
> >                         return NULL;
> >         }
> > 
> > 	/* we alloc suffer the allocation of the buffer. worst case, if
> > 	 * the name turned empty in the meantime, we return it and
> > 	 * handle it the old-fashioned way.
> > 	 /
> >         return getname_flags(pathname, LOOKUP_EMPTY);
> > }
> > 
> > Then callers would look like this:
> > filename = getname_maybe_null(dfd, pathname, at_flags);
> > if (!filename) {
> > 	/* fd handling goes here */
> > 	CLASS(fd, f)(dfd);
> > 	....
> > 
> > } else {
> > 	/* regular path handling goes here */
> > }
> > 
> > 
> > set_nameidata() would lose this branch:
> > p->pathname = likely(name) ? name->name : "";
> > 
> > and putname would convert IS_ERR_OR_NULL (which is 2 branches) into one,
> > maybe like so:
> > -       if (IS_ERR_OR_NULL(name))
> > +       VFS_BUG_ON(!name);
> > +
> > +       if (IS_ERR(name))
> >                 return;
> > 
> > i think this would be an ok cleanup
> 
> Not opposed, but please for -next and Jan's thing as a backportable fix,
> please. Thanks!

Exactly, I agree the code is pretty subtle and ugly. It shouldn't take
several engineers to properly call a function to lookup a file :) So
some cleanup and refactoring is definitely long overdue but for now I
wanted some minimal fix which is easy to backport to stable.

When we speak about refactoring: Is there a reason why user_path_at()
actually doesn't handle NULL 'name' as empty like we do it in *xattrat()
syscalls? I understand this will make all _at() syscalls accept NULL name
with AT_EMPTY_PATH but is that a problem?

								Honza

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




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

  Powered by Linux