Messages in this thread | | | Date | Thu, 15 Oct 2009 20:31:52 -0700 | From | Earl Chew <> | Subject | Re: fs/pipe.c null pointer dereference |
| |
Earl Chew wrote: > I have given the matter more thought, and I believe it is unlikely > that the problem is in fs/fifo.c. As outlined in my previous > email, the code looks ok.
I notice that the other place the rdwr_pipe_fops is set up is:
> static struct inode * get_pipe_inode(void) > { > ... > inode->i_fop = &rdwr_pipe_fops; >
and that get_pipe_inode() is called from:
> struct file *create_write_pipe(void) > { > ... > inode = get_pipe_inode(); > if (!inode) > goto err_file;
and that is called from do_pipe():
> int do_pipe(int *fd) > { > ... > fw = create_write_pipe(); > if (IS_ERR(fw)) > return PTR_ERR(fw); > fr = create_read_pipe(fw); > error = PTR_ERR(fr); > if (IS_ERR(fr)) > goto err_write_pipe;
... and do_pipe() is called from many places.
The stack trace I have shows:
> Call Trace: > [<ffffffff802899a5>] pipe_rdwr_open+0x35/0x70 > [<ffffffff8028125c>] __dentry_open+0x13c/0x230 > [<ffffffff8028143d>] do_filp_open+0x2d/0x40 > [<ffffffff802814aa>] do_sys_open+0x5a/0x100 > [<ffffffff8021faf3>] sysenter_do_call+0x1b/0x67
How can it be possible that sys_open (ie open(2)) can get hold of an inode whose i_fop->open() points at pipe_rdwr_open() ?
Is this possible via /proc/pid/fd/* ?
Yes, it looks likely:
> { echo y ; sleep 1 ; } | { while read ; do echo z$REPLY; done ; } & > PID=$! > OUT=$(ps -efl | grep 'sleep 1' | grep -v grep) > OUT=${OUT%% *} > echo n > /proc/$OUT/fd/1
This test prints zy and zn indicating that the 2nd echo was able to open the writing end of the pipe and inject another character.
Earl
| |