ps: use attr/current as fallback for context
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>
This commit is contained in:
parent
6fcb690099
commit
5da390422d
1
NEWS
1
NEWS
@ -2,6 +2,7 @@ procps-ng-NEXT
|
|||||||
----------------
|
----------------
|
||||||
* ps: sort by cgroup Debian #692279
|
* ps: sort by cgroup Debian #692279
|
||||||
* ps: display control group name with -o cgname
|
* ps: display control group name with -o cgname
|
||||||
|
* ps: Fallback to attr/current for context Debian #786956
|
||||||
|
|
||||||
procps-ng-3.3.11
|
procps-ng-3.3.11
|
||||||
----------------
|
----------------
|
||||||
|
73
ps/output.c
73
ps/output.c
@ -1283,67 +1283,69 @@ static int pr_lxcname(char *restrict const outbuf, const proc_t *restrict const
|
|||||||
/****************** FLASK & seLinux security stuff **********************/
|
/****************** FLASK & seLinux security stuff **********************/
|
||||||
// move the bulk of this to libproc sometime
|
// 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;
|
|
||||||
|
|
||||||
// wchan file is suitable for testing
|
|
||||||
//snprintf(filename, sizeof filename, "/proc/%d/wchan", pp->tgid);
|
|
||||||
snprintf(filename, sizeof filename, "/proc/%d/attr/current", pp->tgid);
|
|
||||||
|
|
||||||
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:
|
// This needs more study, considering:
|
||||||
// 1. the static linking option (maybe disable this in that case)
|
// 1. the static linking option (maybe disable this in that case)
|
||||||
// 2. the -z and -Z option issue
|
// 2. the -z and -Z option issue
|
||||||
// 3. width of output
|
// 3. width of output
|
||||||
static int pr_context(char *restrict const outbuf, const proc_t *restrict const pp){
|
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_getpidcon)(pid_t pid, char **context) = 0;
|
||||||
|
static int (*ps_is_selinux_enabled)(void) = 0;
|
||||||
static int tried_load = 0;
|
static int tried_load = 0;
|
||||||
|
static int selinux_enabled = 0;
|
||||||
size_t len;
|
size_t len;
|
||||||
char *context;
|
char *context;
|
||||||
|
|
||||||
|
#if ENABLE_LIBSELINUX
|
||||||
if(!ps_getpidcon && !tried_load){
|
if(!ps_getpidcon && !tried_load){
|
||||||
void *handle = dlopen("libselinux.so.1", RTLD_NOW);
|
void *handle = dlopen("libselinux.so.1", RTLD_NOW);
|
||||||
if(handle){
|
if(handle){
|
||||||
|
ps_freecon = dlsym(handle, "freecon");
|
||||||
|
if(dlerror())
|
||||||
|
ps_freecon = 0;
|
||||||
dlerror();
|
dlerror();
|
||||||
ps_getpidcon = dlsym(handle, "getpidcon");
|
ps_getpidcon = dlsym(handle, "getpidcon");
|
||||||
if(dlerror())
|
if(dlerror())
|
||||||
ps_getpidcon = 0;
|
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++;
|
tried_load++;
|
||||||
}
|
}
|
||||||
if(ps_getpidcon && !ps_getpidcon(pp->tgid, &context)){
|
#endif
|
||||||
|
if(ps_getpidcon && selinux_enabled && !ps_getpidcon(pp->tgid, &context)){
|
||||||
size_t max_len = OUTBUF_SIZE-1;
|
size_t max_len = OUTBUF_SIZE-1;
|
||||||
len = strlen(context);
|
len = strlen(context);
|
||||||
if(len > max_len) len = max_len;
|
if(len > max_len) len = max_len;
|
||||||
memcpy(outbuf, context, len);
|
memcpy(outbuf, context, len);
|
||||||
if (outbuf[len-1] == '\n') --len;
|
if (outbuf[len-1] == '\n') --len;
|
||||||
outbuf[len] = '\0';
|
outbuf[len] = '\0';
|
||||||
free(context);
|
ps_freecon(context);
|
||||||
}else{
|
}else{
|
||||||
|
char filename[48];
|
||||||
|
ssize_t num_read;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
// wchan file is suitable for testing
|
||||||
|
//snprintf(filename, sizeof filename, "/proc/%d/wchan", pp->tgid);
|
||||||
|
snprintf(filename, sizeof filename, "/proc/%d/attr/current", pp->tgid);
|
||||||
|
|
||||||
|
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[0] = '-';
|
||||||
outbuf[1] = '\0';
|
outbuf[1] = '\0';
|
||||||
len = 1;
|
len = 1;
|
||||||
@ -1351,9 +1353,6 @@ static int pr_context(char *restrict const outbuf, const proc_t *restrict const
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////// Test code /////////////////////////////////
|
////////////////////////////// Test code /////////////////////////////////
|
||||||
|
|
||||||
// like "args"
|
// like "args"
|
||||||
|
Loading…
Reference in New Issue
Block a user