patch-2.1.37 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

diff -u --recursive --new-file v2.1.36/linux/kernel/sys.c linux/kernel/sys.c
@@ -523,16 +523,15 @@
  */
 asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
 {
-	int old_ruid;
-	int old_euid;
+	int old_ruid, old_euid, new_ruid;
 
-	old_ruid = current->uid;
+	new_ruid = old_ruid = current->uid;
 	old_euid = current->euid;
 	if (ruid != (uid_t) -1) {
 		if ((old_ruid == ruid) || 
 		    (current->euid==ruid) ||
 		    suser())
-			current->uid = ruid;
+			new_ruid = ruid;
 		else
 			return -EPERM;
 	}
@@ -542,10 +541,8 @@
 		    (current->suid == euid) ||
 		    suser())
 			current->fsuid = current->euid = euid;
-		else {
-			current->uid = old_ruid;
+		else
 			return -EPERM;
-		}
 	}
 	if (ruid != (uid_t) -1 ||
 	    (euid != (uid_t) -1 && euid != old_ruid))
@@ -553,6 +550,18 @@
 	current->fsuid = current->euid;
 	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
+		 */
+		charge_uid(current, -1);
+		current->uid = new_ruid;
+		if(new_ruid)
+			charge_uid(current, 1);
+	}
 	return 0;
 }
 
@@ -570,9 +579,11 @@
 asmlinkage int sys_setuid(uid_t uid)
 {
 	int old_euid = current->euid;
+	int old_ruid, new_ruid;
 
+	old_ruid = new_ruid = current->uid;
 	if (suser())
-		current->uid = current->euid = current->suid = current->fsuid = uid;
+		new_ruid = current->euid = current->suid = current->fsuid = uid;
 	else if ((uid == current->uid) || (uid == current->suid))
 		current->fsuid = current->euid = uid;
 	else
@@ -580,6 +591,14 @@
 
 	if (current->euid != old_euid)
 		current->dumpable = 0;
+
+	if(new_ruid != old_ruid) {
+		/* See comment above about NPROC rlimit issues... */
+		charge_uid(current, -1);
+		current->uid = new_ruid;
+		if(new_ruid)
+			charge_uid(current, 1);
+	}
 	return 0;
 }
 
@@ -605,8 +624,13 @@
 	if ((suid != (uid_t) -1) && (suid != current->uid) &&
 	    (suid != current->euid) && (suid != current->suid))
 		return -EPERM;
-	if (ruid != (uid_t) -1)
+	if (ruid != (uid_t) -1) {
+		/* See above commentary about NPROC rlimit issues here. */
+		charge_uid(current, -1);
 		current->uid = ruid;
+		if(ruid)
+			charge_uid(current, 1);
+	}
 	if (euid != (uid_t) -1)
 		current->euid = euid;
 	if (suid != (uid_t) -1)
@@ -709,22 +733,13 @@
 	if (pgid < 0)
 		return -EINVAL;
 
-	read_lock(&tasklist_lock);
-	for_each_task(p) {
-		if (p->pid == pid) {
-			/* NOTE: I haven't dropped tasklist_lock, this is
-			 *       on purpose. -DaveM
-			 */
-			goto found_task;
-		}
-	}
-	read_unlock(&tasklist_lock);
-	return -ESRCH;
+	if((p = find_task_by_pid(pid)) == NULL)
+		return -ESRCH;
 
-found_task:
 	/* From this point forward we keep holding onto the tasklist lock
 	 * so that our parent does not change from under us. -DaveM
 	 */
+	read_lock(&tasklist_lock);
 	err = -ESRCH;
 	if (p->p_pptr == current || p->p_opptr == current) {
 		err = -EPERM;
@@ -762,18 +777,12 @@
 	if (!pid) {
 		return current->pgrp;
 	} else {
-		struct task_struct *p;
-		int ret = -ESRCH;
+		struct task_struct *p = find_task_by_pid(pid);
 
-		read_lock(&tasklist_lock);
-		for_each_task(p) {
-			if (p->pid == pid) {
-				ret = p->pgrp;
-				break;
-			}
-		}
-		read_unlock(&tasklist_lock);
-		return ret;
+		if(p)
+			return p->pgrp;
+		else
+			return -ESRCH;
 	}
 }
 
@@ -785,25 +794,16 @@
 
 asmlinkage int sys_getsid(pid_t pid)
 {
-	struct task_struct * p;
-	int ret;
-
-	/* SMP: The 'self' case requires no lock */
 	if (!pid) {
-		ret = current->session;
+		return current->session;
 	} else {
-		ret = -ESRCH;
+		struct task_struct *p = find_task_by_pid(pid);
 
-		read_lock(&tasklist_lock);
-		for_each_task(p) {
-			if (p->pid == pid) {
-				ret = p->session;
-				break;
-			}
-		}
-		read_unlock(&tasklist_lock);
+		if(p)
+			return p->session;
+		else
+			return -ESRCH;
 	}
-	return ret;
 }
 
 asmlinkage int sys_setsid(void)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov