summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-11-05 11:36:16 +0000
committerkib <kib@FreeBSD.org>2007-11-05 11:36:16 +0000
commit9ae733819b7cdf0eef51ba1b18d39feb136a9dbf (patch)
treecccec36134d2cab5ce1eabb67dcaab5981e9beb0 /sys/i386
parentf3f033b9b90ea07350fbe7483af3d9636cb31d1d (diff)
downloadFreeBSD-src-9ae733819b7cdf0eef51ba1b18d39feb136a9dbf.zip
FreeBSD-src-9ae733819b7cdf0eef51ba1b18d39feb136a9dbf.tar.gz
Fix for the panic("vm_thread_new: kstack allocation failed") and
silent NULL pointer dereference in the i386 and sparc64 pmap_pinit() when the kmem_alloc_nofault() failed to allocate address space. Both functions now return error instead of panicing or dereferencing NULL. As consequence, vmspace_exec() and vmspace_unshare() returns the errno int. struct vmspace arg was added to vm_forkproc() to avoid dealing with failed allocation when most of the fork1() job is already done. The kernel stack for the thread is now set up in the thread_alloc(), that itself may return NULL. Also, allocation of the first process thread is performed in the fork1() to properly deal with stack allocation failure. proc_linkup() is separated into proc_linkup() called from fork1(), and proc_linkup0(), that is used to set up the kernel process (was known as swapper). In collaboration with: Peter Holm Reviewed by: jhb
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/machdep.c2
-rw-r--r--sys/i386/i386/pmap.c9
-rw-r--r--sys/i386/ibcs2/imgact_coff.c4
-rw-r--r--sys/i386/linux/imgact_linux.c4
4 files changed, 15 insertions, 4 deletions
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 55ec4be..eacbb48 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -2088,7 +2088,7 @@ init386(first)
* This may be done better later if it gets more high level
* components in it. If so just link td->td_proc here.
*/
- proc_linkup(&proc0, &thread0);
+ proc_linkup0(&proc0, &thread0);
metadata_missing = 0;
if (bootinfo.bi_modulep) {
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index b83fd1c..343760a 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -1227,7 +1227,7 @@ pmap_pinit0(pmap_t pmap)
* Initialize a preallocated and zeroed pmap structure,
* such as one in a vmspace structure.
*/
-void
+int
pmap_pinit(pmap_t pmap)
{
vm_page_t m, ptdpg[NPGPTD];
@@ -1244,6 +1244,11 @@ pmap_pinit(pmap_t pmap)
if (pmap->pm_pdir == NULL) {
pmap->pm_pdir = (pd_entry_t *)kmem_alloc_nofault(kernel_map,
NBPTD);
+
+ if (pmap->pm_pdir == NULL) {
+ PMAP_LOCK_DESTROY(pmap);
+ return (0);
+ }
#ifdef PAE
pmap->pm_pdpt = uma_zalloc(pdptzone, M_WAITOK | M_ZERO);
KASSERT(((vm_offset_t)pmap->pm_pdpt &
@@ -1297,6 +1302,8 @@ pmap_pinit(pmap_t pmap)
pmap->pm_active = 0;
TAILQ_INIT(&pmap->pm_pvchunk);
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
+
+ return (1);
}
/*
diff --git a/sys/i386/ibcs2/imgact_coff.c b/sys/i386/ibcs2/imgact_coff.c
index b078e56..74a01f4 100644
--- a/sys/i386/ibcs2/imgact_coff.c
+++ b/sys/i386/ibcs2/imgact_coff.c
@@ -337,7 +337,9 @@ exec_coff_imgact(imgp)
VOP_UNLOCK(imgp->vp, 0, td);
- exec_new_vmspace(imgp, &ibcs2_svr3_sysvec);
+ error = exec_new_vmspace(imgp, &ibcs2_svr3_sysvec);
+ if (error)
+ goto fail;
vmspace = imgp->proc->p_vmspace;
for (i = 0; i < nscns; i++) {
diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c
index 268936d..ce067d5 100644
--- a/sys/i386/linux/imgact_linux.c
+++ b/sys/i386/linux/imgact_linux.c
@@ -119,7 +119,9 @@ exec_linux_imgact(struct image_params *imgp)
/*
* Destroy old process VM and create a new one (with a new stack)
*/
- exec_new_vmspace(imgp, &linux_sysvec);
+ error = exec_new_vmspace(imgp, &linux_sysvec);
+ if (error)
+ goto fail;
vmspace = imgp->proc->p_vmspace;
/*
OpenPOWER on IntegriCloud