diff options
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 114 |
1 files changed, 80 insertions, 34 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index ca3d17807..27d41eed1 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -21,7 +21,6 @@ #include <linux/fcntl.h> #include <linux/acct.h> #include <linux/tty.h> -#include <linux/nametrans.h> #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/notifier.h> @@ -397,10 +396,8 @@ int acct_process(long exitcode) fs = get_fs(); set_fs(KERNEL_DS); - acct_file.f_op->write(acct_file.f_inode, &acct_file, + acct_file.f_op->write(acct_file.f_dentry->d_inode, &acct_file, (char *)&ac, sizeof(struct acct)); - /* inode->i_status |= ST_MODIFIED is willingly *not* done here */ - set_fs(fs); } return 0; @@ -408,8 +405,6 @@ int acct_process(long exitcode) asmlinkage int sys_acct(const char *name) { - struct inode *inode = (struct inode *)0; - char *tmp; int error = -EPERM; lock_kernel(); @@ -419,10 +414,10 @@ asmlinkage int sys_acct(const char *name) if (name == (char *)0) { if (acct_active) { if (acct_file.f_op->release) - acct_file.f_op->release(acct_file.f_inode, &acct_file); + acct_file.f_op->release(acct_file.f_dentry->d_inode, &acct_file); - if (acct_file.f_inode != (struct inode *) 0) - iput(acct_file.f_inode); + if (acct_file.f_dentry != NULL) + dput(acct_file.f_dentry); acct_active = 0; } @@ -430,40 +425,51 @@ asmlinkage int sys_acct(const char *name) } else { error = -EBUSY; if (!acct_active) { - if ((error = getname(name, &tmp)) != 0) + struct dentry *dentry; + struct inode *inode; + char *tmp; + + tmp = getname(name); + error = PTR_ERR(tmp); + if (IS_ERR(tmp)) goto out; - error = open_namei(tmp, O_RDWR, 0600, &inode, 0); + dentry = open_namei(tmp, O_RDWR, 0600); putname(tmp); - if (error) + + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) goto out; + inode = dentry->d_inode; error = -EACCES; if (!S_ISREG(inode->i_mode)) { - iput(inode); + dput(dentry); goto out; } error = -EIO; if (!inode->i_op || !inode->i_op->default_file_ops || !inode->i_op->default_file_ops->write) { - iput(inode); + dput(dentry); goto out; } acct_file.f_mode = 3; acct_file.f_flags = 0; acct_file.f_count = 1; - acct_file.f_inode = inode; + acct_file.f_dentry = dentry; acct_file.f_pos = inode->i_size; acct_file.f_reada = 0; acct_file.f_op = inode->i_op->default_file_ops; - if(acct_file.f_op->open) - if(acct_file.f_op->open(acct_file.f_inode, &acct_file)) { - iput(inode); + if(acct_file.f_op->open) { + error = acct_file.f_op->open(inode, &acct_file); + if (error) { + dput(dentry); goto out; } + } acct_active = 1; error = 0; @@ -612,21 +618,17 @@ asmlinkage int sys_setuid(uid_t uid) */ asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) { - uid_t old_ruid, old_euid, old_suid; - - old_ruid = current->uid; - old_euid = current->euid; - old_suid = current->suid; - - if ((ruid != (uid_t) -1) && (ruid != current->uid) && - (ruid != current->euid) && (ruid != current->suid)) - return -EPERM; - if ((euid != (uid_t) -1) && (euid != current->uid) && - (euid != current->euid) && (euid != current->suid)) - return -EPERM; - if ((suid != (uid_t) -1) && (suid != current->uid) && - (suid != current->euid) && (suid != current->suid)) - return -EPERM; + if (current->uid != 0 && current->euid != 0 && current->suid != 0) { + if ((ruid != (uid_t) -1) && (ruid != current->uid) && + (ruid != current->euid) && (ruid != current->suid)) + return -EPERM; + if ((euid != (uid_t) -1) && (euid != current->uid) && + (euid != current->euid) && (euid != current->suid)) + return -EPERM; + if ((suid != (uid_t) -1) && (suid != current->uid) && + (suid != current->euid) && (suid != current->suid)) + return -EPERM; + } if (ruid != (uid_t) -1) { /* See above commentary about NPROC rlimit issues here. */ charge_uid(current, -1); @@ -634,8 +636,12 @@ asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) if(ruid) charge_uid(current, 1); } - if (euid != (uid_t) -1) + if (euid != (uid_t) -1) { + if (euid != current->euid) + current->dumpable = 0; current->euid = euid; + current->fsuid = euid; + } if (suid != (uid_t) -1) current->suid = suid; return 0; @@ -652,6 +658,46 @@ asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) return retval; } +/* + * Same as above, but for rgid, egid, sgid. + */ +asmlinkage int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) +{ + if (current->uid != 0 && current->euid != 0 && current->suid != 0) { + if ((rgid != (gid_t) -1) && (rgid != current->gid) && + (rgid != current->egid) && (rgid != current->sgid)) + return -EPERM; + if ((egid != (gid_t) -1) && (egid != current->gid) && + (egid != current->egid) && (egid != current->sgid)) + return -EPERM; + if ((sgid != (gid_t) -1) && (sgid != current->gid) && + (sgid != current->egid) && (sgid != current->sgid)) + return -EPERM; + } + if (rgid != (gid_t) -1) + current->gid = rgid; + if (egid != (gid_t) -1) { + if (egid != current->egid) + current->dumpable = 0; + current->egid = egid; + current->fsgid = egid; + } + if (sgid != (gid_t) -1) + current->sgid = sgid; + return 0; +} + +asmlinkage int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) +{ + int retval; + + if (!(retval = put_user(current->gid, rgid)) && + !(retval = put_user(current->egid, egid))) + retval = put_user(current->sgid, sgid); + + return retval; +} + /* * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This |