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; 
+}
+

Reply via email to