summaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-08-29 05:27:07 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-08-29 05:27:07 +0000
commita60c6812feb6ba35b5b8a9ee8a5ca3d01d1fcd5f (patch)
tree2290ff15f280314a063f3dfc523742c8934c4259 /fs/exec.c
parent1a1d77dd589de5a567fa95e36aa6999c704ceca4 (diff)
Merge with Linux 2.4.0-test8-pre1.
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/fs/exec.c b/fs/exec.c
index c0df3a68b..f0c64b43a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -496,6 +496,27 @@ static inline void flush_old_files(struct files_struct * files)
write_unlock(&files->file_lock);
}
+/*
+ * An execve() will automatically "de-thread" the process.
+ * Note: we don't have to hold the tasklist_lock to test
+ * whether we migth need to do this. If we're not part of
+ * a thread group, there is no way we can become one
+ * dynamically. And if we are, we only need to protect the
+ * unlink - even if we race with the last other thread exit,
+ * at worst the list_del_init() might end up being a no-op.
+ */
+static inline void de_thread(struct task_struct *tsk)
+{
+ if (!list_empty(&tsk->thread_group)) {
+ write_lock_irq(&tasklist_lock);
+ list_del_init(&tsk->thread_group);
+ write_unlock_irq(&tasklist_lock);
+ }
+
+ /* Minor oddity: this might stay the same. */
+ tsk->tgid = tsk->pid;
+}
+
int flush_old_exec(struct linux_binprm * bprm)
{
char * name;
@@ -534,6 +555,8 @@ int flush_old_exec(struct linux_binprm * bprm)
flush_thread();
+ de_thread(current);
+
if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
permission(bprm->file->f_dentry->d_inode,MAY_READ))
current->dumpable = 0;