patch-2.4.0-test6 linux/kernel/sys.c
Next file: linux/kernel/sysctl.c
Previous file: linux/kernel/softirq.c
Back to the patch index
Back to the overall index
- Lines: 138
- Date:
Wed Aug 9 18:59:17 2000
- Orig file:
v2.4.0-test5/linux/kernel/sys.c
- Orig date:
Thu Jul 27 17:38:02 2000
diff -u --recursive --new-file v2.4.0-test5/linux/kernel/sys.c linux/kernel/sys.c
@@ -466,6 +466,28 @@
}
}
+static int set_user(uid_t new_ruid)
+{
+ struct user_struct *new_user, *old_user;
+
+ /* What if a process setreuid()'s and this brings the
+ * new uid over his NPROC rlimit? We can check this now
+ * cheaply with the new uid cache, so if it matters
+ * we should be checking for it. -DaveM
+ */
+ new_user = alloc_uid(new_ruid);
+ if (!new_user)
+ return -EAGAIN;
+ old_user = current->user;
+ atomic_dec(&old_user->processes);
+ atomic_inc(&new_user->processes);
+
+ current->uid = new_ruid;
+ current->user = new_user;
+ free_uid(old_user);
+ return 0;
+}
+
/*
* Unprivileged users may change the real uid to the effective uid
* or vice versa. (BSD-style)
@@ -483,28 +505,33 @@
*/
asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
{
- int old_ruid, old_euid, old_suid, new_ruid;
+ int old_ruid, old_euid, old_suid, new_ruid, new_euid;
new_ruid = old_ruid = current->uid;
- old_euid = current->euid;
+ new_euid = old_euid = current->euid;
old_suid = current->suid;
+
if (ruid != (uid_t) -1) {
- if ((old_ruid == ruid) ||
- (current->euid==ruid) ||
- capable(CAP_SETUID))
- new_ruid = ruid;
- else
+ new_ruid = ruid;
+ if ((old_ruid != ruid) &&
+ (current->euid != ruid) &&
+ !capable(CAP_SETUID))
return -EPERM;
}
+
if (euid != (uid_t) -1) {
- if ((old_ruid == euid) ||
- (current->euid == euid) ||
- (current->suid == euid) ||
- capable(CAP_SETUID))
- current->fsuid = current->euid = euid;
- else
+ new_euid = euid;
+ if ((old_ruid != euid) &&
+ (current->euid != euid) &&
+ (current->suid != euid) &&
+ !capable(CAP_SETUID))
return -EPERM;
}
+
+ if (new_ruid != old_ruid && set_user(new_ruid) < 0)
+ return -EAGAIN;
+
+ current->fsuid = current->euid = new_euid;
if (ruid != (uid_t) -1 ||
(euid != (uid_t) -1 && euid != old_ruid))
current->suid = current->euid;
@@ -512,17 +539,6 @@
if (current->euid != old_euid)
current->dumpable = 0;
- if(new_ruid != old_ruid) {
- /* What if a process setreuid()'s and this brings the
- * new uid over his NPROC rlimit? We can check this now
- * cheaply with the new uid cache, so if it matters
- * we should be checking for it. -DaveM
- */
- free_uid(current);
- current->uid = new_ruid;
- alloc_uid(current);
- }
-
if (!issecure(SECURE_NO_SETUID_FIXUP)) {
cap_emulate_setxuid(old_ruid, old_euid, old_suid);
}
@@ -550,22 +566,17 @@
old_ruid = new_ruid = current->uid;
old_suid = current->suid;
- if (capable(CAP_SETUID))
- new_ruid = current->euid = current->suid = current->fsuid = uid;
- else if ((uid == current->uid) || (uid == current->suid))
- current->fsuid = current->euid = uid;
- else
+ if (capable(CAP_SETUID)) {
+ if (uid != old_ruid && set_user(uid) < 0)
+ return -EAGAIN;
+ current->suid = uid;
+ } else if ((uid != current->uid) && (uid != current->suid))
return -EPERM;
- if (current->euid != old_euid)
- current->dumpable = 0;
+ current->fsuid = current->euid = uid;
- if (new_ruid != old_ruid) {
- /* See comment above about NPROC rlimit issues... */
- free_uid(current);
- current->uid = new_ruid;
- alloc_uid(current);
- }
+ if (old_euid != uid)
+ current->dumpable = 0;
if (!issecure(SECURE_NO_SETUID_FIXUP)) {
cap_emulate_setxuid(old_ruid, old_euid, old_suid);
@@ -597,10 +608,8 @@
return -EPERM;
}
if (ruid != (uid_t) -1) {
- /* See above commentary about NPROC rlimit issues here. */
- free_uid(current);
- current->uid = ruid;
- alloc_uid(current);
+ if (ruid != current->uid && set_user(ruid) < 0)
+ return -EAGAIN;
}
if (euid != (uid_t) -1) {
if (euid != current->euid)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)