Skip to content

Commit e57712e

Browse files
author
Al Viro
committed
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: Al Viro <[email protected]>
1 parent 0320937 commit e57712e

File tree

1 file changed

+28
-50
lines changed

1 file changed

+28
-50
lines changed

fs/open.c

+28-50
Original file line numberDiff line numberDiff line change
@@ -446,74 +446,52 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
446446
return error;
447447
}
448448

449-
SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
449+
static int chmod_common(struct path *path, umode_t mode)
450450
{
451-
struct inode * inode;
452-
struct dentry * dentry;
453-
struct file * file;
454-
int err = -EBADF;
451+
struct inode *inode = path->dentry->d_inode;
455452
struct iattr newattrs;
453+
int error;
456454

457-
file = fget(fd);
458-
if (!file)
459-
goto out;
460-
461-
dentry = file->f_path.dentry;
462-
inode = dentry->d_inode;
463-
464-
audit_inode(NULL, dentry);
465-
466-
err = mnt_want_write_file(file);
467-
if (err)
468-
goto out_putf;
455+
error = mnt_want_write(path->mnt);
456+
if (error)
457+
return error;
469458
mutex_lock(&inode->i_mutex);
470-
err = security_path_chmod(dentry, file->f_vfsmnt, mode);
471-
if (err)
459+
error = security_path_chmod(path->dentry, path->mnt, mode);
460+
if (error)
472461
goto out_unlock;
473-
if (mode == (mode_t) -1)
474-
mode = inode->i_mode;
475462
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
476463
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
477-
err = notify_change(dentry, &newattrs);
464+
error = notify_change(path->dentry, &newattrs);
478465
out_unlock:
479466
mutex_unlock(&inode->i_mutex);
480-
mnt_drop_write(file->f_path.mnt);
481-
out_putf:
482-
fput(file);
483-
out:
467+
mnt_drop_write(path->mnt);
468+
return error;
469+
}
470+
471+
SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
472+
{
473+
struct file * file;
474+
int err = -EBADF;
475+
476+
file = fget(fd);
477+
if (file) {
478+
audit_inode(NULL, file->f_path.dentry);
479+
err = chmod_common(&file->f_path, mode);
480+
fput(file);
481+
}
484482
return err;
485483
}
486484

487485
SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
488486
{
489487
struct path path;
490-
struct inode *inode;
491488
int error;
492-
struct iattr newattrs;
493489

494490
error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
495-
if (error)
496-
goto out;
497-
inode = path.dentry->d_inode;
498-
499-
error = mnt_want_write(path.mnt);
500-
if (error)
501-
goto dput_and_out;
502-
mutex_lock(&inode->i_mutex);
503-
error = security_path_chmod(path.dentry, path.mnt, mode);
504-
if (error)
505-
goto out_unlock;
506-
if (mode == (mode_t) -1)
507-
mode = inode->i_mode;
508-
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
509-
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
510-
error = notify_change(path.dentry, &newattrs);
511-
out_unlock:
512-
mutex_unlock(&inode->i_mutex);
513-
mnt_drop_write(path.mnt);
514-
dput_and_out:
515-
path_put(&path);
516-
out:
491+
if (!error) {
492+
error = chmod_common(&path, mode);
493+
path_put(&path);
494+
}
517495
return error;
518496
}
519497

0 commit comments

Comments
 (0)