patch-2.4.22 linux-2.4.22/fs/exec.c

Next file: linux-2.4.22/fs/ext3/file.c
Previous file: linux-2.4.22/fs/dquot.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/fs/exec.c linux-2.4.22/fs/exec.c
@@ -286,6 +286,8 @@
 	pgd_t * pgd;
 	pmd_t * pmd;
 	pte_t * pte;
+	struct vm_area_struct *vma; 
+	pgprot_t prot = PAGE_COPY; 
 
 	if (page_count(page) != 1)
 		printk(KERN_ERR "mem_map disagrees with %p at %08lx\n", page, address);
@@ -303,7 +305,11 @@
 	lru_cache_add(page);
 	flush_dcache_page(page);
 	flush_page_to_ram(page);
-	set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY))));
+	/* lookup is cheap because there is only a single entry in the list */
+	vma = find_vma(tsk->mm, address); 
+	if (vma) 
+		prot = vma->vm_page_prot;
+	set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, prot))));
 	tsk->mm->rss++;
 	spin_unlock(&tsk->mm->page_table_lock);
 
@@ -338,8 +344,8 @@
 		mpnt->vm_mm = current->mm;
 		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
 		mpnt->vm_end = STACK_TOP;
-		mpnt->vm_page_prot = PAGE_COPY;
 		mpnt->vm_flags = VM_STACK_FLAGS;
+		mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
 		mpnt->vm_ops = NULL;
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
@@ -557,6 +563,7 @@
 	char * name;
 	int i, ch, retval;
 	struct signal_struct * oldsig;
+	struct files_struct * files;
 
 	/*
 	 * Make sure we have a private signal table
@@ -565,6 +572,17 @@
 	retval = make_private_signals();
 	if (retval) goto flush_failed;
 
+	/*
+	 * Make sure we have private file handles. Ask the
+	 * fork helper to do the work for us and the exit
+	 * helper to do the cleanup of the old one.
+	 */
+	 
+	files = current->files;		/* refcounted so safe to hold */
+	retval = unshare_files();
+	if(retval)
+		goto flush_failed;
+	
 	/* 
 	 * Release all of the old mmap stuff
 	 */
@@ -572,6 +590,8 @@
 	if (retval) goto mmap_failed;
 
 	/* This is the point of no return */
+	steal_locks(files);
+	put_files_struct(files);
 	release_old_signals(oldsig);
 
 	current->sas_ss_sp = current->sas_ss_size = 0;
@@ -609,6 +629,8 @@
 	return 0;
 
 mmap_failed:
+	put_files_struct(current->files);
+	current->files = files;
 flush_failed:
 	spin_lock_irq(&current->sigmask_lock);
 	if (current->sig != oldsig) {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)