summaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
commit74a9f2e1b4d3ab45a9f72cb5b556c9f521524ab3 (patch)
tree7c4cdb103ab1b388c9852a88bd6fb1e73eba0b5c /kernel/sys.c
parentee6374c8b0d333c08061c6a97bc77090d7461225 (diff)
Merge with Linux 2.4.3.
Note that mingetty does no longer work with serial console, you have to switch to another getty like getty_ps. This commit also includes a fix for a setitimer bug which did prevent getty_ps from working on older kernels.
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c120
1 files changed, 87 insertions, 33 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index ded9c6328..bb2b0c8bf 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -330,6 +330,12 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void * arg)
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 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void * arg)
*/
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 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
{
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 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
(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 @@ asmlinkage long sys_setgid(gid_t gid)
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 @@ extern inline void cap_emulate_setxuid(int old_ruid, int old_euid,
}
}
-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 @@ static int set_user(uid_t new_ruid)
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 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
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_setreuid(uid_t ruid, uid_t euid)
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 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
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_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
*/
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 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
(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 @@ asmlinkage long sys_setfsuid(uid_t uid)
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 @@ asmlinkage long sys_setfsgid(gid_t gid)
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;
}