]> granicus.if.org Git - sudo/commitdiff
Wrap wordexp(3) in sudo_noexec.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 6 Oct 2016 02:21:18 +0000 (20:21 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 6 Oct 2016 02:21:18 +0000 (20:21 -0600)
aclocal.m4
config.h.in
configure
configure.ac
src/sudo_noexec.c

index ed555540b101bff339c4377fd318ac4c4dc6a6a5..c2591690e6fcdc32e6f437329477e325c404c9ab 100644 (file)
@@ -13,7 +13,7 @@
 
 m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
 # longlong.m4 serial 17
-dnl Copyright (C) 1999-2007, 2009-2015 Free Software Foundation, Inc.
+dnl Copyright (C) 1999-2007, 2009-2016 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
index f9d63a5d528e05721c363559bdb30e8158a7a121..3ca0056787a093475e88d5bb4e795a05e0baab46 100644 (file)
 /* 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 <wordexp.h> header file. */
+#undef HAVE_WORDEXP_H
+
 /* Define to 1 if you have the <zlib.h> header file. */
 #undef HAVE_ZLIB_H
 
index d753be4ef94bd22a80fbf52a7a2b815bb9318139..576ca1028fbece9d3dd0ecbd8f386c13acffae0d 100755 (executable)
--- a/configure
+++ b/configure
@@ -2648,6 +2648,7 @@ as_fn_append ac_header_list " netgroup.h"
 as_fn_append ac_header_list " paths.h"
 as_fn_append ac_header_list " spawn.h"
 as_fn_append ac_header_list " utmpx.h"
+as_fn_append ac_header_list " wordexp.h"
 as_fn_append ac_header_list " sys/sockio.h"
 as_fn_append ac_header_list " sys/bsdtypes.h"
 as_fn_append ac_header_list " sys/select.h"
@@ -2661,6 +2662,7 @@ as_fn_append ac_func_list " pread"
 as_fn_append ac_func_list " pwrite"
 as_fn_append ac_func_list " openat"
 as_fn_append ac_func_list " faccessat"
+as_fn_append ac_func_list " wordexp"
 as_fn_append ac_func_list " seteuid"
 # Check that the precious variables saved in the cache have kept the same
 # value.
@@ -16813,6 +16815,8 @@ done
 
 
 
+
+
 
 
 for ac_header in endian.h sys/endian.h machine/endian.h
@@ -18072,6 +18076,8 @@ done
 
 
 
+
+
 case "$host_os" in
     hpux*)
        if test X"$ac_cv_func_pread" = X"yes"; then
index 9feddfdd95983945610dd86e7ced5bec8b779e1f..2479b54dc9d63fb85482982ba4b653f6e1dbebfe 100644 (file)
@@ -2261,7 +2261,7 @@ AC_HEADER_DIRENT
 AC_HEADER_TIME
 AC_HEADER_STDBOOL
 AC_HEADER_MAJOR
-AC_CHECK_HEADERS_ONCE([netgroup.h paths.h spawn.h utmpx.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h])
+AC_CHECK_HEADERS_ONCE([netgroup.h paths.h spawn.h utmpx.h wordexp.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h])
 AC_CHECK_HEADERS([endian.h] [sys/endian.h] [machine/endian.h], [break])
 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
@@ -2400,7 +2400,7 @@ dnl
 dnl Function checks
 dnl
 AC_FUNC_GETGROUPS
-AC_CHECK_FUNCS_ONCE([fexecve killpg nl_langinfo strftime pread pwrite openat faccessat])
+AC_CHECK_FUNCS_ONCE([fexecve killpg nl_langinfo strftime pread pwrite openat faccessat wordexp])
 case "$host_os" in
     hpux*)
        if test X"$ac_cv_func_pread" = X"yes"; then
index 91bc994d3f2cdd0ce09add35d893f967841218a7..43392da6855be20c860f871464cb4ae059596241 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005, 2010-2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2004-2005, 2010-2016 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 #ifdef HAVE_SPAWN_H
 #include <spawn.h>
 #endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_WORDEXP_H
+#include <wordexp.h>
+#endif
+#if defined(HAVE_SHL_LOAD)
+# include <dl.h>
+#elif defined(HAVE_DLOPEN)
+# include <dlfcn.h>
+#endif
 
 #include "sudo_compat.h"
+#include "pathnames.h"
 
 #ifdef HAVE___INTERPOSE
 /*
@@ -141,3 +156,51 @@ FN_NAME(popen)(const char *c, const char *t)
     return NULL;
 }
 INTERPOSE(popen)
+
+/*
+ * 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)