提交 e57712eb 编写于 作者: A Al Viro

merge fchmod() and fchmodat() guts, kill ancient broken kludge

The kludge in question is undocumented and doesn't work for 32bit
binaries on amd64, sparc64 and s390.  Passing (mode_t)-1 as
mode had (since 0.99.14v and contrary to behaviour of any
other Unix, prescriptions of POSIX, SuS and our own manpages)
was kinda-sorta no-op.  Note that any software relying on
that (and looking for examples shows none) would be visibly
broken on sparc64, where practically all userland is built
32bit.  No such complaints noticed...
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 03209378
...@@ -446,74 +446,52 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename) ...@@ -446,74 +446,52 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
return error; return error;
} }
SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode) static int chmod_common(struct path *path, umode_t mode)
{ {
struct inode * inode; struct inode *inode = path->dentry->d_inode;
struct dentry * dentry;
struct file * file;
int err = -EBADF;
struct iattr newattrs; struct iattr newattrs;
int error;
file = fget(fd); error = mnt_want_write(path->mnt);
if (!file) if (error)
goto out; return error;
dentry = file->f_path.dentry;
inode = dentry->d_inode;
audit_inode(NULL, dentry);
err = mnt_want_write_file(file);
if (err)
goto out_putf;
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
err = security_path_chmod(dentry, file->f_vfsmnt, mode); error = security_path_chmod(path->dentry, path->mnt, mode);
if (err) if (error)
goto out_unlock; goto out_unlock;
if (mode == (mode_t) -1)
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); error = notify_change(path->dentry, &newattrs);
out_unlock: out_unlock:
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
mnt_drop_write(file->f_path.mnt); mnt_drop_write(path->mnt);
out_putf: return error;
fput(file); }
out:
SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
{
struct file * file;
int err = -EBADF;
file = fget(fd);
if (file) {
audit_inode(NULL, file->f_path.dentry);
err = chmod_common(&file->f_path, mode);
fput(file);
}
return err; return err;
} }
SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode) SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
{ {
struct path path; struct path path;
struct inode *inode;
int error; int error;
struct iattr newattrs;
error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
if (error) if (!error) {
goto out; error = chmod_common(&path, mode);
inode = path.dentry->d_inode; path_put(&path);
}
error = mnt_want_write(path.mnt);
if (error)
goto dput_and_out;
mutex_lock(&inode->i_mutex);
error = security_path_chmod(path.dentry, path.mnt, mode);
if (error)
goto out_unlock;
if (mode == (mode_t) -1)
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
error = notify_change(path.dentry, &newattrs);
out_unlock:
mutex_unlock(&inode->i_mutex);
mnt_drop_write(path.mnt);
dput_and_out:
path_put(&path);
out:
return error; return error;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册