summaryrefslogtreecommitdiff
path: root/src/strace.c
diff options
context:
space:
mode:
authorRenaud Métrich <rmetrich@redhat.com>2021-10-05 08:36:22 +0200
committerDmitry V. Levin <ldv@strace.io>2022-01-04 08:00:00 +0000
commitca1aa96f2b00a0dda41506c8eb15bed265066e3a (patch)
tree6f70a4fead68e89e302e6f7175872988cb430d30 /src/strace.c
parent3b3617b65d54b60c6d48aa4fb5f339587ca9871f (diff)
downloadstrace-ca1aa96f2b00a0dda41506c8eb15bed265066e3a.tar.gz
Implement displaying of expected context upon mismatch
New option to --secontext=... (also available as -e secontext=...) - mismatch: print expected context on mismatch When using 'mismatch', an additional check is made on the context by reading the context database and comparing the output after stripping the unwanted part (e.g. stripping nothing in 'full' mode, keeping the type only in default mode): - if it differs, prints the expected context after printing '!!' - if not, don't print anything Example with /home/rmetrich/GIT/strace/autom4te.cache/output.3 file: ---- $ matchpathcon /home/rmetrich/GIT/strace/autom4te.cache/output.3 /home/rmetrich/GIT/strace/autom4te.cache/output.3 unconfined_u:object_r:user_home_t:s0 $ ls -Z /home/rmetrich/GIT/strace/autom4te.cache/output.3 system_u:object_r:user_home_t:s0 /home/rmetrich/GIT/strace/autom4te.cache/output.3 ---- From above, we see the user part differs ('unconfined_u' vs 'system_u') Output in '!full' mode (no diff found on type): ---- $ strace --secontext=mismatch -e statx stat /home/rmetrich/GIT/strace/autom4te.cache/output.3 ... statx(AT_FDCWD, "/home/rmetrich/GIT/strace/autom4te.cache/output.3" [user_home_t], ... ---- Output in 'full' mode (diff found on user): ---- ... statx(AT_FDCWD, "/home/rmetrich/GIT/strace/autom4te.cache/output.3" [system_u:object_r:user_home_t:s0!!unconfined_u:object_r:user_home_t:s0], ... ---- * NEWS: Mention this change. * doc/strace.1.in: Document it. * m4/st_selinux.m4 (st_SELINUX): Check for selabel_open and selabel_lookup. * src/filter_qualify.c [ENABLE_SECONTEXT]: Include "secontext.h". [ENABLE_SECONTEXT] (secontext_set): New variable. [ENABLE_SECONTEXT] (secontextstr_to_uint, qualify_secontext): New functions. (qual_options) [ENABLE_SECONTEXT]: Add "secontext". * src/secontext.c: Include <sys/stat.h>, <unistd.h>, <selinux/label.h>, "largefile_wrappers.h", "number_set.h", and "xmalloc.h". (selinux_context, selinux_context_full): Remove. (getcontext): Use is_number_in_set instead of selinux_context_full. (selinux_getpidcon): Use is_number_in_set instead of selinux_context. (get_expected_filecontext): New function. (selinux_getfdcon, selinux_getfilecon): Use it to print context mismatch if SECONTEXT_MISMATCH is set in secontext_set. * src/secontext.h (selinux_context, selinux_context_full): Remove. (secontext_bits): New enum. (secontext_set, qualify_secontext, selinux_set_format): New declarations. * src/strace.c (SECONTEXT_E_QUAL): New macro. (usage): Use it, describe --secontext. (init) [ENABLE_SECONTEXT]: Call qualify_secontext, rename GETOPT_SECONTEXT to GETOPT_QUAL_SECONTEXT, use is_number_in_set instead of selinux_context. (init) [ENABLE_SECONTEXT] (secontext_qual): New variable. (init) [ENABLE_SECONTEXT] <GETOPT_QUAL_SECONTEXT>: Use it. * tests/.gitignore: Add *--secontext_full_mismatch, *--secontext_full_mismatch.c, *--secontext_mismatch, and *--secontext_mismatch.c. * tests/gen_secontext.sh: Generate *--secontext_full_mismatch.c and *--secontext_mismatch.c. * tests/gen_tests.in (access--secontext_full_mismatch, access--secontext_mismatch, chmod--secontext_full_mismatch, chmod--secontext_mismatch, execve--secontext_full_mismatch, execve--secontext_mismatch, execveat--secontext_full_mismatch, execveat--secontext_mismatch, faccessat--secontext_full_mismatch, faccessat--secontext_mismatch, faccessat-y--secontext_full_mismatch, faccessat-y--secontext_mismatch, fanotify_mark--secontext_full_mismatch, fanotify_mark--secontext_mismatch, fchmod--secontext_full_mismatch, fchmod--secontext_mismatch, fchmod-y--secontext_full_mismatch, fchmod-y--secontext_mismatch, fchmodat--secontext_full_mismatch, fchmodat--secontext_mismatch, fchownat--secontext_full_mismatch, fchownat--secontext_mismatch, file_handle--secontext_full_mismatch, file_handle--secontext_mismatch, linkat--secontext_full_mismatch, linkat--secontext_mismatch, open--secontext_full_mismatch, open--secontext_mismatch, openat--secontext_full_mismatch, openat--secontext_mismatch): New tests. * tests/linkat.c: Include <string.h>. (main) [PRINT_SECONTEXT_MISMATCH]: Check context mismatch. * tests/options-syntax.test: Check --secontext and -e secontext syntax. * tests/secontext.h (secontext_field): New enum. (secontext_full_file, secontext_short_file): Add "mismatch" argument. (update_secontext_type): Rename to update_secontext_field, add "field" argument. (SECONTEXT_FILE): Conditionalize "mismatch" argument passed to secontext_full_file and secontext_short_file on PRINT_SECONTEXT_MISMATCH. * tests/secontext.c: Include <sys/stat.h> and <selinux/label.h>. (get_type_from_context, raw_expected_secontext_full_file, raw_expected_secontext_short_file): New functions. (raw_secontext_short_file, raw_secontext_short_pid): Use get_type_from_context. (secontext_full_file): Add "mismatch" argument, use raw_expected_secontext_full_file if mismatch is enabled. (secontext_short_file): Add "mismatch" argument, use raw_expected_secontext_short_file if mismatch is enabled. (update_secontext_type): Rename to update_secontext_field, add "field" argument. Co-authored-by: Dmitry V. Levin <ldv@strace.io>
Diffstat (limited to 'src/strace.c')
-rw-r--r--src/strace.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/src/strace.c b/src/strace.c
index 676fcb85b..7370275e1 100644
--- a/src/strace.c
+++ b/src/strace.c
@@ -264,9 +264,11 @@ usage(void)
# define K_OPT ""
#endif
#ifdef ENABLE_SECONTEXT
-# define SECONTEXT_OPT "[--secontext[=full]]\n"
+# define SECONTEXT_OPT " [--secontext[=FORMAT]]\n"
+# define SECONTEXT_E_QUAL ", secontext"
#else
# define SECONTEXT_OPT ""
+# define SECONTEXT_E_QUAL ""
#endif
printf("\
@@ -282,7 +284,7 @@ Usage: strace [-ACdffhi" K_OPT "qqrtttTvVwxxyyzZ] [-I N] [-b execve] [-e EXPR]..
General:\n\
-e EXPR a qualifying expression: OPTION=[!]all or OPTION=[!]VAL1[,VAL2]...\n\
options: trace, abbrev, verbose, raw, signal, read, write, fault,\n\
- inject, status, quiet, kvm, decode-fds\n\
+ inject, status, quiet, kvm, decode-fds" SECONTEXT_E_QUAL "\n\
\n\
Startup:\n\
-E VAR=VAL, --env=VAR=VAL\n\
@@ -358,6 +360,19 @@ Output format:\n\
path (file path),\n\
pidfd (associated PID for pidfds),\n\
socket (protocol-specific information for socket descriptors)\n\
+"
+#ifdef ENABLE_SECONTEXT
+"\
+ -e secontext=FORMAT, --secontext[=FORMAT]\n\
+ print SELinux contexts in square brackets\n\
+ formats: comma-separated list of all, full, mismatch, none\n\
+ all: equivalent to full,mismatch\n\
+ full: print the full context instead of the type only\n\
+ mismatch: print expected context when actual is not matching\n\
+ none: equivalent to not specifying the option at all\n\
+"
+#endif
+"\
-i, --instruction-pointer\n\
print instruction pointer at time of syscall\n\
"
@@ -420,14 +435,6 @@ Output format:\n\
print PIDs in strace's namespace, too\n\
-Y, --decode-pids=comm\n\
print command names associated with PIDs\n\
-"
-#ifdef ENABLE_SECONTEXT
-"\
- --secontext[=full]\n\
- print SELinux contexts (type only unless 'full' is specified)\n\
-"
-#endif
-"\
\n\
Statistics:\n\
-c, --summary-only\n\
@@ -2066,6 +2073,9 @@ init(int argc, char *argv[])
static const char tflag_str[] = "format:time";
static const char ttflag_str[] = "precision:us,format:time";
static const char tttflag_str[] = "format:unix,precision:us";
+#ifdef ENABLE_SECONTEXT
+ static const char secontext_qual[] = "!full,mismatch";
+#endif
int c, i;
int optF = 0, zflags = 0;
@@ -2129,6 +2139,9 @@ init(int argc, char *argv[])
qualify_quiet("none");
qualify_decode_fd("none");
qualify_signals("all");
+#ifdef ENABLE_SECONTEXT
+ qualify_secontext("none");
+#endif
static const char optstring[] =
"+a:Ab:cCdDe:E:fFhiI:kno:O:p:P:qrs:S:tTu:U:vVwxX:yYzZ";
@@ -2141,9 +2154,6 @@ init(int argc, char *argv[])
GETOPT_OUTPUT_SEPARATELY,
GETOPT_TS,
GETOPT_PIDNS_TRANSLATION,
-#ifdef ENABLE_SECONTEXT
- GETOPT_SECONTEXT,
-#endif
GETOPT_QUAL_TRACE,
GETOPT_QUAL_ABBREV,
@@ -2159,6 +2169,9 @@ init(int argc, char *argv[])
GETOPT_QUAL_QUIET,
GETOPT_QUAL_DECODE_FD,
GETOPT_QUAL_DECODE_PID,
+#ifdef ENABLE_SECONTEXT
+ GETOPT_QUAL_SECONTEXT,
+#endif
};
static const struct option longopts[] = {
{ "columns", required_argument, 0, 'a' },
@@ -2201,9 +2214,6 @@ init(int argc, char *argv[])
{ "failed-only", no_argument, 0, 'Z' },
{ "failing-only", no_argument, 0, 'Z' },
{ "seccomp-bpf", no_argument, 0, GETOPT_SECCOMP },
-#ifdef ENABLE_SECONTEXT
- { "secontext", optional_argument, 0, GETOPT_SECONTEXT },
-#endif
{ "trace", required_argument, 0, GETOPT_QUAL_TRACE },
{ "abbrev", required_argument, 0, GETOPT_QUAL_ABBREV },
@@ -2221,6 +2231,9 @@ init(int argc, char *argv[])
{ "silence", optional_argument, 0, GETOPT_QUAL_QUIET },
{ "decode-fds", optional_argument, 0, GETOPT_QUAL_DECODE_FD },
{ "decode-pids",required_argument, 0, GETOPT_QUAL_DECODE_PID },
+#ifdef ENABLE_SECONTEXT
+ { "secontext", optional_argument, 0, GETOPT_QUAL_SECONTEXT },
+#endif
{ 0, 0, 0, 0 }
};
@@ -2437,14 +2450,8 @@ init(int argc, char *argv[])
seccomp_filtering = true;
break;
#ifdef ENABLE_SECONTEXT
- case GETOPT_SECONTEXT:
- selinux_context = true;
- if (optarg) {
- if (!strcmp(optarg, "full"))
- selinux_context_full = true;
- else
- error_opt_arg(c, lopt, optarg);
- }
+ case GETOPT_QUAL_SECONTEXT:
+ qualify_secontext(optarg ? optarg : secontext_qual);
break;
#endif
case GETOPT_QUAL_TRACE:
@@ -2646,7 +2653,7 @@ init(int argc, char *argv[])
error_msg("-y/--decode-fds has no effect "
"with -c/--summary-only");
#ifdef ENABLE_SECONTEXT
- if (selinux_context)
+ if (!number_set_array_is_empty(secontext_set, 0))
error_msg("--secontext has no effect with "
"-c/--summary-only");
#endif