Linux Kernel *fpos += count signed integer overflow bug

I’ve included an interesting genre of bug I’ve seen in some kernel drivers.  In some cases, it may be exploitable.  However, not everyone would agree that this code represents the bug.


  loff_t pos = *ppos;
  ...
         *ppos = pos + nbytes;
         res = nbytes;
out:
         free_page((unsigned long) page);
         return res;

I’ve included smore code than is necessary, but what is the bug?  The bug is that the file pointer ppos can overflow.  No validation is performed on the result of pos + nbytes.  The file pointer is of type loff_t and is a signed long long, so an overflow leads to a negative result which is not valid.  That the file pointer is now in an undefined state, may leave other sections of code that depend on it vulnerable.

Some may argue that these are not bugs at all.   In 2002 no-one in the Linux camp (and neither I at the time; as I was looking for exploitable conditions) cared much for such bugs and were generally ignored.

But are these types of bugs exploitable?  Depends. It requires another area of code to depend on the value of the file pointer for the above code to become useful from an attackers point of view. Alof of kernel code is definately vulnerable if the lseek code in general was allowed to overflow and make the file pointer negative, but there are explicit checks for this in most of the lseek code. 

Most of the time these bugs are not exploitable.   In 2002, I did however find a number of exploitable conditions concerning the use of interesting reads and seeks.  Some of those bugs were in default installs as part of the proc filesystem.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s