@@ -1001,7 +1001,8 @@ static int may_linkat(struct path *link)
1001
1001
* may_create_in_sticky - Check whether an O_CREAT open in a sticky directory
1002
1002
* should be allowed, or not, on files that already
1003
1003
* exist.
1004
- * @dir: the sticky parent directory
1004
+ * @dir_mode: mode bits of directory
1005
+ * @dir_uid: owner of directory
1005
1006
* @inode: the inode of the file to open
1006
1007
*
1007
1008
* Block an O_CREAT open of a FIFO (or a regular file) when:
@@ -1017,18 +1018,18 @@ static int may_linkat(struct path *link)
1017
1018
*
1018
1019
* Returns 0 if the open is allowed, -ve on error.
1019
1020
*/
1020
- static int may_create_in_sticky (struct dentry * const dir ,
1021
+ static int may_create_in_sticky (umode_t dir_mode , kuid_t dir_uid ,
1021
1022
struct inode * const inode )
1022
1023
{
1023
1024
if ((!sysctl_protected_fifos && S_ISFIFO (inode -> i_mode )) ||
1024
1025
(!sysctl_protected_regular && S_ISREG (inode -> i_mode )) ||
1025
- likely (!(dir -> d_inode -> i_mode & S_ISVTX )) ||
1026
- uid_eq (inode -> i_uid , dir -> d_inode -> i_uid ) ||
1026
+ likely (!(dir_mode & S_ISVTX )) ||
1027
+ uid_eq (inode -> i_uid , dir_uid ) ||
1027
1028
uid_eq (current_fsuid (), inode -> i_uid ))
1028
1029
return 0 ;
1029
1030
1030
- if (likely (dir -> d_inode -> i_mode & 0002 ) ||
1031
- (dir -> d_inode -> i_mode & 0020 &&
1031
+ if (likely (dir_mode & 0002 ) ||
1032
+ (dir_mode & 0020 &&
1032
1033
((sysctl_protected_fifos >= 2 && S_ISFIFO (inode -> i_mode )) ||
1033
1034
(sysctl_protected_regular >= 2 && S_ISREG (inode -> i_mode ))))) {
1034
1035
const char * operation = S_ISFIFO (inode -> i_mode ) ?
@@ -3201,6 +3202,8 @@ static int do_last(struct nameidata *nd,
3201
3202
struct file * file , const struct open_flags * op )
3202
3203
{
3203
3204
struct dentry * dir = nd -> path .dentry ;
3205
+ kuid_t dir_uid = dir -> d_inode -> i_uid ;
3206
+ umode_t dir_mode = dir -> d_inode -> i_mode ;
3204
3207
int open_flag = op -> open_flag ;
3205
3208
bool will_truncate = (open_flag & O_TRUNC ) != 0 ;
3206
3209
bool got_write = false;
@@ -3331,7 +3334,7 @@ static int do_last(struct nameidata *nd,
3331
3334
error = - EISDIR ;
3332
3335
if (d_is_dir (nd -> path .dentry ))
3333
3336
goto out ;
3334
- error = may_create_in_sticky (dir ,
3337
+ error = may_create_in_sticky (dir_mode , dir_uid ,
3335
3338
d_backing_inode (nd -> path .dentry ));
3336
3339
if (unlikely (error ))
3337
3340
goto out ;
0 commit comments