[PATCH] --secontext: Implement displaying of expected context upon mismatch
Dmitry V. Levin
ldv at altlinux.org
Mon Jan 3 00:47:19 UTC 2022
On Sun, Jan 02, 2022 at 08:00:04PM +0100, Renaud Métrich wrote:
[...]
> @@ -97,7 +155,33 @@ selinux_getfdcon(pid_t pid, int fd, char **result)
> xsprintf(linkpath, "/proc/%u/fd/%u", proc_pid, fd);
>
> char *secontext;
> - return getcontext(getfilecon(linkpath, &secontext), &secontext, result);
> + int rc = getcontext(getfilecon(linkpath, &secontext), &secontext, result);
> + if (rc == -1 || !is_number_in_set(SECONTEXT_MISMATCH, secontext_set))
> + return rc;
> +
> + /*
> + * We need to resolve the path, because selabel_lookup() doesn't
> + * resolve anything. Using readlink() is sufficient here.
> + */
> +
> + char buf[PATH_MAX];
> + ssize_t n = readlink(linkpath, buf, sizeof(buf));
> + if ((size_t) n >= sizeof(buf))
> + return 0;
> + buf[n] = '\0';
> +
> + char *expected;
> + if (get_expected_filecontext(buf, &expected) == -1)
> + return 0;
> + if (strcmp(expected, *result) == 0) {
> + free(expected);
> + return 0;
> + }
> + char *final_result = xasprintf("%s!!%s", *result, expected);
> + free(expected);
> + free(*result);
> + *result = final_result;
> + return 0;
> }
>
> /*
> @@ -108,29 +192,56 @@ selinux_getfdcon(pid_t pid, int fd, char **result)
> int
> selinux_getfilecon(struct tcb *tcp, const char *path, char **result)
> {
> - if (!selinux_context)
> + if (number_set_array_is_empty(secontext_set, 0))
> return -1;
>
> int proc_pid = get_proc_pid(tcp->pid);
> if (!proc_pid)
> return -1;
>
> - int ret = -1;
> + int rc = -1;
> char fname[PATH_MAX];
>
> if (path[0] == '/')
> - ret = snprintf(fname, sizeof(fname), "/proc/%u/root%s",
> + rc = snprintf(fname, sizeof(fname), "/proc/%u/root%s",
> proc_pid, path);
> else if (tcp->last_dirfd == AT_FDCWD)
> - ret = snprintf(fname, sizeof(fname), "/proc/%u/cwd/%s",
> + rc = snprintf(fname, sizeof(fname), "/proc/%u/cwd/%s",
> proc_pid, path);
> else if (tcp->last_dirfd >= 0 )
> - ret = snprintf(fname, sizeof(fname), "/proc/%u/fd/%u/%s",
> + rc = snprintf(fname, sizeof(fname), "/proc/%u/fd/%u/%s",
> proc_pid, tcp->last_dirfd, path);
>
> - if ((unsigned int) ret >= sizeof(fname))
> + if ((unsigned int) rc >= sizeof(fname))
> return -1;
>
> char *secontext;
> - return getcontext(getfilecon(fname, &secontext), &secontext, result);
> + rc = getcontext(getfilecon(fname, &secontext), &secontext, result);
> + if (rc == -1 || !is_number_in_set(SECONTEXT_MISMATCH, secontext_set))
> + return rc;
> +
> + /*
> + * We need to fully resolve the path, because selabel_lookup() doesn't
> + * resolve anything. Using realpath() is the only solution here to make
> + * sure the path is canonicalized.
> + */
> +
> + char *resolved = realpath(fname, NULL);
> + if (!resolved)
> + return -1;
Is it correct to return -1 here, that is, to avoid printing context?
For comparison, selinux_getfdcon returns 0 when readlink fails.
[...]
> char *
> -secontext_full_file(const char *filename)
> +secontext_full_file(const char *filename, bool mismatch)
> {
> - return FORMAT_SPACE_BEFORE(raw_secontext_full_file(filename));
> + char *context = raw_secontext_full_file(filename);
> + if (mismatch) {
> + char *expected = raw_expected_secontext_full_file(filename);
> + if (expected && strcmp(context, expected) != 0) {
What if context == NULL here?
--
ldv
More information about the Strace-devel
mailing list