Actually, the latter fix is not right, as it can leave the
process in a (slightly) inconsistent state if an out-of-memory
condition occurs.
Below is a smaller patch that addresses only the execve/clone
interaction.
Apologies for the extra traffic on this list.
Best regards,
- Xavier Leroy
diff -u -r linux-2.0.27/fs/exec.c linux-2.0.27patched/fs/exec.c
--- linux-2.0.27/fs/exec.c Sat Nov 30 11:21:18 1996
+++ linux-2.0.27patched/fs/exec.c Mon Dec 30 11:49:36 1996
@@ -392,6 +392,33 @@
}
/*
+ * This function makes a copy of the signal table of the current
+ * process if it's shared with other processes,
+ * so that flush_old_signal will not modify other processes's signal tables,
+ * and the exec()ed program can set its own signal handlers without
+ * disturbing the other processes.
+ */
+
+static inline void unshare_signals(void)
+{
+ struct signal_struct *sig;
+
+ if (current->sig->count > 1) {
+ sig = kmalloc(sizeof(*sig), GFP_KERNEL);
+ if (!sig) {
+ /* this is wrong, I think. */
+ oom(current);
+ return;
+ }
+ sig->count = 1;
+ memcpy(sig->action, current->sig->action, sizeof(sig->action));
+ current->sig->count--;
+ current->sig = sig;
+ }
+ return 0;
+}
+
+/*
* These functions flushes out all traces of the currently running executable
* so that a new one can be started
*/
@@ -448,6 +475,9 @@
current->comm[i++] = ch;
}
current->comm[i] = '\0';
+
+ /* Make sure we have a private signal table. */
+ unshare_signals();
/* Release all of the old mmap stuff. */
exec_mmap();