Package: eject
Version: 2.1.5+deb1+cvs20081104-11
Severity: wishlist

Dear Maintainer,
I noticed that the only reason dmcrypt-get-device (from eject package) needs 
setuid privilege is to read the major:minor numbers (unless I have missed 
something).
A lot of distributions are trying to avoid use of the setuid bit because it can 
potentially introduce a privilege escalation attack vector.
I think the same thing could be accomplished by reading the major:minor device 
numbers through a sys file, and then eliminate the need for dmcrypt-get-device 
to be setuid-to-root.
The major:minor numbers are available in the file /sys/block/dm-*/dev and the 
corresponding device name can be confirmed from file /sys/block/dm-*/dm/name.
Martin Pitt - the author of dmcrypt-get-device.c - suggested that I should send 
the patch here and you could help integrate and comment on the patch.
Attached is the patch for dmcrypt-get-device.c.

-- System Information:
Debian Release: wheezy/sid
  APT prefers quantal-updates
  APT policy: (500, 'quantal-updates'), (500, 'quantal-security'), (500, 
'quantal'), (100, 'quantal-backports')
Architecture: i386 (i686)

Kernel: Linux 3.5.0-17-generic (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages eject depends on:
ii  libc6               2.15-0ubuntu20
ii  libdevmapper1.02.1  2:1.02.74-4ubuntu1

eject recommends no packages.

Versions of packages eject suggests:
pn  cdtool  <none>
pn  setcd   <none>

-- no debconf information
--- original-dmcrypt-get-device.c	2012-12-09 05:29:50.792388997 -0500
+++ dmcrypt-get-device.c	2012-12-09 05:38:00.512388998 -0500
@@ -15,20 +15,22 @@
  * parsing is done with normal user privileges afterwards.
  */
 
-#include <libdevmapper.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <linux/dm-ioctl.h>
 
 int
 main (int argc, char** argv)
 {
-    struct dm_task *dmt = NULL;
-    struct dm_info dmi;
-    char *target_type = NULL, *params = NULL;
-    uint64_t start, length;
-    void *next = NULL;
+    DIR *dir;
+    FILE *file;
+    struct dirent *ent;
+    char filename[4096];
+    char name[DM_NAME_LEN];
     struct stat st;
     unsigned major, minor;
 
@@ -49,37 +51,35 @@
     if (stat (argv[1], &st) || !S_ISBLK(st.st_mode))
         return 1;
 
-    /* Request device info */
-    if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
-        return 1;
-    if (!dm_task_set_name(dmt, argv[1]))
-        return 1;
-    if (!dm_task_run(dmt))
-        return 1;
-
-    /* Drop all privileges */
-    setgid(getgid());
-    setuid(getuid());
-
-    if (!dm_task_get_info(dmt, &dmi))
-        return 1;
-
-    /* Get underlying physical device */
-    next = dm_get_next_target(dmt, next, &start, &length,
-            &target_type, &params);
-
-    /* verify validity and that it is a dmcrypt device */
-    if (!target_type || strcmp(target_type, "crypt")  || next)
-        return 1;
-
-    /* params has the format: cipher key offset major:minor <unknown> */
-    length = sscanf(params, "%*s %*s %*s %u:%u %*s", &major, &minor);
-    if (length != 2)
-        return 1;
+    if ((dir = opendir("/sys/block")) == NULL)
+    {
+      perror("Unable to open directory");
+      return 1;
+    }
 
-    /* Success */
-    printf ("%u:%u\n", major, minor);
-    
-    return 0;
+    while ((ent = readdir(dir)) != NULL)
+    {
+        const char* dmname = "dm-";
+        /* Check for the device name */
+    	if(!strncmp(ent->d_name, dmname, strlen(dmname)))
+    	{
+    		sprintf(filename,"/sys/block/%s/dm/name",ent->d_name);
+    		file = fopen(filename,"r");
+    		fscanf(file,"%s",name);
+    		fclose(file);
+            /* Read the major:minor number for given device */
+    		if(!strcmp(name,argv[1] + devmapdirlen))
+    		{
+        		sprintf(filename,"/sys/block/%s/dev",ent->d_name);
+        		file = fopen(filename,"r");
+        		fscanf(file,"%u:%u",&major,&minor);
+        	    /* Success */
+                printf ("%u:%u\n", major, minor);
+        		fclose(file);
+                return 0;
+    		}
+    	}
+    }
+    /* Not found */
+    return 1;
 }
-

Reply via email to