###################################################################### Application: eject Version: 2.0.10 Platforms: Linux Distribution: SuSE 7.3, most likely other versions of SuSE Linux as well also all distributions that make eject SUID root Bugs: verbose error messages reveal location of files/directories Risk: low Author: nordi e-mail: nordi@addcom.de ###################################################################### 1) Introduction 2) Bug 3) Impact 4) Fix ###################################################################### =============== 1) Introduction =============== The eject program is used to eject CDs, Zip-disks and the like. On SuSE Linux, eject is installed by default and set SUID root. ###################################################################### ====== 2) Bug ====== Eject takes the name of the device to eject as command line argument. It then checks if the file exists and if it is a valid device. When eject is installed SUID root a normal user can run the command eject /root/fubar and will get one of the following error messages: -device not found -invalid ioctl If you get "device not found" you know there is no file of that name. But if you get "invalid ioctl" then you know there is something called /root/fubar. Now you run eject /root/fubar/.. Again you get one of the above error messages. Now, "device not found" means that /root/fubar is a normal file. If you get "invalid ioctl", then it is a directory. ###################################################################### ========== 3) Impact =========== The impact is relativly small, but this bug can still help an attacker by revealing which files/directories exist: An attacker can make a good guess what programs a specific user usually uses if he knows what configuration files exist in this user's home directory. Also, the check if the file exists is done by opening the file for reading. This changes the access-time of the file. Software that relies on the atime may get confused. ###################################################################### ====== 4) Fix ====== diff -Nurd eject-2.0.10/eject.c eject-2.0.11/eject.c --- eject-2.0.10/eject.c Mon Jul 2 22:17:41 2001 +++ eject-2.0.11/eject.c Fri Nov 22 17:26:25 2002 @@ -273,14 +273,13 @@ /* Return 1 if file/device exists, 0 otherwise. */ static int FileExists(const char *name) { - int fd; - - fd = open(name, O_RDONLY|O_NONBLOCK); - if (fd == -1) { - return 0; - } else { - close(fd); + /*access() uses the UID, not the EUID. This way a normal user cannot find out if a file + (say, /root/fubar) exists or not, even if eject is SUID root*/ + if (access (name, F_OK) == 0) { return 1; + } + else { + return 0; } } ######################################################################