Commit e2e83e40 authored by Darrick Wong's avatar Darrick Wong Committed by Linus Torvalds

[PATCH] Fix BUG in io_destroy

With Suparna Bhattacharya <suparna@in.ibm.com>

I was running a random system call generator against mainline the other 
day and got this bug report about AIO in dmesg:

kernel BUG at fs/aio.c:1249!

Each ioctx structure has a "users" field that acts as a reference counter
for the ioctx, and a "dead" flag that seems to indicate that the ioctx
isn't associated with any particular list of IO requests.

The problem, then, lies in aio.c:1247.  The io_destroy function checks the
(old) value of the dead flag--if it's false (i.e.  the ioctx is alive),
then the function calls put_ioctx to decrease the reference count on the
assumption that the ioctx is no longer associated with any requests. 
Later, it calls put_ioctx again, on the assumption that someone called
lookup_ioctx to perform some operation at some point.

This BUG is caused by the reference counts being off.  The testcase that
I provided looks for a chunk of user memory that's read-only and passes
that to the sys_io_setup syscall.  sys_io_setup checks that the pointer
is readable, creates the ioctx and then tries to write the ioctx handle
back to userland.  This is where the problems start to surface.

Since the pointer points to a non-writable region of memory, the write
fails.  The syscall handler then destroys the ioctx.  The dead flag is
zero, so io_destroy calls put_ioctx...but wait!  Nobody ever put the ioctx
into a request list.  The ioctx is alive but not in a list, yet the
io_destroy code assumes that being alive implies being in a request list
somewhere.  Hence, calling put_ioctx is bogus; the reference count becomes
0, and the ioctx is freed.  Worse yet, put_ioctx is called again (on a
freed pointer!) to clear up the lookup_ioctx that never happened. 
put_ioctx sees that the reference count has become negative and BUGs.

Suparna's patch simply takes that additional ref so that io_destroy() will
dtrt.
Signed-off-by: default avatarDarrick Wong <djwong@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f52c44de
...@@ -1285,6 +1285,7 @@ asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp) ...@@ -1285,6 +1285,7 @@ asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
if (!ret) if (!ret)
return 0; return 0;
get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */
io_destroy(ioctx); io_destroy(ioctx);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment