Package: cdrecord Version: 4:2.0+a34-2 Followup-For: Bug #267273 When installed suid, cdrecord drops its root privileges early, and then tries to issue SCSI commands. This does not work with newer kernels (>=2.6.8.1) because that security hole has been fixed and processes are now required to have CAP_SYS_RAWIO to use SCSI commands. The attached patch (which is unlikely to be accepted upstream because the author hates Linux) fixes this.
-- System Information: Debian Release: 3.1 APT prefers testing APT policy: (900, 'testing') Architecture: i386 (i686) Kernel: Linux 2.6.10-mm1-v0.7.34-01 Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Versions of packages cdrecord depends on: ii debconf 1.4.30.11 Debian configuration management sy ii libc6 2.3.2.ds1-20 GNU C Library: Shared libraries an ii makedev 2.3.1-75 Creates device files in /dev
--- cdrecord.c.orig 2005-01-13 00:18:39.000000000 -0500 +++ cdrecord.c.new 2005-01-13 00:29:04.000000000 -0500 @@ -58,6 +58,7 @@ #include "defaults.h" #include "movesect.h" +#include <sys/capability.h> /* for rawio capability */ char cdr_version[] = "2.01a34"; @@ -242,6 +243,7 @@ LOCAL void print_wrmodes __PR((cdr_t *dp)); LOCAL BOOL check_wrmode __PR((cdr_t *dp, int wmode, int tflags)); LOCAL void set_wrmode __PR((cdr_t *dp, int wmode, int tflags)); +LOCAL int get_cap __PR((cap_value_t cap_array)); struct exargs { SCSI *scgp; @@ -479,6 +481,12 @@ #endif comerr("Panic cannot set back effective uid.\n"); } + + /* get the rawio capability */ + if (get_cap(CAP_SYS_RAWIO)) + perror("Error: Cannot gain SYS_RAWIO capability." + "Is cdrecord installed SUID root?\n"); + /* * WARNING: We now are no more able to do any privilleged operation * unless we have been called by root. @@ -1004,6 +1012,10 @@ if (setreuid(-1, getuid()) < 0) comerr("Panic cannot set back effective uid.\n"); } + if (get_cap(CAP_SYS_RAWIO)) + perror("Error: Cannot gain SYS_RAWIO capability." + "Is cdrecord installed SUID root?\n"); + #endif } if ((*dp->cdr_set_speed_dummy)(scgp, dp, &speed) < 0) { @@ -4613,3 +4625,17 @@ } dsp->ds_wrmode = WM_NONE; } + +LOCAL int +get_cap(cap_array) + cap_value_t cap_array; +{ + int ret; + cap_t capa; + capa = cap_get_proc(); + cap_set_flag(capa, CAP_EFFECTIVE, 1, &cap_array, CAP_SET); + ret = cap_set_proc(capa); + cap_free(capa); + return ret; +} +