Skip to content

Commit

Permalink
Synchronize codes for OnePlus 7 Oxygen OS 10.3.3/OnePlus 7 Pro Oxygen…
Browse files Browse the repository at this point in the history
… OS 10.3.3

[CVE-2020-8428]do_last(): fetch directory ->i_mode and ->i_uid before it's too late

In do_last of namei.c, there is a possible information disclosure
      due to a double free. This could lead to local information disclosure
      with no additional execution privileges needed. User interaction is
      not needed for exploitation.
      The fix is designed to cache the required data before it is freed.

Change-Id: Ia474a04d41159cbdb492e0f22df9705f5472754b
Signed-off-by: Siba Prasad <[email protected]>
Signed-off-by: engstk <[email protected]>
  • Loading branch information
Siba Prasad authored and engstk committed Jun 8, 2020
1 parent 7010b45 commit a63212c
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,8 @@ static int may_linkat(struct path *link)
* may_create_in_sticky - Check whether an O_CREAT open in a sticky directory
* should be allowed, or not, on files that already
* exist.
* @dir: the sticky parent directory
* @dir_mode: mode bits of directory
* @dir_uid: owner of directory
* @inode: the inode of the file to open
*
* Block an O_CREAT open of a FIFO (or a regular file) when:
Expand All @@ -1058,18 +1059,18 @@ static int may_linkat(struct path *link)
*
* Returns 0 if the open is allowed, -ve on error.
*/
static int may_create_in_sticky(struct dentry * const dir,
static int may_create_in_sticky(umode_t dir_mode, kuid_t dir_uid,
struct inode * const inode)
{
if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) ||
(!sysctl_protected_regular && S_ISREG(inode->i_mode)) ||
likely(!(dir->d_inode->i_mode & S_ISVTX)) ||
uid_eq(inode->i_uid, dir->d_inode->i_uid) ||
likely(!(dir_mode & S_ISVTX)) ||
uid_eq(inode->i_uid, dir_uid) ||
uid_eq(current_fsuid(), inode->i_uid))
return 0;

if (likely(dir->d_inode->i_mode & 0002) ||
(dir->d_inode->i_mode & 0020 &&
if (likely(dir_mode & 0002) ||
(dir_mode & 0020 &&
((sysctl_protected_fifos >= 2 && S_ISFIFO(inode->i_mode)) ||
(sysctl_protected_regular >= 2 && S_ISREG(inode->i_mode))))) {
return -EACCES;
Expand Down Expand Up @@ -3329,6 +3330,8 @@ static int do_last(struct nameidata *nd,
int *opened)
{
struct dentry *dir = nd->path.dentry;
kuid_t dir_uid = nd->inode->i_uid;
umode_t dir_mode = nd->inode->i_mode;
int open_flag = op->open_flag;
bool will_truncate = (open_flag & O_TRUNC) != 0;
bool got_write = false;
Expand Down Expand Up @@ -3464,7 +3467,7 @@ static int do_last(struct nameidata *nd,
error = -EISDIR;
if (d_is_dir(nd->path.dentry))
goto out;
error = may_create_in_sticky(dir,
error = may_create_in_sticky(dir_mode, dir_uid,
d_backing_inode(nd->path.dentry));
if (unlikely(error))
goto out;
Expand Down

0 comments on commit a63212c

Please sign in to comment.