patch-2.3.99-pre6 linux/kernel/exec_domain.c
Next file: linux/kernel/exit.c
Previous file: linux/ipc/shm.c
Back to the patch index
Back to the overall index
- Lines: 75
- Date:
Fri Apr 21 13:36:40 2000
- Orig file:
v2.3.99-pre5/linux/kernel/exec_domain.c
- Orig date:
Tue Mar 14 19:10:40 2000
diff -u --recursive --new-file v2.3.99-pre5/linux/kernel/exec_domain.c linux/kernel/exec_domain.c
@@ -32,9 +32,7 @@
* personality set incorrectly. Check to see whether SVr4 is available,
* and use it, otherwise give the user a SEGV.
*/
- put_exec_domain(current->exec_domain);
- current->personality = PER_SVR4;
- current->exec_domain = lookup_exec_domain(current->personality);
+ set_personality(PER_SVR4);
if (current->exec_domain && current->exec_domain->handler
&& current->exec_domain->handler != no_lcall7) {
@@ -45,7 +43,7 @@
send_sig(SIGSEGV, current, 1);
}
-struct exec_domain *lookup_exec_domain(unsigned long personality)
+static struct exec_domain *lookup_exec_domain(unsigned long personality)
{
unsigned long pers = personality & PER_MASK;
struct exec_domain *it;
@@ -104,28 +102,37 @@
return -EINVAL;
}
-asmlinkage long sys_personality(unsigned long personality)
+void __set_personality(unsigned long personality)
{
struct exec_domain *it;
- unsigned long old_personality;
- int ret;
-
- if (personality == 0xffffffff)
- return current->personality;
- ret = -EINVAL;
- lock_kernel();
it = lookup_exec_domain(personality);
- if (!it)
- goto out;
+ if (it) {
+ if (atomic_read(¤t->fs->count) != 1) {
+ struct fs_struct *new = copy_fs_struct(current->fs);
+ if (!new)
+ return;
+ put_fs_struct(xchg(¤t->fs,new));
+ }
+ /*
+ * At that point we are guaranteed to be the sole owner of
+ * current->fs.
+ */
+ current->personality = personality;
+ current->exec_domain = it;
+ set_fs_altroot();
+ put_exec_domain(current->exec_domain);
+ }
+}
- old_personality = current->personality;
- put_exec_domain(current->exec_domain);
- current->personality = personality;
- current->exec_domain = it;
- ret = old_personality;
-out:
- unlock_kernel();
+asmlinkage long sys_personality(unsigned long personality)
+{
+ int ret = current->personality;
+ if (personality != 0xffffffff) {
+ set_personality(personality);
+ if (current->personality != personality)
+ ret = -EINVAL;
+ }
return ret;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)