]> granicus.if.org Git - procps-ng/commitdiff
ps: use attr/current as fallback for context
authorLaurent Bigonville <bigon@debian.org>
Sun, 3 Jan 2016 07:11:51 +0000 (18:11 +1100)
committerCraig Small <csmall@enc.com.au>
Fri, 15 Apr 2016 21:44:31 +0000 (07:44 +1000)
If SELINUX is enabled but the machine is using another MAC system
(like apparmor), ps will fallback to just parsing
"/proc/%d/attr/current", otherwise the label/context would not
be properly displayed in that case.

References:
 https://bugs.debian.org/786956

Signed-off-by: Craig Small <csmall@enc.com.au>
NEWS
ps/output.c

diff --git a/NEWS b/NEWS
index b30aedf3a5ad0e87bb51e56048568dc340b004b4..e92355e742bbea78eb9b6bf4ec29bf5f202a5338 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ procps-ng-NEXT
 ----------------
   * ps: sort by cgroup Debian #692279
   * ps: display control group name with -o cgname
+  * ps: Fallback to attr/current for context Debian #786956
 
 procps-ng-3.3.11
 ----------------
index 16e00c18ad1e67b7114bbd62d40384355906226d..0d637d676db66e1caa916397d8d8d2fab6d4c426 100644 (file)
@@ -1212,64 +1212,68 @@ setREL1(LXCNAME)
 
 /****************** FLASK & seLinux security stuff **********************/
 // move the bulk of this to libproc sometime
-
-#if !ENABLE_LIBSELINUX
-
-static int pr_context(char *restrict const outbuf, const proc_t *restrict const pp){
-  char filename[48];
-  size_t len;
-  ssize_t num_read;
-  int fd;
-setREL1(ID_TGID)
-  snprintf(filename, sizeof filename, "/proc/%d/attr/current", rSv(ID_TGID, s_int, pp));
-  fd = open(filename, O_RDONLY, 0);
-  if(likely(fd==-1)) goto fail;
-  num_read = read(fd, outbuf, 666);
-  close(fd);
-  if(unlikely(num_read<=0)) goto fail;
-  outbuf[num_read] = '\0';
-
-  len = 0;
-  while(outbuf[len]>' ' && outbuf[len]<='~') len++;
-  outbuf[len] = '\0';
-  if(len) return len;
-fail:
-  outbuf[0] = '-';
-  outbuf[1] = '\0';
-  return 1;
-}
-
-#else
-
 // This needs more study, considering:
 // 1. the static linking option (maybe disable this in that case)
 // 2. the -z and -Z option issue
 // 3. width of output
 static int pr_context(char *restrict const outbuf, const proc_t *restrict const pp){
+  static void (*ps_freecon)(char*) = 0;
   static int (*ps_getpidcon)(pid_t pid, char **context) = 0;
+  static int (*ps_is_selinux_enabled)(void) = 0;
   static int tried_load = 0;
+  static int selinux_enabled = 0;
   size_t len;
   char *context;
 setREL1(ID_TGID)
+
+#if ENABLE_LIBSELINUX
   if(!ps_getpidcon && !tried_load){
     void *handle = dlopen("libselinux.so.1", RTLD_NOW);
     if(handle){
+      ps_freecon = dlsym(handle, "freecon");
+      if(dlerror())
+        ps_freecon = 0;
       dlerror();
       ps_getpidcon = dlsym(handle, "getpidcon");
       if(dlerror())
         ps_getpidcon = 0;
+      ps_is_selinux_enabled = dlsym(handle, "is_selinux_enabled");
+      if(dlerror())
+        ps_is_selinux_enabled = 0;
+      else
+        selinux_enabled = ps_is_selinux_enabled();
     }
     tried_load++;
   }
-  if(ps_getpidcon && !ps_getpidcon(rSv(ID_TGID, s_int, pp), &context)){
+#endif
+  if(ps_getpidcon && selinux_enabled && !ps_getpidcon(rSv(ID_TGID, s_int, pp), &context)){
     size_t max_len = OUTBUF_SIZE-1;
     len = strlen(context);
     if(len > max_len) len = max_len;
     memcpy(outbuf, context, len);
     if (outbuf[len-1] == '\n') --len;
     outbuf[len] = '\0';
-    free(context);
+    ps_freecon(context);
   }else{
+    char filename[48];
+    ssize_t num_read;
+    int fd;
+
+    snprintf(filename, sizeof filename, "/proc/%d/attr/current", rSv(ID_TGID, s_int, pp));
+
+    if ((fd = open(filename, O_RDONLY, 0)) != -1) {
+      num_read = read(fd, outbuf, OUTBUF_SIZE-1);
+      close(fd);
+      if (num_read > 0) {
+        outbuf[num_read] = '\0';
+        len = 0;
+        while(isprint(outbuf[len]))
+          len++;
+        outbuf[len] = '\0';
+        if(len)
+          return len;
+      }
+    }
     outbuf[0] = '-';
     outbuf[1] = '\0';
     len = 1;
@@ -1277,9 +1281,6 @@ setREL1(ID_TGID)
   return len;
 }
 
-#endif
-
-
 ////////////////////////////// Test code /////////////////////////////////
 
 // like "args"