On Mon, 27 Sep 2004, Dr Andrew C Aitchison wrote: > I belive at one time the kernel wasn't trusted to stop a malicious > user from generating a SCSI request which was received by a different > device than the one the kernel was told was the target. Even if it were, there's a more subtle security hole lurking here -- most recordable optical drives allow firmware updates via the bus. Aside from filtering specific commands to specific devices (error-prone and difficult to maintain, especially as the commands in question are frequently undocumented), there's nothing the kernel can do to prevent the uploading of malicious firmware that, among other things, could proxy SCSI commands to other devices on the bus. This probably isn't an issue on a single-initiator bus like IDE, but it's certainly possible in the multiple-initiator world of SCSI. In addition, there are many opportunities for denial-of-service, particularly with older devices that don't do a very good job of sharing the SCSI bus in the first place (e.g., devices that don't support disconnect/reconnect), and devices that allow SCSI controller configuration via mode pages (e.g., disabling D/R). Of course, it's probably a bad idea to put the first class of devices on the same bus with critical devices in the first place, but I digress. With that said, the safest way to run cdrecord seems like the following: - create a user (e.g., cdrecord) and a group (e.g., cdrecord-user) - give the cdrecord user (_not_ the group) permission to access any resources necessary to run cdrecord - chown cdrecord:cdrecord-user cdrecord - chmod 4550 cdrecord This is simply the principle of least privilege. Cdrecord shouldn't need to be root -- it only needs certain permissions to get its job done. Cdrecord users don't need to be able to send arbitrary SCSI commands -- cdrecord itself does. The notion that a program must be root if an ordinary user doesn't have the necessary permissions by default is a dangerous one. Sometimes UNIX makes this unavoidable (root-based security checks, e.g., privileged port access), but, curiously, I see it more in the Windows world, where lots of software wants to run as either a local Administrator or LocalSystem (i.e., as a part of the TCB) instead of as an ordinary user with whatever additional privileges are required, even though more granular security is available (e.g., why does the Windows Time service need to run as a part of the TCB? It needs to be able to set the system's clock, but NT has a separate privilege [SeSystemTime] for this, presumably for a reason). If one were to re-implement cdrecord with security in mind, it may make sense to separate it into two executables: - a front-end program, running as the user, which does command-line processing, file access, and other tasks not directly related to device control - a "device access" program, running as cdrecord, which contains the minimum amount of code necessary to control the optical drives. The front-end would send it generic requests (e.g., write, finalize) which would then be translated into the appropriate SCSI commands. This way, only the smaller (and, presumably, easier to audit) "device access" program would have to be trusted with raw SCSI access. Since the "device access" portion of cdrecord is probably the largest and most error-prone portion of the code (I assume this from my own experience writing SCSI software, not from inspecting the cdrecord sources), it is questionable whether this would be worth the trouble. However, if implemented as a generic, portable "burner daemon" with a simplified API that could be useful to multiple front-end programs (e.g., X11 front ends, music players, backup software), it could be worthwhile. -jtm