public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Very weird bug in fs/exec.c
@ 2002-06-27 21:19 Felipe Contreras
  2002-06-28  4:35 ` Jordan Breeding
  0 siblings, 1 reply; 2+ messages in thread
From: Felipe Contreras @ 2002-06-27 21:19 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 453 bytes --]

Hi,

I've found a weird bug that seems to only happend in my system. It makes
recursive makes segfault, like:

test:
	( make -v )

After a lot of work tracking it I finally found what causes it, I'm attaching
the patch that generates the bug, it's a diff from 2.5.18 to 2.5.19.

I'm saying it's weird because just adding a printk before do_execve returns
successfully makes the bug dissapear.

BTW, yes, my system is very special.

-- 
Felipe Contreras

[-- Attachment #2: bug.diff --]
[-- Type: text/plain, Size: 3227 bytes --]

--- a/fs/exec.c	Wed May 29 11:43:02 2002
+++ b/fs/exec.c	Wed May 29 11:43:02 2002
@@ -391,48 +391,31 @@
 	return result;
 }
 
-static int exec_mmap(void)
+static int exec_mmap(struct mm_struct *mm)
 {
-	struct mm_struct * mm, * old_mm;
+	struct mm_struct * old_mm, *active_mm;
 
-	old_mm = current->mm;
-	if (old_mm && atomic_read(&old_mm->mm_users) == 1) {
-		mm_release();
-		exit_mmap(old_mm);
-		return 0;
-	}
-
-	mm = mm_alloc();
-	if (mm) {
-		struct mm_struct *active_mm;
-
-		if (init_new_context(current, mm)) {
-			mmdrop(mm);
-			return -ENOMEM;
-		}
+	/* Add it to the list of mm's */
+	spin_lock(&mmlist_lock);
+	list_add(&mm->mmlist, &init_mm.mmlist);
+	mmlist_nr++;
+	spin_unlock(&mmlist_lock);
 
-		/* Add it to the list of mm's */
-		spin_lock(&mmlist_lock);
-		list_add(&mm->mmlist, &init_mm.mmlist);
-		mmlist_nr++;
-		spin_unlock(&mmlist_lock);
-
-		task_lock(current);
-		active_mm = current->active_mm;
-		current->mm = mm;
-		current->active_mm = mm;
-		activate_mm(active_mm, mm);
-		task_unlock(current);
-		mm_release();
-		if (old_mm) {
-			if (active_mm != old_mm) BUG();
-			mmput(old_mm);
-			return 0;
-		}
-		mmdrop(active_mm);
+	task_lock(current);
+	old_mm = current->mm;
+	active_mm = current->active_mm;
+	current->mm = mm;
+	current->active_mm = mm;
+	activate_mm(active_mm, mm);
+	task_unlock(current);
+	mm_release();
+	if (old_mm) {
+		if (active_mm != old_mm) BUG();
+		mmput(old_mm);
 		return 0;
 	}
-	return -ENOMEM;
+	mmdrop(active_mm);
+	return 0;
 }
 
 /*
@@ -571,7 +554,7 @@
 	/* 
 	 * Release all of the old mmap stuff
 	 */
-	retval = exec_mmap();
+	retval = exec_mmap(bprm->mm);
 	if (retval) goto mmap_failed;
 
 	/* This is the point of no return */
@@ -902,17 +885,23 @@
 	bprm.sh_bang = 0;
 	bprm.loader = 0;
 	bprm.exec = 0;
-	if ((bprm.argc = count(argv, bprm.p / sizeof(void *))) < 0) {
-		allow_write_access(file);
-		fput(file);
-		return bprm.argc;
-	}
 
-	if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) {
-		allow_write_access(file);
-		fput(file);
-		return bprm.envc;
-	}
+	bprm.mm = mm_alloc();
+	retval = -ENOMEM;
+	if (!bprm.mm)
+		goto out_file;
+
+	retval = init_new_context(current, bprm.mm);
+	if (retval < 0)
+		goto out_mm;
+
+	bprm.argc = count(argv, bprm.p / sizeof(void *));
+	if ((retval = bprm.argc) < 0)
+		goto out_mm;
+
+	bprm.envc = count(envp, bprm.p / sizeof(void *));
+	if ((retval = bprm.envc) < 0)
+		goto out_mm;
 
 	retval = prepare_binprm(&bprm);
 	if (retval < 0) 
@@ -938,16 +927,20 @@
 
 out:
 	/* Something went wrong, return the inode and free the argument pages*/
-	allow_write_access(bprm.file);
-	if (bprm.file)
-		fput(bprm.file);
-
 	for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
 		struct page * page = bprm.page[i];
 		if (page)
 			__free_page(page);
 	}
 
+out_mm:
+	mmdrop(bprm.mm);
+
+out_file:
+	if (bprm.file) {
+		allow_write_access(bprm.file);
+		fput(bprm.file);
+	}
 	return retval;
 }
 
--- a/include/linux/binfmts.h	Wed May 29 11:43:03 2002
+++ b/include/linux/binfmts.h	Wed May 29 11:43:03 2002
@@ -22,6 +22,7 @@
 struct linux_binprm{
 	char buf[BINPRM_BUF_SIZE];
 	struct page *page[MAX_ARG_PAGES];
+	struct mm_struct *mm;
 	unsigned long p; /* current top of mem */
 	int sh_bang;
 	struct file * file;

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Very weird bug in fs/exec.c
  2002-06-27 21:19 Very weird bug in fs/exec.c Felipe Contreras
@ 2002-06-28  4:35 ` Jordan Breeding
  0 siblings, 0 replies; 2+ messages in thread
From: Jordan Breeding @ 2002-06-28  4:35 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: linux-kernel

Felipe Contreras wrote:
> Hi,
> 
> I've found a weird bug that seems to only happend in my system. It makes
> recursive makes segfault, like:
> 
> test:
> 	( make -v )
> 
> After a lot of work tracking it I finally found what causes it, I'm attaching
> the patch that generates the bug, it's a diff from 2.5.18 to 2.5.19.
> 
> I'm saying it's weird because just adding a printk before do_execve returns
> successfully makes the bug dissapear.
> 
> BTW, yes, my system is very special.
> 


I can verify that a lot of weird problems (compiles failing with seg 
faults, `java -version` not running, other java programs not running and 
in most cases the program in question would succeed if I ran it through 
strace first) I was seeing in kernels after 2.5.18 (ie. 2.5.20-dj1, 
2.5.20-dj4, 2.5.23-dj1 and 2.5.24-dj1) go away if I reverse the patch 
included in the original email for this thread.  Glad to find out what 
had been causing that mess!  Thanks.

Jordan



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-06-28  4:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-06-27 21:19 Very weird bug in fs/exec.c Felipe Contreras
2002-06-28  4:35 ` Jordan Breeding

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox