@@ -744,80 +744,85 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
744744/*
745745 * Extended attribute GET operations
746746 */
747- ssize_t
747+ static ssize_t
748748do_getxattr (struct mnt_idmap * idmap , struct dentry * d ,
749749 struct kernel_xattr_ctx * ctx )
750750{
751751 ssize_t error ;
752752 char * kname = ctx -> kname -> name ;
753+ void * kvalue = NULL ;
753754
754755 if (ctx -> size ) {
755756 if (ctx -> size > XATTR_SIZE_MAX )
756757 ctx -> size = XATTR_SIZE_MAX ;
757- ctx -> kvalue = kvzalloc (ctx -> size , GFP_KERNEL );
758- if (!ctx -> kvalue )
758+ kvalue = kvzalloc (ctx -> size , GFP_KERNEL );
759+ if (!kvalue )
759760 return - ENOMEM ;
760761 }
761762
762- if (is_posix_acl_xattr (ctx -> kname -> name ))
763- error = do_get_acl (idmap , d , kname , ctx -> kvalue , ctx -> size );
763+ if (is_posix_acl_xattr (kname ))
764+ error = do_get_acl (idmap , d , kname , kvalue , ctx -> size );
764765 else
765- error = vfs_getxattr (idmap , d , kname , ctx -> kvalue , ctx -> size );
766+ error = vfs_getxattr (idmap , d , kname , kvalue , ctx -> size );
766767 if (error > 0 ) {
767- if (ctx -> size && copy_to_user (ctx -> value , ctx -> kvalue , error ))
768+ if (ctx -> size && copy_to_user (ctx -> value , kvalue , error ))
768769 error = - EFAULT ;
769770 } else if (error == - ERANGE && ctx -> size >= XATTR_SIZE_MAX ) {
770771 /* The file system tried to returned a value bigger
771772 than XATTR_SIZE_MAX bytes. Not possible. */
772773 error = - E2BIG ;
773774 }
774775
776+ kvfree (kvalue );
775777 return error ;
776778}
777779
778- static ssize_t
779- getxattr (struct mnt_idmap * idmap , struct dentry * d ,
780- const char __user * name , void __user * value , size_t size )
780+ ssize_t file_getxattr (struct file * f , struct kernel_xattr_ctx * ctx )
781781{
782- ssize_t error ;
783- struct xattr_name kname ;
784- struct kernel_xattr_ctx ctx = {
785- .value = value ,
786- .kvalue = NULL ,
787- .size = size ,
788- .kname = & kname ,
789- .flags = 0 ,
790- };
791-
792- error = import_xattr_name (& kname , name );
793- if (error )
794- return error ;
795-
796- error = do_getxattr (idmap , d , & ctx );
797-
798- kvfree (ctx .kvalue );
799- return error ;
782+ audit_file (f );
783+ return do_getxattr (file_mnt_idmap (f ), f -> f_path .dentry , ctx );
800784}
801785
802- static ssize_t path_getxattr ( const char __user * pathname ,
803- const char __user * name , void __user * value ,
804- size_t size , unsigned int lookup_flags )
786+ /* unconditionally consumes filename */
787+ ssize_t filename_getxattr ( int dfd , struct filename * filename ,
788+ unsigned int lookup_flags , struct kernel_xattr_ctx * ctx )
805789{
806790 struct path path ;
807791 ssize_t error ;
808792retry :
809- error = user_path_at ( AT_FDCWD , pathname , lookup_flags , & path );
793+ error = filename_lookup ( dfd , filename , lookup_flags , & path , NULL );
810794 if (error )
811- return error ;
812- error = getxattr (mnt_idmap (path .mnt ), path .dentry , name , value , size );
795+ goto out ;
796+ error = do_getxattr (mnt_idmap (path .mnt ), path .dentry , ctx );
813797 path_put (& path );
814798 if (retry_estale (error , lookup_flags )) {
815799 lookup_flags |= LOOKUP_REVAL ;
816800 goto retry ;
817801 }
802+ out :
803+ putname (filename );
818804 return error ;
819805}
820806
807+ static ssize_t path_getxattr (const char __user * pathname ,
808+ const char __user * name , void __user * value ,
809+ size_t size , unsigned int lookup_flags )
810+ {
811+ ssize_t error ;
812+ struct xattr_name kname ;
813+ struct kernel_xattr_ctx ctx = {
814+ .value = value ,
815+ .size = size ,
816+ .kname = & kname ,
817+ .flags = 0 ,
818+ };
819+
820+ error = import_xattr_name (& kname , name );
821+ if (error )
822+ return error ;
823+ return filename_getxattr (AT_FDCWD , getname (pathname ), lookup_flags , & ctx );
824+ }
825+
821826SYSCALL_DEFINE4 (getxattr , const char __user * , pathname ,
822827 const char __user * , name , void __user * , value , size_t , size )
823828{
@@ -833,13 +838,22 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
833838SYSCALL_DEFINE4 (fgetxattr , int , fd , const char __user * , name ,
834839 void __user * , value , size_t , size )
835840{
841+ ssize_t error ;
842+ struct xattr_name kname ;
843+ struct kernel_xattr_ctx ctx = {
844+ .value = value ,
845+ .size = size ,
846+ .kname = & kname ,
847+ .flags = 0 ,
848+ };
836849 CLASS (fd , f )(fd );
837850
838851 if (fd_empty (f ))
839852 return - EBADF ;
840- audit_file (fd_file (f ));
841- return getxattr (file_mnt_idmap (fd_file (f )), fd_file (f )-> f_path .dentry ,
842- name , value , size );
853+ error = import_xattr_name (& kname , name );
854+ if (error )
855+ return error ;
856+ return file_getxattr (fd_file (f ), & ctx );
843857}
844858
845859/*
0 commit comments