From 84fdb2e19779dcdebd517d5fd9e88d935e21e429 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Dec 06 2016 09:43:55 +0000 Subject: import sudo-1.8.6p7-21.el7_3 --- diff --git a/SOURCES/sudo-1.8.6p7-noexec-update.patch b/SOURCES/sudo-1.8.6p7-noexec-update.patch new file mode 100644 index 0000000..4005794 --- /dev/null +++ b/SOURCES/sudo-1.8.6p7-noexec-update.patch @@ -0,0 +1,422 @@ +diff --git a/config.h.in b/config.h.in +index 106af3a..30c3928 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -87,6 +87,10 @@ + don't. */ + #undef HAVE_DECL_H_ERRNO + ++/* Define to 1 if you have the declaration of `SECCOMP_SET_MODE_FILTER', and ++ to 0 if you don't. */ ++#undef HAVE_DECL_SECCOMP_SET_MODE_FILTER ++ + /* Define to 1 if you have the declaration of `sys_sigabbrev', and to 0 if you + don't. */ + #undef HAVE_DECL_SYS_SIGABBREV +@@ -134,9 +138,21 @@ + /* Define to 1 if the compiler supports the __visibility__ attribute. */ + #undef HAVE_DSO_VISIBILITY + ++/* Define to 1 if you have the `exect' function. */ ++#undef HAVE_EXECT ++ ++/* Define to 1 if you have the `execvp' function. */ ++#undef HAVE_EXECVP ++ ++/* Define to 1 if you have the `execvpe' function. */ ++#undef HAVE_EXECVPE ++ + /* Define to 1 if your system has the F_CLOSEM fcntl. */ + #undef HAVE_FCNTL_CLOSEM + ++/* Define to 1 if you have the `fexecve' function. */ ++#undef HAVE_FEXECVE ++ + /* Define to 1 if you have the `fgetln' function. */ + #undef HAVE_FGETLN + +@@ -421,6 +437,12 @@ + /* Define to 1 if you have the `posix_openpt' function. */ + #undef HAVE_POSIX_OPENPT + ++/* Define to 1 if you have the `posix_spawn' function. */ ++#undef HAVE_POSIX_SPAWN ++ ++/* Define to 1 if you have the `posix_spawnp' function. */ ++#undef HAVE_POSIX_SPAWNP ++ + /* Define to 1 if you have the `priv_set' function. */ + #undef HAVE_PRIV_SET + +@@ -703,6 +725,12 @@ + /* Define to 1 if you have the `vsnprintf' function. */ + #undef HAVE_VSNPRINTF + ++/* Define to 1 if you have the `wordexp' function. */ ++#undef HAVE_WORDEXP ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_WORDEXP_H ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_ZLIB_H + +diff --git a/configure.in b/configure.in +index 06b4722..945284e 100644 +--- a/configure.in ++++ b/configure.in +@@ -1824,6 +1824,14 @@ case "$host" in + shadow_funcs="getspnam" + shadow_libs_optional="-lshadow" + test -z "$with_pam" && AUTH_EXCL_DEF="PAM" ++ # Check for SECCOMP_SET_MODE_FILTER in linux/seccomp.h ++ AC_CHECK_DECLS([SECCOMP_SET_MODE_FILTER], [], [], [ ++#include ++#include ++#include ++#include ++#include ++ ]) + ;; + *-convex-bsd*) + OSDEFS="${OSDEFS} -D_CONVEX_SOURCE" +@@ -2091,7 +2099,7 @@ AC_HEADER_DIRENT + AC_HEADER_TIME + AC_HEADER_STDBOOL + AC_HEADER_MAJOR +-AC_CHECK_HEADERS(malloc.h netgroup.h paths.h spawn.h utime.h utmpx.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h) ++AC_CHECK_HEADERS(malloc.h netgroup.h paths.h spawn.h utime.h utmpx.h wordexp.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h) + AC_CHECK_HEADERS([procfs.h] [sys/procfs.h], [AC_CHECK_MEMBERS(struct psinfo.pr_ttydev, [AC_CHECK_FUNCS(_ttyname_dev)], [], [AC_INCLUDES_DEFAULT + #ifdef HAVE_PROCFS_H + #include +@@ -2226,7 +2234,8 @@ dnl + AC_FUNC_GETGROUPS + AC_CHECK_FUNCS(glob strrchr sysconf tzset strftime setenv \ + regcomp setlocale nl_langinfo mbr_check_membership \ +- setrlimit64) ++ setrlimit64 \ ++ wordexp exect execvp execvpe fexecve posix_spawn posix_spawnp) + AC_REPLACE_FUNCS(getgrouplist) + AC_CHECK_FUNCS(getline, [], [ + AC_LIBOBJ(getline) +diff --git a/include/missing.h b/include/missing.h +index fda151b..cac8088 100644 +--- a/include/missing.h ++++ b/include/missing.h +@@ -198,6 +198,13 @@ typedef struct sigaction sigaction_t; + #endif + + /* ++ * The nitems macro may be defined in sys/param.h ++ */ ++#ifndef nitems ++# define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) ++#endif ++ ++/* + * If dirfd() does not exists, hopefully dd_fd does. + */ + #if !defined(HAVE_DIRFD) && defined(HAVE_DD_FD) +diff --git a/src/Makefile.in b/src/Makefile.in +index 918cf04..079aa3e 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -109,7 +109,7 @@ sudo: $(OBJS) $(LT_LIBS) + $(LIBTOOL) --mode=link $(CC) -o $@ $(OBJS) $(LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) + + libsudo_noexec.la: sudo_noexec.lo +- $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir) ++ $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) @LIBDL@ -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir) + + sesh: sesh.o error.o exec_common.o @LIBINTL@ $(LT_LIBS) + $(LIBTOOL) --mode=link $(CC) -o $@ sesh.o error.o exec_common.o $(LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) @LIBINTL@ $(LIBS) +diff --git a/src/sudo_noexec.c b/src/sudo_noexec.c +index 2872501..f04b277 100644 +--- a/src/sudo_noexec.c ++++ b/src/sudo_noexec.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2004-2005, 2010-2011 Todd C. Miller ++ * Copyright (c) 2004-2005, 2010-2016 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +@@ -18,20 +18,64 @@ + + #include + ++#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER ++# include ++# include ++# include ++# include ++#endif ++ + #include + #include ++#include ++#include ++#include + #ifdef HAVE_SPAWN_H + #include + #endif ++#ifdef HAVE_STRING_H ++# include ++#endif /* HAVE_STRING_H */ ++#ifdef HAVE_STRINGS_H ++# include ++#endif /* HAVE_STRINGS_H */ ++#ifdef HAVE_WORDEXP_H ++#include ++#endif ++#if defined(HAVE_SHL_LOAD) ++# include ++#elif defined(HAVE_DLOPEN) ++# include ++#endif + + #include "missing.h" ++#include "pathnames.h" + ++#ifdef HAVE___INTERPOSE + /* +- * Dummy versions of the execve() family of syscalls. We don't need +- * to stub out all of them, just the ones that correspond to actual +- * system calls (which varies by OS). Note that it is still possible +- * to access the real syscalls via the syscall() interface but very +- * few programs actually do that. ++ * Mac OS X 10.4 and above has support for library symbol interposition. ++ * There is a good explanation of this in the Mac OS X Internals book. ++ */ ++typedef struct interpose_s { ++ void *new_func; ++ void *orig_func; ++} interpose_t; ++ ++# define FN_NAME(fn) dummy_ ## fn ++# define INTERPOSE(fn) \ ++ __attribute__((__used__)) static const interpose_t interpose_ ## fn \ ++ __attribute__((__section__("__DATA,__interpose"))) = \ ++ { (void *)dummy_ ## fn, (void *)fn }; ++#else ++# define FN_NAME(fn) fn ++# define INTERPOSE(fn) ++#endif ++ ++/* ++ * Dummy versions of the exec(3) family of syscalls. It is not enough to ++ * just dummy out execve(2) since many C libraries do not call the public ++ * execve(2) interface. Note that it is still possible to access the real ++ * syscalls via the syscall(2) interface, but that is rarely done. + */ + + #define DUMMY_BODY \ +@@ -40,61 +84,172 @@ + return -1; \ + } + ++#define DUMMY1(fn, t1) \ ++__dso_public int \ ++FN_NAME(fn)(t1 a1) \ ++DUMMY_BODY \ ++INTERPOSE(fn) ++ + #define DUMMY2(fn, t1, t2) \ + __dso_public int \ +-fn(t1 a1, t2 a2) \ +-DUMMY_BODY ++FN_NAME(fn)(t1 a1, t2 a2) \ ++DUMMY_BODY \ ++INTERPOSE(fn) + + #define DUMMY3(fn, t1, t2, t3) \ + __dso_public int \ +-fn(t1 a1, t2 a2, t3 a3) \ +-DUMMY_BODY ++FN_NAME(fn)(t1 a1, t2 a2, t3 a3) \ ++DUMMY_BODY \ ++INTERPOSE(fn) + + #define DUMMY6(fn, t1, t2, t3, t4, t5, t6) \ + __dso_public int \ +-fn(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +-DUMMY_BODY ++FN_NAME(fn)(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ ++DUMMY_BODY \ ++INTERPOSE(fn) + + #define DUMMY_VA(fn, t1, t2) \ + __dso_public int \ +-fn(t1 a1, t2 a2, ...) \ +-DUMMY_BODY ++FN_NAME(fn)(t1 a1, t2 a2, ...) \ ++DUMMY_BODY \ ++INTERPOSE(fn) + ++/* ++ * Standard exec(3) family of functions. ++ */ + DUMMY_VA(execl, const char *, const char *) +-DUMMY_VA(_execl, const char *, const char *) +-DUMMY_VA(__execl, const char *, const char *) + DUMMY_VA(execle, const char *, const char *) +-DUMMY_VA(_execle, const char *, const char *) +-DUMMY_VA(__execle, const char *, const char *) + DUMMY_VA(execlp, const char *, const char *) +-DUMMY_VA(_execlp, const char *, const char *) +-DUMMY_VA(__execlp, const char *, const char *) +-DUMMY3(exect, const char *, char * const *, char * const *) +-DUMMY3(_exect, const char *, char * const *, char * const *) +-DUMMY3(__exect, const char *, char * const *, char * const *) + DUMMY2(execv, const char *, char * const *) +-DUMMY2(_execv, const char *, char * const *) +-DUMMY2(__execv, const char *, char * const *) + DUMMY2(execvp, const char *, char * const *) +-DUMMY2(_execvp, const char *, char * const *) +-DUMMY2(__execvp, const char *, char * const *) +-DUMMY3(execvP, const char *, const char *, char * const *) +-DUMMY3(_execvP, const char *, const char *, char * const *) +-DUMMY3(__execvP, const char *, const char *, char * const *) + DUMMY3(execve, const char *, char * const *, char * const *) +-DUMMY3(_execve, const char *, char * const *, char * const *) +-DUMMY3(__execve, const char *, char * const *, char * const *) ++ ++/* ++ * Non-standard exec(3) functions and corresponding private versions. ++ */ ++#ifdef HAVE_EXECVP ++DUMMY3(execvP, const char *, const char *, char * const *) ++#endif ++#ifdef HAVE_EXECVPE + DUMMY3(execvpe, const char *, char * const *, char * const *) +-DUMMY3(_execvpe, const char *, char * const *, char * const *) +-DUMMY3(__execvpe, const char *, char * const *, char * const *) ++#endif ++#ifdef HAVE_EXECT ++DUMMY3(exect, const char *, char * const *, char * const *) ++#endif ++ ++/* ++ * Not all systems support fexecve(2), posix_spawn(2) and posix_spawnp(2). ++ */ ++#ifdef HAVE_FEXECVE + DUMMY3(fexecve, int , char * const *, char * const *) +-DUMMY3(_fexecve, int , char * const *, char * const *) +-DUMMY3(__fexecve, int , char * const *, char * const *) +-#ifdef HAVE_SPAWN_H ++#endif ++#ifdef HAVE_POSIX_SPAWN + DUMMY6(posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) +-DUMMY6(_posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) +-DUMMY6(__posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) ++#endif ++#ifdef HAVE_POSIX_SPAWNP + DUMMY6(posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) +-DUMMY6(_posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) +-DUMMY6(__posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) +-#endif /* HAVE_SPAWN_H */ ++#endif ++ ++/* ++ * system(3) and popen(3). ++ * We can't use a wrapper for popen since it returns FILE *, not int. ++ */ ++DUMMY1(system, const char *) ++ ++__dso_public FILE * ++FN_NAME(popen)(const char *c, const char *t) ++{ ++ errno = EACCES; ++ return NULL; ++} ++INTERPOSE(popen) ++ ++#if defined(HAVE_WORDEXP) && (defined(RTLD_NEXT) || defined(HAVE_SHL_LOAD) || defined(HAVE___INTERPOSE)) ++/* ++ * We can't use a wrapper for wordexp(3) since we still want to call ++ * the real wordexp(3) but with WRDE_NOCMD added to the flags argument. ++ */ ++typedef int (*sudo_fn_wordexp_t)(const char *, wordexp_t *, int); ++ ++__dso_public int ++FN_NAME(wordexp)(const char *words, wordexp_t *we, int flags) ++{ ++#if defined(HAVE___INTERPOSE) ++ return wordexp(words, we, flags | WRDE_NOCMD); ++#else ++# if defined(HAVE_DLOPEN) ++ void *fn = dlsym(RTLD_NEXT, "wordexp"); ++# elif defined(HAVE_SHL_LOAD) ++ const char *name, *myname = _PATH_SUDO_NOEXEC; ++ struct shl_descriptor *desc; ++ void *fn = NULL; ++ int idx = 0; ++ ++ name = strrchr(myname, '/'); ++ if (name != NULL) ++ myname = name + 1; ++ ++ /* Search for wordexp() but skip this shared object. */ ++ while (shl_get(idx++, &desc) == 0) { ++ name = strrchr(desc->filename, '/'); ++ if (name == NULL) ++ name = desc->filename; ++ else ++ name++; ++ if (strcmp(name, myname) == 0) ++ continue; ++ if (shl_findsym(&desc->handle, "wordexp", TYPE_PROCEDURE, &fn) == 0) ++ break; ++ } ++# else ++ void *fn = NULL; ++# endif ++ if (fn == NULL) { ++ errno = EACCES; ++ return -1; ++ } ++ return ((sudo_fn_wordexp_t)fn)(words, we, flags | WRDE_NOCMD); ++#endif /* HAVE___INTERPOSE */ ++} ++INTERPOSE(wordexp) ++#endif /* HAVE_WORDEXP && (RTLD_NEXT || HAVE_SHL_LOAD || HAVE___INTERPOSE) */ ++ ++/* ++ * On Linux we can use a seccomp() filter to disable exec. ++ */ ++#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER ++ ++/* Older systems may not support execveat(2). */ ++#ifndef __NR_execveat ++# define __NR_execveat -1 ++#endif ++ ++static void noexec_ctor(void) __attribute__((constructor)); ++ ++static void ++noexec_ctor(void) ++{ ++ struct sock_filter exec_filter[] = { ++ /* Load syscall number into the accumulator */ ++ BPF_STMT(BPF_LD | BPF_ABS, offsetof(struct seccomp_data, nr)), ++ /* Jump to deny for execve/execveat */ ++ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 2, 0), ++ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execveat, 1, 0), ++ /* Allow non-matching syscalls */ ++ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), ++ /* Deny execve/execveat syscall */ ++ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (EACCES & SECCOMP_RET_DATA)) ++ }; ++ const struct sock_fprog exec_fprog = { ++ nitems(exec_filter), ++ exec_filter ++ }; ++ ++ /* ++ * SECCOMP_MODE_FILTER will fail unless the process has ++ * CAP_SYS_ADMIN or the no_new_privs bit is set. ++ */ ++ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == 0) ++ (void)prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &exec_fprog); ++} ++#endif /* HAVE_DECL_SECCOMP_SET_MODE_FILTER */ diff --git a/SPECS/sudo.spec b/SPECS/sudo.spec index ad1cab7..b78c293 100644 --- a/SPECS/sudo.spec +++ b/SPECS/sudo.spec @@ -1,7 +1,7 @@ Summary: Allows restricted root access for specified users Name: sudo Version: 1.8.6p7 -Release: 20%{?dist} +Release: 21%{?dist} License: ISC Group: Applications/System URL: http://www.courtesan.com/sudo/ @@ -144,6 +144,8 @@ Patch55: sudo-1.8.6p7-nproc-nowait.patch Patch56: sudo-1.8.6p7-digest_race_doc.patch # 1350828 - [RHEL7] visudo ignores -q flag Patch57: sudo-1.8.6p3-visudo-quiet-flag.patch +# 1391939 - CVE-2016-7032 CVE-2016-7076 sudo: various flaws [rhel-7.4] +Patch58: sudo-1.8.6p7-noexec-update.patch %description Sudo (superuser do) allows a system administrator to give certain @@ -225,6 +227,7 @@ plugins that use %{name}. %patch55 -p1 -b .nproc-nowait %patch56 -p1 -b .digest_race_doc %patch57 -p1 -b .visudo-quiet-flag +%patch58 -p1 -b .noexec-update %build autoreconf -I m4 -fv --install @@ -346,6 +349,11 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man8/sudo_plugin.8* %changelog +* Wed Nov 23 2016 Daniel Kopecek - 1.8.6p7-21 +- Update noexec syscall blacklist +- Fixes CVE-2016-7032 and CVE-2016-7076 + Resolves: rhbz#1391939 + * Tue Jul 19 2016 Daniel Kopecek - 1.8.6p7-20 - RHEL 7.3 erratum - fixed visudo's -q flag