summaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c114
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