* 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