- About Goa'14
- Blackshield Awards
- About Speakers
- Siddhesh Poyarekar
Attack of the setuid bit - pt_chown and pwning root terminals
I demonstrate and talk about a recent vulnerability in glibc that was exposed by a FUSE feature of allowing user mounts of filesystems. This was found and reported by Martin Carpenter and was assigned CVE-2013-2207. While this vulnerability is fixed, it still has some open questions about authenticating terminal structures.
The gist of the problem is that the FUSE filesystem has an option to allow user mounts with the 'user_allow_other' option. One could use this option to mount a custom FUSE filesystem that does the following:
- Mount a rogue fuse file system on a user-owned directory
- Write a program that opens /dev/pts/42 as fd 3, where /dev/pts/42 is the path of a root tty
- exec pt_chown via that program
The rogue fuse filesystem provides a couple of overrides for ioctl (TIOCGPIN, TCGETS) that fool pt_chown into thinking that the users current terminal is that root terminal we supplied. I intend to do a live demonstration on this in my talk.
We fixed this in glibc with the obvious resolution of getting rid of pt_chown since it does not add any value to a properly configured Linux system, i.e. one that has devpts configured in the kernel and the devpts filesystem is correctly mounted. Configuring a Linux system (or chroot) in any other manner is just wrong and is asking for trouble - we don't support that as a default configuration in glibc anymore.
There is however a second problem that this exploit uses, which is the way ioctl was used to fool pt_chown into owning the root terminal. Pt_chown calls isatty, which in turn calls TCGETS to verify if the file descriptor is a tty. While fuse allows filesystems to provide their own ioctls, it does not give the filesystem access to the termios structure. As a result the ioctl cannot fill in any fake details. It can however simply return success, which is what is done in this exploit. The isatty implementation (and the underlying tcgetattr) do not check to see if the structure is modified and hence simply believes whatever the fuse filesystem sends it.
We could mitigate this in the userspace in glibc by filling the termios structure with some canary value and ensuring that it has been overwritten, but that is a specific case. There needs to be a thorough investigation of the kind of ioctl interfaces a fuse filesystem is allowed to override and ensure that they don't have any security implications.
I am a toolchain engineer from Red Hat and I contribute to the GNU C Library project. In the past I have worked on a variety of technologies from middleware messaging to desktop applications, mostly in the Free and Open Source Software space.