Add the public interfaces getpidprevcon(3) and getpidprevcon_raw(3), and the utility getpidprevcon to gather the previous context before the last exec of a given process. Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> --- v2: added new interfaces to libselinux.map --- libselinux/include/selinux/selinux.h | 5 ++++ libselinux/man/man3/getcon.3 | 10 ++++++++ libselinux/man/man3/getpidprevcon.3 | 1 + libselinux/man/man3/getpidprevcon_raw.3 | 1 + libselinux/src/libselinux.map | 6 +++++ libselinux/src/procattr.c | 18 ++++++++++++++ libselinux/utils/.gitignore | 1 + libselinux/utils/getpidprevcon.c | 33 +++++++++++++++++++++++++ 8 files changed, 75 insertions(+) create mode 100644 libselinux/man/man3/getpidprevcon.3 create mode 100644 libselinux/man/man3/getpidprevcon_raw.3 create mode 100644 libselinux/utils/getpidprevcon.c diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h index 47af9953..a0948853 100644 --- a/libselinux/include/selinux/selinux.h +++ b/libselinux/include/selinux/selinux.h @@ -54,6 +54,11 @@ extern int getpidcon_raw(pid_t pid, char ** con); extern int getprevcon(char ** con); extern int getprevcon_raw(char ** con); +/* Get previous context (prior to last exec) of process identified by pid, and + set *con to refer to it. Caller must free via freecon. */ +extern int getpidprevcon(pid_t pid, char ** con); +extern int getpidprevcon_raw(pid_t pid, char ** con); + /* Get exec context, and set *con to refer to it. Sets *con to NULL if no exec context has been set, i.e. using default. If non-NULL, caller must free via freecon. */ diff --git a/libselinux/man/man3/getcon.3 b/libselinux/man/man3/getcon.3 index e7e394f3..1b4fe4b7 100644 --- a/libselinux/man/man3/getcon.3 +++ b/libselinux/man/man3/getcon.3 @@ -23,6 +23,10 @@ setcon \- set current security context of a process .sp .BI "int getpidcon_raw(pid_t " pid ", char **" context ); .sp +.BI "int getpidprevcon(pid_t " pid ", char **" context ); +.sp +.BI "int getpidprevcon_raw(pid_t " pid ", char **" context ); +.sp .BI "int getpeercon(int " fd ", char **" context ); .sp .BI "int getpeercon_raw(int " fd ", char **" context ); @@ -50,6 +54,11 @@ same as getcon but gets the context before the last exec. returns the process context for the specified PID, which must be free'd with .BR freecon (). +.TP +.BR getpidprevcon () +returns the process context before the last exec for the specified PID, which must be free'd with +.BR freecon (). + .TP .BR getpeercon () retrieves the context of the peer socket, which must be free'd with @@ -125,6 +134,7 @@ will fail if it is not allowed by policy. .BR getcon_raw (), .BR getprevcon_raw (), .BR getpidcon_raw (), +.BR getpidprevcon_raw (), .BR getpeercon_raw () and .BR setcon_raw () diff --git a/libselinux/man/man3/getpidprevcon.3 b/libselinux/man/man3/getpidprevcon.3 new file mode 100644 index 00000000..1210b5a0 --- /dev/null +++ b/libselinux/man/man3/getpidprevcon.3 @@ -0,0 +1 @@ +.so man3/getcon.3 diff --git a/libselinux/man/man3/getpidprevcon_raw.3 b/libselinux/man/man3/getpidprevcon_raw.3 new file mode 100644 index 00000000..1210b5a0 --- /dev/null +++ b/libselinux/man/man3/getpidprevcon_raw.3 @@ -0,0 +1 @@ +.so man3/getcon.3 diff --git a/libselinux/src/libselinux.map b/libselinux/src/libselinux.map index 6e04eb61..5e00f45b 100644 --- a/libselinux/src/libselinux.map +++ b/libselinux/src/libselinux.map @@ -246,3 +246,9 @@ LIBSELINUX_3.4 { selinux_restorecon_get_skipped_errors; selinux_restorecon_parallel; } LIBSELINUX_1.0; + +LIBSELINUX_3.5 { + global: + getpidprevcon; + getpidprevcon_raw; +} LIBSELINUX_3.4; diff --git a/libselinux/src/procattr.c b/libselinux/src/procattr.c index 6f4cfb82..b7a93a2b 100644 --- a/libselinux/src/procattr.c +++ b/libselinux/src/procattr.c @@ -300,3 +300,21 @@ int getpidcon(pid_t pid, char **c) } return getprocattrcon(c, pid, "current", NULL); } + +int getpidprevcon_raw(pid_t pid, char **c) +{ + if (pid <= 0) { + errno = EINVAL; + return -1; + } + return getprocattrcon_raw(c, pid, "prev", NULL); +} + +int getpidprevcon(pid_t pid, char **c) +{ + if (pid <= 0) { + errno = EINVAL; + return -1; + } + return getprocattrcon(c, pid, "prev", NULL); +} diff --git a/libselinux/utils/.gitignore b/libselinux/utils/.gitignore index 3ef34374..b19b94a8 100644 --- a/libselinux/utils/.gitignore +++ b/libselinux/utils/.gitignore @@ -9,6 +9,7 @@ getdefaultcon getenforce getfilecon getpidcon +getpidprevcon getsebool getseuser matchpathcon diff --git a/libselinux/utils/getpidprevcon.c b/libselinux/utils/getpidprevcon.c new file mode 100644 index 00000000..662ad500 --- /dev/null +++ b/libselinux/utils/getpidprevcon.c @@ -0,0 +1,33 @@ +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <selinux/selinux.h> + +int main(int argc, char **argv) +{ + pid_t pid; + char *buf; + int rc; + + if (argc != 2) { + fprintf(stderr, "usage: %s pid\n", argv[0]); + exit(1); + } + + if (sscanf(argv[1], "%d", &pid) != 1) { + fprintf(stderr, "%s: invalid pid %s\n", argv[0], argv[1]); + exit(2); + } + + rc = getpidprevcon(pid, &buf); + if (rc < 0) { + fprintf(stderr, "%s: getpidprevcon() failed: %s\n", argv[0], strerror(errno)); + exit(3); + } + + printf("%s\n", buf); + freecon(buf); + exit(EXIT_SUCCESS); +} -- 2.39.1