Re: [ 2.0.31-PRE10 EXIT.C BUG ] [PATCH]

Gordon Oliver (gordo@telsur.cl)
Tue, 14 Oct 1997 19:29:58 -0300


... Dan Hollis said ...
>There seems to be some bad bug in 2.0.31-pre10. There is some condition
>in exit.c close_files() that corrupts filedescriptors, causing OOPSes,
>quite often with threaded programs.
>
>Ingo Molnar made a patch to reveal this bug, but as yet nobody has
>submitted a fix. The patch to detect it is below:

Herein lies a patch to make sure that proc will never attempt to dereference
a file pointer from a task struct without first verifying that it is not NULL.
In the current ext2 release code it is possible that the task will sleep,

I'm not sure if it is legal to sleep in release, but both ext2 and affs can do so...
The patch below makes sure that the proc filesystem is more robust in the
face of a NULL file pointer in the task structure.

If it is not allowed to sleep in fops->release, you can remove it for ext2 by
turning off EXT2_PREALLOC...

let me know if this fixes the problem... I haven't had any problems up to
now...

-gordo

--
---------------------------------------------------------------
Gordon Oliver	(gordo@telsur.cl)	Independent Consultant
	... Available for consulting on Linux  ...

diff -ur linux-2.0.31/fs/proc/fd.c linux/fs/proc/fd.c --- linux-2.0.31/fs/proc/fd.c Fri Dec 22 08:00:19 1995 +++ linux/fs/proc/fd.c Tue Oct 14 19:04:46 1997 @@ -106,8 +106,9 @@ if (!pid || i >= NR_TASKS) return -ENOENT; - if (fd >= NR_OPEN || !p->files->fd[fd] || !p->files->fd[fd]->f_inode) - return -ENOENT; + if (fd >= NR_OPEN || !p->files || !p->files->fd[fd] + || !p->files->fd[fd]->f_inode) + return -ENOENT; ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd; diff -ur linux-2.0.31/fs/proc/inode.c linux/fs/proc/inode.c --- linux-2.0.31/fs/proc/inode.c Sat Nov 30 07:21:21 1996 +++ linux/fs/proc/inode.c Tue Oct 14 19:02:32 1997 @@ -236,7 +236,7 @@ switch (ino >> 8) { case PROC_PID_FD_DIR: ino &= 0xff; - if (ino >= NR_OPEN || !p->files->fd[ino]) + if (ino >= NR_OPEN || !p->files || !p->files->fd[ino]) return; inode->i_op = &proc_link_inode_operations; inode->i_size = 64; diff -ur linux-2.0.31/fs/proc/link.c linux/fs/proc/link.c --- linux-2.0.31/fs/proc/link.c Fri Dec 22 08:00:19 1995 +++ linux/fs/proc/link.c Tue Oct 14 19:03:11 1997 @@ -121,7 +121,7 @@ if (!p->files) break; ino &= 0xff; - if (ino < NR_OPEN && p->files->fd[ino]) { + if (ino < NR_OPEN && p->files && p->files->fd[ino]) { new_inode = p->files->fd[ino]->f_inode; } break;