@@ -744,80 +744,85 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
744
744
/*
745
745
* Extended attribute GET operations
746
746
*/
747
- ssize_t
747
+ static ssize_t
748
748
do_getxattr (struct mnt_idmap * idmap , struct dentry * d ,
749
749
struct kernel_xattr_ctx * ctx )
750
750
{
751
751
ssize_t error ;
752
752
char * kname = ctx -> kname -> name ;
753
+ void * kvalue = NULL ;
753
754
754
755
if (ctx -> size ) {
755
756
if (ctx -> size > XATTR_SIZE_MAX )
756
757
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 )
759
760
return - ENOMEM ;
760
761
}
761
762
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 );
764
765
else
765
- error = vfs_getxattr (idmap , d , kname , ctx -> kvalue , ctx -> size );
766
+ error = vfs_getxattr (idmap , d , kname , kvalue , ctx -> size );
766
767
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 ))
768
769
error = - EFAULT ;
769
770
} else if (error == - ERANGE && ctx -> size >= XATTR_SIZE_MAX ) {
770
771
/* The file system tried to returned a value bigger
771
772
than XATTR_SIZE_MAX bytes. Not possible. */
772
773
error = - E2BIG ;
773
774
}
774
775
776
+ kvfree (kvalue );
775
777
return error ;
776
778
}
777
779
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 )
781
781
{
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 );
800
784
}
801
785
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 )
805
789
{
806
790
struct path path ;
807
791
ssize_t error ;
808
792
retry :
809
- error = user_path_at ( AT_FDCWD , pathname , lookup_flags , & path );
793
+ error = filename_lookup ( dfd , filename , lookup_flags , & path , NULL );
810
794
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 );
813
797
path_put (& path );
814
798
if (retry_estale (error , lookup_flags )) {
815
799
lookup_flags |= LOOKUP_REVAL ;
816
800
goto retry ;
817
801
}
802
+ out :
803
+ putname (filename );
818
804
return error ;
819
805
}
820
806
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
+
821
826
SYSCALL_DEFINE4 (getxattr , const char __user * , pathname ,
822
827
const char __user * , name , void __user * , value , size_t , size )
823
828
{
@@ -833,13 +838,22 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
833
838
SYSCALL_DEFINE4 (fgetxattr , int , fd , const char __user * , name ,
834
839
void __user * , value , size_t , size )
835
840
{
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
+ };
836
849
CLASS (fd , f )(fd );
837
850
838
851
if (fd_empty (f ))
839
852
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 );
843
857
}
844
858
845
859
/*
0 commit comments