commit:     66af02c4670b0c8547c27810c1e2ddbe60c5788c
Author:     Lars Wendler <polynomial-c <AT> gentoo <DOT> org>
AuthorDate: Thu Feb  8 07:53:09 2018 +0000
Commit:     Lars Wendler <polynomial-c <AT> gentoo <DOT> org>
CommitDate: Thu Feb  8 07:59:22 2018 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=66af02c4

sys-apps/man-db: Revbump adding seccomp support. Removed old.

Package-Manager: Portage-2.3.24, Repoman-2.3.6

 .../files/man-db-2.8.0-libseccomp_automagic.patch  |  99 +++++++++++++---
 .../files/man-db-2.8.0-refactor_drop_privs.patch   | 120 ++++++++++++++++++++
 .../man-db/files/man-db-2.8.0-seccomp_suid.patch   | 126 +++++++++++++++++++++
 ...{man-db-2.8.0.ebuild => man-db-2.8.0-r1.ebuild} |  19 ++--
 4 files changed, 335 insertions(+), 29 deletions(-)

diff --git a/sys-apps/man-db/files/man-db-2.8.0-libseccomp_automagic.patch 
b/sys-apps/man-db/files/man-db-2.8.0-libseccomp_automagic.patch
index 333bc5fe295..cf9c1257317 100644
--- a/sys-apps/man-db/files/man-db-2.8.0-libseccomp_automagic.patch
+++ b/sys-apps/man-db/files/man-db-2.8.0-libseccomp_automagic.patch
@@ -1,42 +1,107 @@
-From c693c0d6c41e777def51984035710779697d1989 Mon Sep 17 00:00:00 2001
+From 3d4ab15670079aa8e898f80a650b3be941230486 Mon Sep 17 00:00:00 2001
 From: Lars Wendler <polynomia...@gentoo.org>
-Date: Tue, 6 Feb 2018 14:41:22 +0100
-Subject: [PATCH] Change libseccomp logic to not be automagic only.
+Date: Tue, 6 Feb 2018 15:30:21 +0100
+Subject: [PATCH] Change libseccomp logic to not be automagic only
 
-Introduce --with-libseccomp configure option so that users can disable
-seccomp even if libseccomp is available on the system.
-The default is unchanged to before this patch. If no --with(out)-libseccomp
-has been given on command line, the macro looks for presence of libseccomp
-and uses that if found.
+Introduce --without-libseccomp configure option so that users can
+disable seccomp even if libseccomp is available on the system.
+
+The default is unchanged from before this patch.  If no
+--with(out)-libseccomp has been given on the command line, the macro
+looks for presence of libseccomp and uses that if found.
+
+* m4/man-libseccomp.m4: Guard pkg-config test with a command-line
+option.
 ---
- m4/man-libseccomp.m4 | 19 ++++++++++++++-----
- 1 file changed, 14 insertions(+), 5 deletions(-)
 
