Archive

Archive for December, 2009

Ext4 online defrag and how you can mess up everything when implementing it

December 20th, 2009 2 comments

It’s been a long time since I last posted something at my blog. Unfortunatelly, I’m too busy so I have almost no time to write something!

This post is about the online defrag the ext4 filesystem supports. It is a very cool feature and allows you to defrag any file without even unmounting a filesystem! This is done using a special ioctl, EXT4_IOC_MOVE_EXT defined as follows:

As you can see the ioctl’s last parameter is a special structure, struct move_extent, defined as:

What the ioctl does is copy len extents from the file with descriptor orig_fd starting with orig_start to the one with descriptor donor_fd starting at donor_start. Finally it returns the total number of extents moved at the member moved_len. Using this syscall it is pretty easy to defrag files. You must first open a new file, which will be the donor, and allocate some space using fallocate. Hopefully the extents of the new file will be less than the ones of the original file so you just swap the extents of donor using the ones from the original file. The following code is a simple call to this ioctl which can help you understand how it works:

You should note that there is no restriction on the doner file, it can be any file on the disk.

And here it is! CVE-2009-4131! Until commit 910123ba363623f15ffb5d05dd87bdf06d08c609 the only check was if the user could read the donor file, not write it! Furthermore, there were no checks on the file’s mode. You can simply open your program which executes /bin/sh as the original file, /bin/ping as the donor and kaboom! /bin/ping is an suid root executable and the code that will be executed will be your code!

I have written a small program that you can use to demonstrate this vulnerability. It simply moves extents. You can download it here. Just use a program that spawns a shell as the original file, a suid root file as a donor, zero as the offset and ceil(filesize/1024) as len. However, it is not very usable yet since for some strange reason you need to unmount the fs and then remount it in order for the changes to take effect. If you find a solution just leave a comment!

UPDATE: Try reading a LOT of data from the partition after running the program! Damn cache! I shouldn’t have been working with a filesystem that’s 10mbs and store only the executable there!

Categories: Linux, Programming Tags:
SEO Powered by Platinum SEO from Techblissonline

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close