|
@@ -619,17 +619,17 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
|
|
err = mnt_want_write_file(file);
|
|
err = mnt_want_write_file(file);
|
|
if (err)
|
|
if (err)
|
|
goto out_putf;
|
|
goto out_putf;
|
|
|
|
+ mutex_lock(&inode->i_mutex);
|
|
err = security_path_chmod(dentry, file->f_vfsmnt, mode);
|
|
err = security_path_chmod(dentry, file->f_vfsmnt, mode);
|
|
if (err)
|
|
if (err)
|
|
- goto out_drop_write;
|
|
|
|
- mutex_lock(&inode->i_mutex);
|
|
|
|
|
|
+ goto out_unlock;
|
|
if (mode == (mode_t) -1)
|
|
if (mode == (mode_t) -1)
|
|
mode = inode->i_mode;
|
|
mode = inode->i_mode;
|
|
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
|
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
|
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
|
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
|
err = notify_change(dentry, &newattrs);
|
|
err = notify_change(dentry, &newattrs);
|
|
|
|
+out_unlock:
|
|
mutex_unlock(&inode->i_mutex);
|
|
mutex_unlock(&inode->i_mutex);
|
|
-out_drop_write:
|
|
|
|
mnt_drop_write(file->f_path.mnt);
|
|
mnt_drop_write(file->f_path.mnt);
|
|
out_putf:
|
|
out_putf:
|
|
fput(file);
|
|
fput(file);
|
|
@@ -652,17 +652,17 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
|
|
error = mnt_want_write(path.mnt);
|
|
error = mnt_want_write(path.mnt);
|
|
if (error)
|
|
if (error)
|
|
goto dput_and_out;
|
|
goto dput_and_out;
|
|
|
|
+ mutex_lock(&inode->i_mutex);
|
|
error = security_path_chmod(path.dentry, path.mnt, mode);
|
|
error = security_path_chmod(path.dentry, path.mnt, mode);
|
|
if (error)
|
|
if (error)
|
|
- goto out_drop_write;
|
|
|
|
- mutex_lock(&inode->i_mutex);
|
|
|
|
|
|
+ goto out_unlock;
|
|
if (mode == (mode_t) -1)
|
|
if (mode == (mode_t) -1)
|
|
mode = inode->i_mode;
|
|
mode = inode->i_mode;
|
|
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
|
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
|
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
|
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
|
error = notify_change(path.dentry, &newattrs);
|
|
error = notify_change(path.dentry, &newattrs);
|
|
|
|
+out_unlock:
|
|
mutex_unlock(&inode->i_mutex);
|
|
mutex_unlock(&inode->i_mutex);
|
|
-out_drop_write:
|
|
|
|
mnt_drop_write(path.mnt);
|
|
mnt_drop_write(path.mnt);
|
|
dput_and_out:
|
|
dput_and_out:
|
|
path_put(&path);
|
|
path_put(&path);
|
|
@@ -675,9 +675,9 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode)
|
|
return sys_fchmodat(AT_FDCWD, filename, mode);
|
|
return sys_fchmodat(AT_FDCWD, filename, mode);
|
|
}
|
|
}
|
|
|
|
|
|
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
|
|
|
|
|
|
+static int chown_common(struct path *path, uid_t user, gid_t group)
|
|
{
|
|
{
|
|
- struct inode *inode = dentry->d_inode;
|
|
|
|
|
|
+ struct inode *inode = path->dentry->d_inode;
|
|
int error;
|
|
int error;
|
|
struct iattr newattrs;
|
|
struct iattr newattrs;
|
|
|
|
|
|
@@ -694,7 +694,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
|
|
newattrs.ia_valid |=
|
|
newattrs.ia_valid |=
|
|
ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
|
|
ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
|
|
mutex_lock(&inode->i_mutex);
|
|
mutex_lock(&inode->i_mutex);
|
|
- error = notify_change(dentry, &newattrs);
|
|
|
|
|
|
+ error = security_path_chown(path, user, group);
|
|
|
|
+ if (!error)
|
|
|
|
+ error = notify_change(path->dentry, &newattrs);
|
|
mutex_unlock(&inode->i_mutex);
|
|
mutex_unlock(&inode->i_mutex);
|
|
|
|
|
|
return error;
|
|
return error;
|
|
@@ -711,9 +713,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
|
|
error = mnt_want_write(path.mnt);
|
|
error = mnt_want_write(path.mnt);
|
|
if (error)
|
|
if (error)
|
|
goto out_release;
|
|
goto out_release;
|
|
- error = security_path_chown(&path, user, group);
|
|
|
|
- if (!error)
|
|
|
|
- error = chown_common(path.dentry, user, group);
|
|
|
|
|
|
+ error = chown_common(&path, user, group);
|
|
mnt_drop_write(path.mnt);
|
|
mnt_drop_write(path.mnt);
|
|
out_release:
|
|
out_release:
|
|
path_put(&path);
|
|
path_put(&path);
|
|
@@ -738,9 +738,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
|
|
error = mnt_want_write(path.mnt);
|
|
error = mnt_want_write(path.mnt);
|
|
if (error)
|
|
if (error)
|
|
goto out_release;
|
|
goto out_release;
|
|
- error = security_path_chown(&path, user, group);
|
|
|
|
- if (!error)
|
|
|
|
- error = chown_common(path.dentry, user, group);
|
|
|
|
|
|
+ error = chown_common(&path, user, group);
|
|
mnt_drop_write(path.mnt);
|
|
mnt_drop_write(path.mnt);
|
|
out_release:
|
|
out_release:
|
|
path_put(&path);
|
|
path_put(&path);
|
|
@@ -759,9 +757,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group
|
|
error = mnt_want_write(path.mnt);
|
|
error = mnt_want_write(path.mnt);
|
|
if (error)
|
|
if (error)
|
|
goto out_release;
|
|
goto out_release;
|
|
- error = security_path_chown(&path, user, group);
|
|
|
|
- if (!error)
|
|
|
|
- error = chown_common(path.dentry, user, group);
|
|
|
|
|
|
+ error = chown_common(&path, user, group);
|
|
mnt_drop_write(path.mnt);
|
|
mnt_drop_write(path.mnt);
|
|
out_release:
|
|
out_release:
|
|
path_put(&path);
|
|
path_put(&path);
|
|
@@ -784,9 +780,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
|
|
goto out_fput;
|
|
goto out_fput;
|
|
dentry = file->f_path.dentry;
|
|
dentry = file->f_path.dentry;
|
|
audit_inode(NULL, dentry);
|
|
audit_inode(NULL, dentry);
|
|
- error = security_path_chown(&file->f_path, user, group);
|
|
|
|
- if (!error)
|
|
|
|
- error = chown_common(dentry, user, group);
|
|
|
|
|
|
+ error = chown_common(&file->f_path, user, group);
|
|
mnt_drop_write(file->f_path.mnt);
|
|
mnt_drop_write(file->f_path.mnt);
|
|
out_fput:
|
|
out_fput:
|
|
fput(file);
|
|
fput(file);
|