+diff --git a/configure b/configure
+index 3f949306..8eaca64e 100755
+--- a/configure
++++ b/configure
+@@ -1718,6 +1718,7 @@ with_included_regex
+ enable_nls
+ with_libiconv_prefix
+ with_libintl_prefix
++with_libseccomp
+ '
+       ac_precious_vars='build_alias
+ host_alias
+@@ -2459,6 +2460,7 @@ Optional Packages:
+   --without-libiconv-prefix     don't search for libiconv in includedir and 
libdir
+   --with-libintl-prefix[=DIR]  search for libintl in DIR/include and DIR/lib
+   --without-libintl-prefix     don't search for libintl in includedir and 
libdir
++  --without-libseccomp    do not confine subprocesses using seccomp
+ 
+ Some influential environment variables:
+   CC          C compiler command
+@@ -47295,6 +47297,15 @@ fi
+ 
+ # Check for libseccomp library.
+ 
++# Check whether --with-libseccomp was given.
++if test "${with_libseccomp+set}" = set; then :
++  withval=$with_libseccomp;
++else
++  with_libseccomp=check
++fi
++
++      if test "x$with_libseccomp" != "xno"; then
++
+ pkg_failed=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libseccomp" >&5
+ $as_echo_n "checking for libseccomp... " >&6; }
+@@ -47353,11 +47364,15 @@ fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$libseccomp_PKG_ERRORS" >&5
+ 
+-      :
++      if test "x$with_libseccomp" = "xyes"; then
++                              as_fn_error $? "--with-libseccomp given but 
cannot find libseccomp" "$LINENO" 5
++                       fi
+ elif test $pkg_failed = untried; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+-      :
++      if test "x$with_libseccomp" = "xyes"; then
++                              as_fn_error $? "--with-libseccomp given but 
cannot find libseccomp" "$LINENO" 5
++                       fi
+ else
+       libseccomp_CFLAGS=$pkg_cv_libseccomp_CFLAGS
+       libseccomp_LIBS=$pkg_cv_libseccomp_LIBS
+@@ -47367,6 +47382,7 @@ $as_echo "yes" >&6; }
+ $as_echo "#define HAVE_LIBSECCOMP 1" >>confdefs.h
+ 
+ fi
++      fi
+ 
+ 
+ { $as_echo "$as_me:${as_lineno-$LINENO}: default CC = \"$CC\"" >&5
 diff --git a/m4/man-libseccomp.m4 b/m4/man-libseccomp.m4
-index a9377317..17a52f72 100644
+index a9377317..c90e3aa4 100644
 --- a/m4/man-libseccomp.m4
 +++ b/m4/man-libseccomp.m4
 @@ -1,9 +1,18 @@
- # man-libseccomp.m4 serial 1
+-# man-libseccomp.m4 serial 1
++# man-libseccomp.m4 serial 2
  dnl MAN_LIBSECCOMP
 -dnl Check for the libseccomp library.
-+dnl Add a --with-libseccomp option.
++dnl Add a --without-libseccomp option; check for the libseccomp library.
  AC_DEFUN([MAN_LIBSECCOMP],
 -[PKG_CHECK_MODULES([libseccomp], [libseccomp],
 -      [AC_DEFINE([HAVE_LIBSECCOMP], [1],
 -              [Define to 1 if you have the `libseccomp' library.])],
 -      [:])
 +      [AC_ARG_WITH([libseccomp],
-+              [AS_HELP_STRING([--with-libseccomp],
-+                             [use libseccomp to do most subprocessing])],
++              [AS_HELP_STRING([--without-libseccomp],
++                              [do not confine subprocesses using seccomp])],
 +              [],
 +              [with_libseccomp=check])
 +      if test "x$with_libseccomp" != "xno"; then
 +              PKG_CHECK_MODULES([libseccomp], [libseccomp],
 +                      [AC_DEFINE([HAVE_LIBSECCOMP], [1],
 +                              [Define to 1 if you have the `libseccomp' 
library.])],
-+                      [if test "xyes" = "x$with_libseccomp"; then
-+                              AC_MSG_ERROR(--with-libseccomp given but cannot 
find libseccomp)
++                      [if test "x$with_libseccomp" = "xyes"; then
++                              AC_MSG_ERROR([--with-libseccomp given but 
cannot find libseccomp])
 +                       fi])
 +      fi
  ]) # MAN_LIBSECCOMP

diff --git a/sys-apps/man-db/files/man-db-2.8.0-refactor_drop_privs.patch 
b/sys-apps/man-db/files/man-db-2.8.0-refactor_drop_privs.patch
new file mode 100644
index 00000000000..87db57afb9e
--- /dev/null
+++ b/sys-apps/man-db/files/man-db-2.8.0-refactor_drop_privs.patch
@@ -0,0 +1,120 @@
+From 24624eaf853158856b8fd0a6f78c873475a16686 Mon Sep 17 00:00:00 2001
+From: Colin Watson <cjwat...@debian.org>
+Date: Wed, 7 Feb 2018 12:23:15 +0000
+Subject: Refactor do_system_drop_privs
+
+Now that we have pipecmd_pre_exec, this can be simplified quite a bit.
+
+* lib/security.c (drop_privs): New function.
+(do_system_drop_privs_child, do_system_drop_privs): Remove.
+* lib/security.h (drop_privs): Add prototype.
+(do_system_drop_privs): Remove prototype.
+* src/man.c (make_browser): Add drop_privs pre-exec hook to browser
+command.
+(format_display): Call browser using pipeline_run rather than
+do_system_drop_privs, since it now has a pre-exec hook to drop
+privileges.
+---
+ lib/security.c | 37 +++----------------------------------
+ lib/security.h |  2 +-
+ src/man.c      |  7 +++++--
+ 3 files changed, 9 insertions(+), 37 deletions(-)
+
+diff --git a/lib/security.c b/lib/security.c
+index 6e84de8..c9b365d 100644
+--- a/lib/security.c
++++ b/lib/security.c
+@@ -158,42 +158,11 @@ void regain_effective_privs (void)
+ #endif /* MAN_OWNER */
+ }
+ 
+-#ifdef MAN_OWNER
+-void do_system_drop_privs_child (void *data)
++/* Pipeline command pre-exec hook to permanently drop privileges. */
++void drop_privs (void *data ATTRIBUTE_UNUSED)
+ {
+-      pipeline *p = data;
+-
++#ifdef MAN_OWNER
+       if (idpriv_drop ())
+               gripe_set_euid ();
+-      exit (pipeline_run (p));
+-}
+-#endif /* MAN_OWNER */
+-
+-/* The safest way to execute a pipeline with no effective privileges is to
+- * fork, permanently drop privileges in the child, run the pipeline from the
+- * child, and wait for it to die.
+- *
+- * It is possible to use saved IDs to avoid the fork, since effective IDs
+- * are copied to saved IDs on execve; we used to do this.  However, forking
+- * is not expensive enough to justify the extra code.
+- *
+- * Note that this frees the supplied pipeline.
+- */
+-int do_system_drop_privs (pipeline *p)
+-{
+-#ifdef MAN_OWNER
+-      pipecmd *child_cmd;
+-      pipeline *child;
+-      int status;
+-
+-      child_cmd = pipecmd_new_function ("unprivileged child",
+-                                        do_system_drop_privs_child, NULL, p);
+-      child = pipeline_new_commands (child_cmd, NULL);
+-      status = pipeline_run (child);
+-
+-      pipeline_free (p);
+-      return status;
+-#else  /* !MAN_OWNER */
+-      return pipeline_run (p);
+ #endif /* MAN_OWNER */
+ }
+diff --git a/lib/security.h b/lib/security.h
+index 7545502..851127d 100644
+--- a/lib/security.h
++++ b/lib/security.h
+@@ -27,7 +27,7 @@
+ /* security.c */
+ extern void drop_effective_privs (void);
+ extern void regain_effective_privs (void);
+-extern int do_system_drop_privs (struct pipeline *p);
++extern void drop_privs (void *data);
+ extern void init_security (void);
+ extern int running_setuid (void);
+ extern struct passwd *get_man_owner (void);
+diff --git a/src/man.c b/src/man.c
+index 959d6cc..ff7ebc7 100644
+--- a/src/man.c
++++ b/src/man.c
+@@ -1481,6 +1481,7 @@ static pipeline *make_roff_command (const char *dir, 
const char *file,
+ static pipeline *make_browser (const char *pattern, const char *file)
+ {
+       pipeline *p;
++      pipecmd *cmd;
+       char *browser = xmalloc (1);
+       int found_percent_s = 0;
+       char *percent;
+@@ -1526,7 +1527,9 @@ static pipeline *make_browser (const char *pattern, 
const char *file)
+               free (esc_file);
+       }
+ 
+-      p = pipeline_new_command_args ("/bin/sh", "-c", browser, NULL);
++      cmd = pipecmd_new_args ("/bin/sh", "-c", browser, NULL);
++      pipecmd_pre_exec (cmd, drop_privs, NULL, NULL);
++      p = pipeline_new_commands (cmd, NULL);
+       pipeline_ignore_signals (p, 1);
+       free (browser);
+ 
+@@ -2021,7 +2024,7 @@ static void format_display (pipeline *decomp,
+                       pipeline *browser;
+                       debug ("Trying browser: %s\n", candidate);
+                       browser = make_browser (candidate, htmlfile);
+-                      disp_status = do_system_drop_privs (browser);
++                      disp_status = pipeline_run (browser);
+                       if (!disp_status)
+                               break;
+               }
+-- 
+cgit v1.0-41-gc330
+

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 00000000000..f513ee8cca6
--- /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 <cjwat...@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
+

diff --git a/sys-apps/man-db/man-db-2.8.0.ebuild 
b/sys-apps/man-db/man-db-2.8.0-r1.ebuild
similarity index 87%
rename from sys-apps/man-db/man-db-2.8.0.ebuild
rename to sys-apps/man-db/man-db-2.8.0-r1.ebuild
index 10c1e80763d..1ff3ca11d5c 100644
--- a/sys-apps/man-db/man-db-2.8.0.ebuild
+++ b/sys-apps/man-db/man-db-2.8.0-r1.ebuild
@@ -3,7 +3,7 @@
 
 EAPI=6
 
-inherit autotools ltprune user versionator
+inherit ltprune user versionator
 
 DESCRIPTION="a man replacement that utilizes berkdb instead of flat files"
 HOMEPAGE="http://www.nongnu.org/man-db/";
@@ -12,7 +12,7 @@ SRC_URI="mirror://nongnu/${PN}/${P}.tar.xz"
 LICENSE="GPL-3"
 SLOT="0"
 KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 
~sh ~sparc ~x86 ~amd64-linux ~arm-linux ~x86-linux"
-IUSE="berkdb +gdbm +manpager nls selinux static-libs zlib"
+IUSE="berkdb +gdbm +manpager nls seccomp selinux static-libs zlib"
 
 CDEPEND="
        !sys-apps/man
@@ -21,6 +21,7 @@ CDEPEND="
        berkdb? ( sys-libs/db:= )
        gdbm? ( sys-libs/gdbm:= )
        !berkdb? ( !gdbm? ( sys-libs/gdbm:= ) )
+       seccomp? ( sys-libs/libseccomp )
        zlib? ( sys-libs/zlib )
 "
 DEPEND="
@@ -39,7 +40,9 @@ RDEPEND="
 PDEPEND="manpager? ( app-text/manpager )"
 
 PATCHES=(
-       "${FILESDIR}/${PN}-2.8.0-libseccomp_automagic.patch"
+       "${FILESDIR}/${P}-refactor_drop_privs.patch"
+       "${FILESDIR}/${P}-seccomp_suid.patch"
+       "${FILESDIR}/${P}-libseccomp_automagic.patch"
 )
 
 pkg_setup() {
@@ -52,11 +55,6 @@ pkg_setup() {
        fi
 }
 
-src_prepare() {
-       default
-       eautoreconf
-}
-
 src_configure() {
        export ac_cv_lib_z_gzopen=$(usex zlib)
        local myeconfargs=(
@@ -67,10 +65,7 @@ src_configure() {
                --with-sections="1 1p 8 2 3 3p 4 5 6 7 9 0p tcl n l p o 1x 2x 
3x 4x 5x 6x 7x 8x"
                $(use_enable nls)
                $(use_enable static-libs static)
-               # fails to show any man page with this error message:
-               # man: /usr/libexec/man-db/manconv -f UTF-8:ISO-8859-1 -t 
UTF-8//IGNORE: Bad system call
-               # This will be made optional or hard enabled once the issue has 
been resolved.
-               --without-libseccomp
+               $(use_with seccomp libseccomp)
                --with-db=$(usex gdbm gdbm $(usex berkdb db gdbm))
        )
        econf "${myeconfargs[@]}"

Reply via email to