涉及程序: eject 2.0.10 描述: eject文件/目录地址泄露缺陷 详细: eject程序用于弹出CD-ROM、 ZIP 磁盘等可移动介质。在SuSE Linux中,eject程序缺省安装在SUID root中。eject使用命令行获取设备名,如果文件存在,并且是一个正常的设备,将对其进行检测。合法用户能运行下列命令: eject /root/fubar 将返回跟踪误差信息: -device not found -invalid ioctl 如果返回“device not found”,表示没有找到文件;如果返回“invalid ioctl”,将调用/root/fubar。接着运行: eject /root/fubar/.. 将再次获得上述错误信息。但是此时的“device not found”表示/root/fubar是一个正常文件,如果返回“invalid ioctl”,代表一个目录。 攻击方法: 运行下列命令: eject /root/fubar 将返回跟踪误差信息: -device not found -invalid ioctl 如果返回“device not found”,表示没有找到文件;如果返回“invalid ioctl”,将调用/root/fubar。 接着运行: eject /root/fubar/.. 将再次获得上述错误信息。但是此时的“device not found”表示/root/fubar是一个正常文件,如果返回“invalid ioctl”,代表一个目录。 解决方案: 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; } }