Index: libbb/procps.c =================================================================== --- libbb/procps.c (revision 18744) +++ libbb/procps.c (working copy) @@ -4,7 +4,8 @@ * * Copyright 1998 by Albert Cahalan; all rights reserved. * Copyright (C) 2002 by Vladimir Oleynik - * + * SELinux support: (c) 2007 by Yuichi Nakamura + * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ @@ -95,6 +96,7 @@ { closedir(sp->dir); free(sp->cmd); + USE_SELINUX(free(sp->context);) free(sp); } @@ -109,6 +111,7 @@ unsigned pid; int n; struct stat sb; + USE_SELINUX(security_context_t sid = NULL;) if (!sp) sp = alloc_procps_scan(flags); @@ -132,6 +135,25 @@ sp->pid = pid; if (!(flags & ~PSSCAN_PID)) break; +#if ENABLE_SELINUX + if (flags & PSSCAN_CONTEXT) { + free(sp->context); + sp->context = NULL; + if (is_selinux_enabled()) { + if (getpidcon(sp->pid, &sid) < 0) + sid = NULL; + } + if (sid) { + safe_strncpy(buf, sid, sizeof(buf) - 1); + freecon(sid); + sid = NULL; + } else { + safe_strncpy(buf, "unknown", 7); + } + sp->context = xstrdup(buf); + } +#endif + filename_tail = filename + sprintf(filename, "/proc/%d", pid); if (flags & PSSCAN_UIDGID) { Index: include/libbb.h =================================================================== --- include/libbb.h (revision 18744) +++ include/libbb.h (working copy) @@ -840,6 +840,7 @@ /* basename of executable in exec(2), read from /proc/N/stat, */ /* size from sizeof(task_struct.comm) in /usr/include/linux/sched.h */ char comm[COMM_LEN]; + USE_SELINUX(char *context;) /* user/group? - use passwd/group parsing functions */ } procps_status_t; enum { @@ -856,12 +857,13 @@ PSSCAN_STIME = 1 << 10, PSSCAN_UTIME = 1 << 11, PSSCAN_TTY = 1 << 12, + USE_SELINUX(PSSCAN_CONTEXT = 1 << 13,) /* These are all retrieved from proc/NN/stat in one go: */ PSSCAN_STAT = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID | PSSCAN_COMM | PSSCAN_STATE | PSSCAN_VSZ | PSSCAN_RSS | PSSCAN_STIME | PSSCAN_UTIME - | PSSCAN_TTY, + | PSSCAN_TTY USE_SELINUX(| PSSCAN_CONTEXT) , }; procps_status_t* alloc_procps_scan(int flags); void free_procps_scan(procps_status_t* sp); Index: procps/ps.c =================================================================== --- procps/ps.c (revision 18744) +++ procps/ps.c (working copy) @@ -3,6 +3,8 @@ * Mini ps implementation(s) for busybox * * Copyright (C) 1999-2004 by Erik Andersen + * Fix for SELinux Support:(c)2007 Hiroshi Shinji + (c)2007 Yuichi Nakamura * * Licensed under the GPL version 2, see the file LICENSE in this tarball. */ @@ -68,6 +70,14 @@ { safe_strncpy(buf, ps->tty_str, size+1); } + +#if ENABLE_SELINUX +static void func_label(char *buf, int size, const procps_status_t *ps) +{ + safe_strncpy(buf, ps->context, size+1); +} +#endif + /* static void func_nice(char *buf, int size, const procps_status_t *ps) { @@ -116,11 +126,19 @@ { 4 , "vsz" ,"VSZ" ,func_vsz ,PSSCAN_VSZ }, // Not mandated by POSIX, but useful: { 4 , "rss" ,"RSS" ,func_rss ,PSSCAN_RSS }, +#if ENABLE_SELINUX + { 35 , "label" ,"LABEL" ,func_label ,PSSCAN_CONTEXT }, +#endif }; #define VEC_SIZE(v) ( sizeof(v) / sizeof((v)[0]) ) -#define DEFAULT_O_STR "pid,user" /* TODO: ,vsz,stat */ ",args" +#if ENABLE_SELINUX +#define SELINIX_O_PREFIX "label," +#define DEFAULT_O_STR SELINIX_O_PREFIX "pid,user" /* TODO: ,vsz,stat */ ",args" +#else +#define DEFAULT_O_STR "pid,user" /* TODO: ,vsz,stat */ ",args" +#endif struct globals { ps_out_t* out; @@ -261,10 +279,8 @@ { procps_status_t *p; llist_t* opt_o = NULL; + USE_SELINUX(int opt;) - /* Cannot be const: parse_o() will choke */ - strcpy(default_o, DEFAULT_O_STR); - // POSIX: // -a Write information for all processes associated with terminals // Implementations may omit session leaders from this list @@ -277,14 +293,24 @@ // Select which columns to display /* We allow (and ignore) most of the above. FIXME */ opt_complementary = "o::"; - getopt32(argc, argv, "o:aAdefl", &opt_o); + USE_SELINUX(opt =) getopt32(argc, argv, "Zo:aAdefl", &opt_o); if (opt_o) { do { parse_o(opt_o->data); opt_o = opt_o->link; } while (opt_o); - } else + } else { + /* Below: parse_o() needs char*, NOT const char*... */ +#if ENABLE_SELINUX + if (!(opt & 1)) { /* no -Z: do not show LABEL */ + strcpy(default_o, DEFAULT_O_STR + sizeof(SELINIX_O_PREFIX)-1); + } else +#endif + { + strcpy(default_o, DEFAULT_O_STR); + } parse_o(default_o); + } post_process(); /* Was INT_MAX, but some libc's go belly up with printf("%.*s") @@ -314,7 +340,6 @@ procps_status_t *p = NULL; int i, len; SKIP_SELINUX(const) int use_selinux = 0; - USE_SELINUX(security_context_t sid = NULL;) #if !ENABLE_FEATURE_PS_WIDE enum { terminal_width = 79 }; #else @@ -356,27 +381,13 @@ | PSSCAN_STATE | PSSCAN_VSZ | PSSCAN_CMD + USE_SELINUX(| PSSCAN_CONTEXT) ))) { char *namecmd = p->cmd; #if ENABLE_SELINUX if (use_selinux) { char sbuf[128]; - len = sizeof(sbuf); - - if (is_selinux_enabled()) { - if (getpidcon(p->pid, &sid) < 0) - sid = NULL; - } - - if (sid) { - /* I assume sid initialized with NULL */ - len = strlen(sid) + 1; - safe_strncpy(sbuf, sid, len); - freecon(sid); - sid = NULL; - } else { - safe_strncpy(sbuf, "unknown", 7); - } + safe_strncpy(sbuf, p->context, sizeof(sbuf)-1); len = printf("%5u %-32s %s ", p->pid, sbuf, p->state); } else #endif