patch-2.4.19 linux-2.4.19/kernel/fork.c
Next file: linux-2.4.19/kernel/kmod.c
Previous file: linux-2.4.19/kernel/exit.c
Back to the patch index
Back to the overall index
- Lines: 137
- Date:
Fri Aug 2 17:39:46 2002
- Orig file:
linux-2.4.18/kernel/fork.c
- Orig date:
Mon Feb 25 11:38:13 2002
diff -urN linux-2.4.18/kernel/fork.c linux-2.4.19/kernel/fork.c
@@ -19,7 +19,9 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/completion.h>
+#include <linux/namespace.h>
#include <linux/personality.h>
+#include <linux/compiler.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -85,12 +87,13 @@
{
static int next_safe = PID_MAX;
struct task_struct *p;
- int pid;
+ int pid, beginpid;
if (flags & CLONE_PID)
return current->pid;
spin_lock(&lastpid_lock);
+ beginpid = last_pid;
if((++last_pid) & 0xffff8000) {
last_pid = 300; /* Skip daemons etc. */
goto inside;
@@ -110,12 +113,16 @@
last_pid = 300;
next_safe = PID_MAX;
}
+ if(unlikely(last_pid == beginpid))
+ goto nomorepids;
goto repeat;
}
if(p->pid > last_pid && next_safe > p->pid)
next_safe = p->pid;
if(p->pgrp > last_pid && next_safe > p->pgrp)
next_safe = p->pgrp;
+ if(p->tgid > last_pid && next_safe > p->tgid)
+ next_safe = p->tgid;
if(p->session > last_pid && next_safe > p->session)
next_safe = p->session;
}
@@ -125,6 +132,11 @@
spin_unlock(&lastpid_lock);
return pid;
+
+nomorepids:
+ read_unlock(&tasklist_lock);
+ spin_unlock(&lastpid_lock);
+ return 0;
}
static inline int dup_mmap(struct mm_struct * mm)
@@ -251,7 +263,7 @@
*/
inline void __mmdrop(struct mm_struct *mm)
{
- if (mm == &init_mm) BUG();
+ BUG_ON(mm == &init_mm);
pgd_free(mm->pgd);
destroy_context(mm);
free_mm(mm);
@@ -336,6 +348,9 @@
if (!mm_init(mm))
goto fail_nomem;
+ if (init_new_context(tsk,mm))
+ goto free_pt;
+
down_write(&oldmm->mmap_sem);
retval = dup_mmap(mm);
up_write(&oldmm->mmap_sem);
@@ -348,9 +363,6 @@
*/
copy_segments(tsk, mm);
- if (init_new_context(tsk,mm))
- goto free_pt;
-
good_mm:
tsk->mm = mm;
tsk->active_mm = mm;
@@ -569,6 +581,9 @@
struct task_struct *p;
struct completion vfork;
+ if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
+ return -EINVAL;
+
retval = -EPERM;
/*
@@ -620,6 +635,8 @@
copy_flags(clone_flags, p);
p->pid = get_pid(clone_flags);
+ if (p->pid == 0 && current->pid != 0)
+ goto bad_fork_cleanup;
p->run_list.next = NULL;
p->run_list.prev = NULL;
@@ -671,9 +688,11 @@
goto bad_fork_cleanup_fs;
if (copy_mm(clone_flags, p))
goto bad_fork_cleanup_sighand;
+ if (copy_namespace(clone_flags, p))
+ goto bad_fork_cleanup_mm;
retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
if (retval)
- goto bad_fork_cleanup_mm;
+ goto bad_fork_cleanup_namespace;
p->semundo = NULL;
/* Our parent execution domain becomes current domain
@@ -710,10 +729,10 @@
/* Need tasklist lock for parent etc handling! */
write_lock_irq(&tasklist_lock);
- /* CLONE_PARENT and CLONE_THREAD re-use the old parent */
+ /* CLONE_PARENT re-uses the old parent */
p->p_opptr = current->p_opptr;
p->p_pptr = current->p_pptr;
- if (!(clone_flags & (CLONE_PARENT | CLONE_THREAD))) {
+ if (!(clone_flags & CLONE_PARENT)) {
p->p_opptr = current;
if (!(p->ptrace & PT_PTRACED))
p->p_pptr = current;
@@ -740,6 +759,8 @@
fork_out:
return retval;
+bad_fork_cleanup_namespace:
+ exit_namespace(p);
bad_fork_cleanup_mm:
exit_mm(p);
bad_fork_cleanup_sighand:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)