diff options
Diffstat (limited to 'sys-apps/man-db/files/man-db-2.8.0-seccomp_suid.patch')
-rw-r--r-- | sys-apps/man-db/files/man-db-2.8.0-seccomp_suid.patch | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/sys-apps/man-db/files/man-db-2.8.0-seccomp_suid.patch b/sys-apps/man-db/files/man-db-2.8.0-seccomp_suid.patch new file mode 100644 index 000000000000..f513ee8cca67 --- /dev/null +++ b/sys-apps/man-db/files/man-db-2.8.0-seccomp_suid.patch @@ -0,0 +1,126 @@ +From 10027a400d6a05f463f3981e1191a2f35d0cc02b Mon Sep 17 00:00:00 2001 +From: Colin Watson <cjwatson@debian.org> +Date: Wed, 7 Feb 2018 13:44:30 +0000 +Subject: [PATCH] Fix manconv under seccomp when man is setuid + +We must drop privileges before loading the sandbox. + +Reported by Lars Wendler. + +* src/manconv_client.c (manconv_pre_exec): New function. +(manconv_stdin): Move setuid hack to ... +(add_manconv): ... here, now implemented using a custom pre-exec hook. +We no longer have a fall-through if dropping privileges fails, since +that's now harder to do and wasn't really necessary in the first place. +--- + src/manconv_client.c | 80 +++++++++++++++++++++++++++++----------------------- + 1 file changed, 45 insertions(+), 35 deletions(-) + +diff --git a/src/manconv_client.c b/src/manconv_client.c +index d6e010b0..41ce4790 100644 +--- a/src/manconv_client.c ++++ b/src/manconv_client.c +@@ -56,41 +56,6 @@ static void manconv_stdin (void *data) + struct manconv_codes *codes = data; + pipeline *p; + +-#ifdef MAN_OWNER +- /* iconv_open may not work correctly in setuid processes; in GNU +- * libc, gconv modules may be linked against other gconv modules and +- * rely on RPATH $ORIGIN to load those modules from the correct +- * path, but $ORIGIN is disabled in setuid processes. It is +- * impossible to reset libc's idea of setuidness without creating a +- * whole new process image. Therefore, if the calling process is +- * setuid, we must drop privileges and execute manconv. +- * +- * If dropping privileges fails, fall through to the in-process +- * code, as in some situations it may actually manage to work. +- */ +- if (running_setuid () && !idpriv_drop ()) { +- char **from_code; +- char *sources = NULL; +- pipecmd *cmd; +- +- for (from_code = codes->from; *from_code; ++from_code) { +- sources = appendstr (sources, *from_code, NULL); +- if (*(from_code + 1)) +- sources = appendstr (sources, ":", NULL); +- } +- +- cmd = pipecmd_new_args (MANCONV, "-f", sources, +- "-t", codes->to, NULL); +- free (sources); +- +- if (quiet >= 2) +- pipecmd_arg (cmd, "-q"); +- +- pipecmd_exec (cmd); +- /* never returns */ +- } +-#endif /* MAN_OWNER */ +- + p = decompress_fdopen (dup (STDIN_FILENO)); + pipeline_start (p); + manconv (p, codes->from, codes->to); +@@ -98,6 +63,17 @@ static void manconv_stdin (void *data) + pipeline_free (p); + } + ++#ifdef MAN_OWNER ++static void manconv_pre_exec (void *data) ++{ ++ /* We must drop privileges before loading the sandbox, since our ++ * seccomp filter doesn't allow setresuid and friends. ++ */ ++ drop_privs (NULL); ++ sandbox_load (data); ++} ++#endif /* MAN_OWNER */ ++ + static void free_manconv_codes (void *data) + { + struct manconv_codes *codes = data; +@@ -139,6 +115,40 @@ void add_manconv (pipeline *p, const char *source, const char *target) + name = appendstr (name, " -t ", codes->to, NULL); + if (quiet >= 2) + name = appendstr (name, " -q", NULL); ++ ++#ifdef MAN_OWNER ++ /* iconv_open may not work correctly in setuid processes; in GNU ++ * libc, gconv modules may be linked against other gconv modules and ++ * rely on RPATH $ORIGIN to load those modules from the correct ++ * path, but $ORIGIN is disabled in setuid processes. It is ++ * impossible to reset libc's idea of setuidness without creating a ++ * whole new process image. Therefore, if the calling process is ++ * setuid, we must drop privileges and execute manconv. ++ */ ++ if (running_setuid ()) { ++ char **from_code; ++ char *sources = NULL; ++ ++ cmd = pipecmd_new_args (MANCONV, "-f", NULL); ++ for (from_code = codes->from; *from_code; ++from_code) { ++ sources = appendstr (sources, *from_code, NULL); ++ if (*(from_code + 1)) ++ sources = appendstr (sources, ":", NULL); ++ } ++ pipecmd_arg (cmd, sources); ++ free (sources); ++ pipecmd_args (cmd, "-t", codes->to, NULL); ++ if (quiet >= 2) ++ pipecmd_arg (cmd, "-q"); ++ pipecmd_pre_exec (cmd, manconv_pre_exec, sandbox_free, ++ sandbox); ++ free (name); ++ free_manconv_codes (codes); ++ pipeline_command (p, cmd); ++ return; ++ } ++#endif /* MAN_OWNER */ ++ + cmd = pipecmd_new_function (name, &manconv_stdin, &free_manconv_codes, + codes); + free (name); +-- +2.16.1 + |