patch-2.4.3 linux/kernel/sys.c
Next file: linux/lib/inflate.c
Previous file: linux/kernel/sched.c
Back to the patch index
Back to the overall index
- Lines: 263
- Date:
Tue Mar 6 19:44:37 2001
- Orig file:
v2.4.2/linux/kernel/sys.c
- Orig date:
Mon Oct 16 12:58:51 2000
diff -u --recursive --new-file v2.4.2/linux/kernel/sys.c linux/kernel/sys.c
@@ -330,6 +330,12 @@
return 0;
}
+static void deferred_cad(void *dummy)
+{
+ notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
+ machine_restart(NULL);
+}
+
/*
* This function gets called by ctrl-alt-del - ie the keyboard interrupt.
* As it's called within an interrupt, it may NOT sync: the only choice
@@ -337,10 +343,13 @@
*/
void ctrl_alt_del(void)
{
- if (C_A_D) {
- notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
- machine_restart(NULL);
- } else
+ static struct tq_struct cad_tq = {
+ routine: deferred_cad,
+ };
+
+ if (C_A_D)
+ schedule_task(&cad_tq);
+ else
kill_proc(1, SIGINT, 1);
}
@@ -367,12 +376,14 @@
{
int old_rgid = current->gid;
int old_egid = current->egid;
+ int new_rgid = old_rgid;
+ int new_egid = old_egid;
if (rgid != (gid_t) -1) {
if ((old_rgid == rgid) ||
(current->egid==rgid) ||
capable(CAP_SETGID))
- current->gid = rgid;
+ new_rgid = rgid;
else
return -EPERM;
}
@@ -381,18 +392,22 @@
(current->egid == egid) ||
(current->sgid == egid) ||
capable(CAP_SETGID))
- current->fsgid = current->egid = egid;
+ new_egid = egid;
else {
- current->gid = old_rgid;
return -EPERM;
}
}
+ if (new_egid != old_egid)
+ {
+ current->dumpable = 0;
+ wmb();
+ }
if (rgid != (gid_t) -1 ||
(egid != (gid_t) -1 && egid != old_rgid))
- current->sgid = current->egid;
- current->fsgid = current->egid;
- if (current->egid != old_egid)
- current->dumpable = 0;
+ current->sgid = new_egid;
+ current->fsgid = new_egid;
+ current->egid = new_egid;
+ current->gid = new_rgid;
return 0;
}
@@ -406,14 +421,25 @@
int old_egid = current->egid;
if (capable(CAP_SETGID))
+ {
+ if(old_egid != gid)
+ {
+ current->dumpable=0;
+ wmb();
+ }
current->gid = current->egid = current->sgid = current->fsgid = gid;
+ }
else if ((gid == current->gid) || (gid == current->sgid))
+ {
+ if(old_egid != gid)
+ {
+ current->dumpable=0;
+ wmb();
+ }
current->egid = current->fsgid = gid;
+ }
else
return -EPERM;
-
- if (current->egid != old_egid)
- current->dumpable = 0;
return 0;
}
@@ -463,7 +489,7 @@
}
}
-static int set_user(uid_t new_ruid)
+static int set_user(uid_t new_ruid, int dumpclear)
{
struct user_struct *new_user, *old_user;
@@ -479,6 +505,11 @@
atomic_dec(&old_user->processes);
atomic_inc(&new_user->processes);
+ if(dumpclear)
+ {
+ current->dumpable = 0;
+ wmb();
+ }
current->uid = new_ruid;
current->user = new_user;
free_uid(old_user);
@@ -525,16 +556,19 @@
return -EPERM;
}
- if (new_ruid != old_ruid && set_user(new_ruid) < 0)
+ if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
return -EAGAIN;
+ if (new_euid != old_euid)
+ {
+ current->dumpable=0;
+ wmb();
+ }
current->fsuid = current->euid = new_euid;
if (ruid != (uid_t) -1 ||
(euid != (uid_t) -1 && euid != old_ruid))
current->suid = current->euid;
current->fsuid = current->euid;
- if (current->euid != old_euid)
- current->dumpable = 0;
if (!issecure(SECURE_NO_SETUID_FIXUP)) {
cap_emulate_setxuid(old_ruid, old_euid, old_suid);
@@ -559,21 +593,26 @@
asmlinkage long sys_setuid(uid_t uid)
{
int old_euid = current->euid;
- int old_ruid, old_suid, new_ruid;
+ int old_ruid, old_suid, new_ruid, new_suid;
old_ruid = new_ruid = current->uid;
old_suid = current->suid;
+ new_suid = old_suid;
+
if (capable(CAP_SETUID)) {
- if (uid != old_ruid && set_user(uid) < 0)
+ if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
return -EAGAIN;
- current->suid = uid;
- } else if ((uid != current->uid) && (uid != current->suid))
+ new_suid = uid;
+ } else if ((uid != current->uid) && (uid != new_suid))
return -EPERM;
- current->fsuid = current->euid = uid;
-
if (old_euid != uid)
+ {
current->dumpable = 0;
+ wmb();
+ }
+ current->fsuid = current->euid = uid;
+ current->suid = new_suid;
if (!issecure(SECURE_NO_SETUID_FIXUP)) {
cap_emulate_setxuid(old_ruid, old_euid, old_suid);
@@ -605,12 +644,15 @@
return -EPERM;
}
if (ruid != (uid_t) -1) {
- if (ruid != current->uid && set_user(ruid) < 0)
+ if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
return -EAGAIN;
}
if (euid != (uid_t) -1) {
if (euid != current->euid)
+ {
current->dumpable = 0;
+ wmb();
+ }
current->euid = euid;
current->fsuid = euid;
}
@@ -640,7 +682,7 @@
*/
asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
{
- if (!capable(CAP_SETGID)) {
+ if (!capable(CAP_SETGID)) {
if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
(rgid != current->egid) && (rgid != current->sgid))
return -EPERM;
@@ -651,14 +693,17 @@
(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;
+ wmb();
+ }
current->egid = egid;
current->fsgid = egid;
}
+ if (rgid != (gid_t) -1)
+ current->gid = rgid;
if (sgid != (gid_t) -1)
current->sgid = sgid;
return 0;
@@ -690,9 +735,14 @@
if (uid == current->uid || uid == current->euid ||
uid == current->suid || uid == current->fsuid ||
capable(CAP_SETUID))
+ {
+ if (uid != old_fsuid)
+ {
+ current->dumpable = 0;
+ wmb();
+ }
current->fsuid = uid;
- if (current->fsuid != old_fsuid)
- current->dumpable = 0;
+ }
/* We emulate fsuid by essentially doing a scaled-down version
* of what we did in setresuid and friends. However, we only
@@ -727,10 +777,14 @@
if (gid == current->gid || gid == current->egid ||
gid == current->sgid || gid == current->fsgid ||
capable(CAP_SETGID))
+ {
+ if (gid != old_fsgid)
+ {
+ current->dumpable = 0;
+ wmb();
+ }
current->fsgid = gid;
- if (current->fsgid != old_fsgid)
- current->dumpable = 0;
-
+ }
return old_fsgid;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)