@@ -671,11 +671,18 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
671
671
return err ;
672
672
}
673
673
674
- static int do_fchmodat (int dfd , const char __user * filename , umode_t mode )
674
+ static int do_fchmodat (int dfd , const char __user * filename , umode_t mode ,
675
+ unsigned int flags )
675
676
{
676
677
struct path path ;
677
678
int error ;
678
- unsigned int lookup_flags = LOOKUP_FOLLOW ;
679
+ unsigned int lookup_flags ;
680
+
681
+ if (unlikely (flags & ~AT_SYMLINK_NOFOLLOW ))
682
+ return - EINVAL ;
683
+
684
+ lookup_flags = (flags & AT_SYMLINK_NOFOLLOW ) ? 0 : LOOKUP_FOLLOW ;
685
+
679
686
retry :
680
687
error = user_path_at (dfd , filename , lookup_flags , & path );
681
688
if (!error ) {
@@ -689,15 +696,21 @@ static int do_fchmodat(int dfd, const char __user *filename, umode_t mode)
689
696
return error ;
690
697
}
691
698
699
+ SYSCALL_DEFINE4 (fchmodat2 , int , dfd , const char __user * , filename ,
700
+ umode_t , mode , unsigned int , flags )
701
+ {
702
+ return do_fchmodat (dfd , filename , mode , flags );
703
+ }
704
+
692
705
SYSCALL_DEFINE3 (fchmodat , int , dfd , const char __user * , filename ,
693
706
umode_t , mode )
694
707
{
695
- return do_fchmodat (dfd , filename , mode );
708
+ return do_fchmodat (dfd , filename , mode , 0 );
696
709
}
697
710
698
711
SYSCALL_DEFINE2 (chmod , const char __user * , filename , umode_t , mode )
699
712
{
700
- return do_fchmodat (AT_FDCWD , filename , mode );
713
+ return do_fchmodat (AT_FDCWD , filename , mode , 0 );
701
714
}
702
715
703
716
/*
0 commit comments