diff options
| author | Brent Cook <busterb@gmail.com> | 2015-04-14 07:55:23 -0500 |
|---|---|---|
| committer | Brent Cook <busterb@gmail.com> | 2015-04-14 07:55:23 -0500 |
| commit | 3096ab0e45351b05b1f1df51cedc183ba6ca7763 (patch) | |
| tree | 01cb87f1fd541907d481311064bdab5d2cdf3691 | |
| parent | fe3f7fc6365bfaac3418a72256b8c11603e80cbf (diff) | |
| download | portable-3096ab0e45351b05b1f1df51cedc183ba6ca7763.tar.gz portable-3096ab0e45351b05b1f1df51cedc183ba6ca7763.tar.bz2 portable-3096ab0e45351b05b1f1df51cedc183ba6ca7763.zip | |
remove issetuigid wrappers, now that all getenv calls are gone.
From deraadt@ upstream:
Remove all getenv() calls, especially those wrapped by issetugid().
getenv()'s wrapped by issetugid() are safe, but issetugid() is ...
difficult to impliment on many operating systems. By accident, a grand
experiment was run over the last year, where issetugid() returned 1 (the
safe value) on a few operating systems. Noone noticed & complained that
certain environment variables were not working.......
| -rw-r--r-- | README | 4 | ||||
| -rw-r--r-- | configure.ac | 8 | ||||
| -rw-r--r-- | crypto/Makefile.am | 18 | ||||
| -rw-r--r-- | crypto/compat/issetugid_aix.c | 107 | ||||
| -rw-r--r-- | crypto/compat/issetugid_hpux.c | 17 | ||||
| -rw-r--r-- | crypto/compat/issetugid_linux.c | 47 | ||||
| -rw-r--r-- | crypto/compat/issetugid_osx.c | 16 | ||||
| -rw-r--r-- | crypto/compat/issetugid_win.c | 26 | ||||
| -rw-r--r-- | include/unistd.h | 4 |
9 files changed, 3 insertions, 244 deletions
| @@ -43,8 +43,8 @@ programs to LibreSSL in order to use it, just as in moving from OpenSSL 0.9.8 | |||
| 43 | to 1.0.1. | 43 | to 1.0.1. |
| 44 | 44 | ||
| 45 | The project attempts to provide working alternatives for operating systems with | 45 | The project attempts to provide working alternatives for operating systems with |
| 46 | limited or broken security primitives (e.g. arc4random(3), issetugid(2)) and | 46 | limited or broken security primitives (e.g. arc4random(3)) and assists with |
| 47 | assists with improving OS-native implementations where possible. | 47 | improving OS-native implementations where possible. |
| 48 | 48 | ||
| 49 | LibreSSL portable will build on any reasonably modern version of Linux, | 49 | LibreSSL portable will build on any reasonably modern version of Linux, |
| 50 | Solaris, or OSX with a standards-compliant compiler and C library. | 50 | Solaris, or OSX with a standards-compliant compiler and C library. |
diff --git a/configure.ac b/configure.ac index 75a1ec2..2cd9814 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -220,7 +220,7 @@ CFLAGS="$save_cflags $AM_CFLAGS" | |||
| 220 | AM_PROG_AS | 220 | AM_PROG_AS |
| 221 | 221 | ||
| 222 | AC_CHECK_FUNCS([arc4random_buf asprintf explicit_bzero funopen getauxval]) | 222 | AC_CHECK_FUNCS([arc4random_buf asprintf explicit_bzero funopen getauxval]) |
| 223 | AC_CHECK_FUNCS([getentropy issetugid memmem poll reallocarray]) | 223 | AC_CHECK_FUNCS([getentropy memmem poll reallocarray]) |
| 224 | AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strsep strtonum]) | 224 | AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strsep strtonum]) |
| 225 | AC_CHECK_FUNCS([symlink]) | 225 | AC_CHECK_FUNCS([symlink]) |
| 226 | AC_CHECK_FUNCS([timingsafe_bcmp timingsafe_memcmp]) | 226 | AC_CHECK_FUNCS([timingsafe_bcmp timingsafe_memcmp]) |
| @@ -230,7 +230,6 @@ AM_CONDITIONAL([HAVE_ARC4RANDOM_BUF], [test "x$ac_cv_func_arc4random_buf" = xyes | |||
| 230 | AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes]) | 230 | AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes]) |
| 231 | AM_CONDITIONAL([HAVE_EXPLICIT_BZERO], [test "x$ac_cv_func_explicit_bzero" = xyes]) | 231 | AM_CONDITIONAL([HAVE_EXPLICIT_BZERO], [test "x$ac_cv_func_explicit_bzero" = xyes]) |
| 232 | AM_CONDITIONAL([HAVE_GETENTROPY], [test "x$ac_cv_func_getentropy" = xyes]) | 232 | AM_CONDITIONAL([HAVE_GETENTROPY], [test "x$ac_cv_func_getentropy" = xyes]) |
| 233 | AM_CONDITIONAL([HAVE_ISSETUGID], [test "x$ac_cv_func_issetugid" = xyes]) | ||
| 234 | AM_CONDITIONAL([HAVE_MEMMEM], [test "x$ac_cv_func_memmem" = xyes]) | 233 | AM_CONDITIONAL([HAVE_MEMMEM], [test "x$ac_cv_func_memmem" = xyes]) |
| 235 | AM_CONDITIONAL([HAVE_POLL], [test "x$ac_cv_func_poll" = xyes]) | 234 | AM_CONDITIONAL([HAVE_POLL], [test "x$ac_cv_func_poll" = xyes]) |
| 236 | AM_CONDITIONAL([HAVE_REALLOCARRAY], [test "x$ac_cv_func_reallocarray" = xyes]) | 235 | AM_CONDITIONAL([HAVE_REALLOCARRAY], [test "x$ac_cv_func_reallocarray" = xyes]) |
| @@ -251,11 +250,6 @@ AM_CONDITIONAL([HAVE_ARC4RANDOM_BUF], | |||
| 251 | -a "x$HOST_OS" != xnetbsd \ | 250 | -a "x$HOST_OS" != xnetbsd \ |
| 252 | -a "x$ac_cv_func_arc4random_buf" = xyes]) | 251 | -a "x$ac_cv_func_arc4random_buf" = xyes]) |
| 253 | 252 | ||
| 254 | # overrides for issetugid implementations with known issues | ||
| 255 | AM_CONDITIONAL([HAVE_ISSETUGID], | ||
| 256 | [test "x$HOST_OS" != xdarwin \ | ||
| 257 | -a "x$ac_cv_func_issetugid" = xyes]) | ||
| 258 | |||
| 259 | AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [ | 253 | AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [ |
| 260 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[ | 254 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[ |
| 261 | #include <stdarg.h> | 255 | #include <stdarg.h> |
diff --git a/crypto/Makefile.am b/crypto/Makefile.am index 83bf0c6..757197f 100644 --- a/crypto/Makefile.am +++ b/crypto/Makefile.am | |||
| @@ -97,24 +97,6 @@ endif | |||
| 97 | 97 | ||
| 98 | endif | 98 | endif |
| 99 | 99 | ||
| 100 | if !HAVE_ISSETUGID | ||
| 101 | if HOST_AIX | ||
| 102 | libcompat_la_SOURCES += compat/issetugid_aix.c | ||
| 103 | endif | ||
| 104 | if HOST_LINUX | ||
| 105 | libcompat_la_SOURCES += compat/issetugid_linux.c | ||
| 106 | endif | ||
| 107 | if HOST_HPUX | ||
| 108 | libcompat_la_SOURCES += compat/issetugid_hpux.c | ||
| 109 | endif | ||
| 110 | if HOST_DARWIN | ||
| 111 | libcompat_la_SOURCES += compat/issetugid_osx.c | ||
| 112 | endif | ||
| 113 | if HOST_WIN | ||
| 114 | libcompat_la_SOURCES += compat/issetugid_win.c | ||
| 115 | endif | ||
| 116 | endif | ||
| 117 | |||
| 118 | noinst_HEADERS = | 100 | noinst_HEADERS = |
| 119 | noinst_HEADERS += compat/arc4random.h | 101 | noinst_HEADERS += compat/arc4random.h |
| 120 | noinst_HEADERS += compat/arc4random_aix.h | 102 | noinst_HEADERS += compat/arc4random_aix.h |
diff --git a/crypto/compat/issetugid_aix.c b/crypto/compat/issetugid_aix.c deleted file mode 100644 index 16f0a6d..0000000 --- a/crypto/compat/issetugid_aix.c +++ /dev/null | |||
| @@ -1,107 +0,0 @@ | |||
| 1 | /* $OpenBSD: $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 2015 Michael Felt <aixtools@gmail.com> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sys/id.h> | ||
| 21 | #include <sys/priv.h> | ||
| 22 | |||
| 23 | #include <stdio.h> | ||
| 24 | #include <unistd.h> | ||
| 25 | |||
| 26 | /* | ||
| 27 | * AIX does not have issetugid(). | ||
| 28 | * This experimental implementation uses getpriv() and get*id(). | ||
| 29 | * First, try getpriv() and check equality of pv_priv values | ||
| 30 | * When these values are equal, using get*id() including login uid. | ||
| 31 | * | ||
| 32 | */ | ||
| 33 | int issetugid(void) | ||
| 34 | { | ||
| 35 | /* | ||
| 36 | * Return fail-safe while we evaluate primitives in AIX. There does | ||
| 37 | * not yet appear to be a single atomic test to tell if privileges of | ||
| 38 | * the process changed from that of the user who is in control of the | ||
| 39 | * environment. | ||
| 40 | */ | ||
| 41 | return (1); | ||
| 42 | |||
| 43 | #define PEPRIV(a,b) a.pv_priv[b] | ||
| 44 | /* | ||
| 45 | * effective priv is what I can do now | ||
| 46 | * inherited priv is what the caller gave or could have given | ||
| 47 | * basically when inherited == 0 and effective != 0 then | ||
| 48 | * some kind of priv escalation has occurred | ||
| 49 | * when 'demoted' -- inherited != 0 but effective == 0 | ||
| 50 | * there is also a change, so, will report 1 as well - to be safe | ||
| 51 | * PROBABLY there needs more study re: how RBAC subtley affects | ||
| 52 | * the priv_t values - for now, they are either zero - nothing added | ||
| 53 | * or non-zero - something added | ||
| 54 | */ | ||
| 55 | priv_t effective,inherited; | ||
| 56 | int luid; | ||
| 57 | int euid, ruid; | ||
| 58 | |||
| 59 | getpriv(PRIV_EFFECTIVE, &effective, sizeof(priv_t)); | ||
| 60 | getpriv(PRIV_INHERITED, &inherited, sizeof(priv_t)); | ||
| 61 | |||
| 62 | if (PEPRIV(effective,0) | PEPRIV(effective,1)) { /* have something */ | ||
| 63 | if ((PEPRIV(inherited,0) | PEPRIV(inherited,1)) == 0) /* had nothing - classic u+s bit */ | ||
| 64 | return (1); | ||
| 65 | } else { | ||
| 66 | /* | ||
| 67 | * effective priv elevation is NULL/NONE | ||
| 68 | * was there something and removed via setuid()? | ||
| 69 | */ | ||
| 70 | if (PEPRIV(inherited,0) | PEPRIV(inherited,1)) | ||
| 71 | return (1); | ||
| 72 | } | ||
| 73 | |||
| 74 | /* | ||
| 75 | * if we get this far, then "no" differences in process priv noted | ||
| 76 | * compare the different uid | ||
| 77 | * the comparision of login id with effective says "TRUE" when different. | ||
| 78 | * this may not work as expected when using sudo for elevation | ||
| 79 | * again, looking at RBAC affects on priv may be more truthful | ||
| 80 | * | ||
| 81 | * ruid - real uid | ||
| 82 | * euid - effictive uid | ||
| 83 | * luid - login uid | ||
| 84 | */ | ||
| 85 | |||
| 86 | /* | ||
| 87 | * if these differ (not common on AIX), return changed | ||
| 88 | */ | ||
| 89 | ruid = getuid(); | ||
| 90 | euid = geteuid(); | ||
| 91 | if (euid != ruid) | ||
| 92 | return (1); | ||
| 93 | |||
| 94 | if (getgid() != getegid()) | ||
| 95 | return (1); | ||
| 96 | |||
| 97 | /* | ||
| 98 | * luid == login id, su/sudo do not/cannot change this afaik | ||
| 99 | * perhaps this is "too strict", but same as in | ||
| 100 | * issetugid_win.c - err on the safe side for now | ||
| 101 | */ | ||
| 102 | luid = getuidx(ID_LOGIN); | ||
| 103 | if (euid != luid) | ||
| 104 | return (1); | ||
| 105 | |||
| 106 | return (0); | ||
| 107 | } | ||
diff --git a/crypto/compat/issetugid_hpux.c b/crypto/compat/issetugid_hpux.c deleted file mode 100644 index ca0e42c..0000000 --- a/crypto/compat/issetugid_hpux.c +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <unistd.h> | ||
| 3 | #include <sys/pstat.h> | ||
| 4 | |||
| 5 | /* | ||
| 6 | * HP-UX does not have issetugid(). | ||
| 7 | * Use pstat_getproc() and check PS_CHANGEDPRIV bit of pst_flag. If this call | ||
| 8 | * cannot be used, assume we must be running in a privileged environment. | ||
| 9 | */ | ||
| 10 | int issetugid(void) | ||
| 11 | { | ||
| 12 | struct pst_status buf; | ||
| 13 | if (pstat_getproc(&buf, sizeof(buf), 0, getpid()) == 1 && | ||
| 14 | !(buf.pst_flag & PS_CHANGEDPRIV)) | ||
| 15 | return 0; | ||
| 16 | return 1; | ||
| 17 | } | ||
diff --git a/crypto/compat/issetugid_linux.c b/crypto/compat/issetugid_linux.c deleted file mode 100644 index 669edce..0000000 --- a/crypto/compat/issetugid_linux.c +++ /dev/null | |||
| @@ -1,47 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * issetugid implementation for Linux | ||
| 3 | * Public domain | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <errno.h> | ||
| 7 | #include <gnu/libc-version.h> | ||
| 8 | #include <string.h> | ||
| 9 | #include <sys/types.h> | ||
| 10 | #include <unistd.h> | ||
| 11 | |||
| 12 | /* | ||
| 13 | * Linux-specific glibc 2.16+ interface for determining if a process was | ||
| 14 | * launched setuid/setgid or with additional capabilities. | ||
| 15 | */ | ||
| 16 | #ifdef HAVE_GETAUXVAL | ||
| 17 | #include <sys/auxv.h> | ||
| 18 | #endif | ||
| 19 | |||
| 20 | int issetugid(void) | ||
| 21 | { | ||
| 22 | #ifdef HAVE_GETAUXVAL | ||
| 23 | /* | ||
| 24 | * The API for glibc < 2.19 does not indicate if there is an error with | ||
| 25 | * getauxval. While it should not be the case that any 2.6 or greater | ||
| 26 | * kernel ever does not supply AT_SECURE, an emulated software environment | ||
| 27 | * might rewrite the aux vector. | ||
| 28 | * | ||
| 29 | * See https://sourceware.org/bugzilla/show_bug.cgi?id=15846 | ||
| 30 | * | ||
| 31 | * Perhaps this code should just read the aux vector itself, so we have | ||
| 32 | * backward-compatibility and error handling in older glibc versions. | ||
| 33 | * info: http://lwn.net/Articles/519085/ | ||
| 34 | * | ||
| 35 | */ | ||
| 36 | const char *glcv = gnu_get_libc_version(); | ||
| 37 | if (strverscmp(glcv, "2.19") >= 0) { | ||
| 38 | errno = 0; | ||
| 39 | if (getauxval(AT_SECURE) == 0) { | ||
| 40 | if (errno != ENOENT) { | ||
| 41 | return 0; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | #endif | ||
| 46 | return 1; | ||
| 47 | } | ||
diff --git a/crypto/compat/issetugid_osx.c b/crypto/compat/issetugid_osx.c deleted file mode 100644 index ad6cb58..0000000 --- a/crypto/compat/issetugid_osx.c +++ /dev/null | |||
| @@ -1,16 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * issetugid implementation for OS X | ||
| 3 | * Public domain | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <unistd.h> | ||
| 7 | |||
| 8 | /* | ||
| 9 | * OS X has issetugid, but it is not fork-safe as of version 10.10. | ||
| 10 | * See this Solaris report for test code that fails similarly: | ||
| 11 | * http://mcarpenter.org/blog/2013/01/15/solaris-issetugid%282%29-bug | ||
| 12 | */ | ||
| 13 | int issetugid(void) | ||
| 14 | { | ||
| 15 | return 1; | ||
| 16 | } | ||
diff --git a/crypto/compat/issetugid_win.c b/crypto/compat/issetugid_win.c deleted file mode 100644 index d0c598d..0000000 --- a/crypto/compat/issetugid_win.c +++ /dev/null | |||
| @@ -1,26 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * issetugid implementation for Windows | ||
| 3 | * Public domain | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <unistd.h> | ||
| 7 | |||
| 8 | /* | ||
| 9 | * Windows does not have a native setuid/setgid functionality. | ||
| 10 | * A user must enter credentials each time a process elevates its | ||
| 11 | * privileges. | ||
| 12 | * | ||
| 13 | * So, in theory, this could always return 0, given what I know currently. | ||
| 14 | * However, it makes sense to stub out initially in 'safe' mode until we | ||
| 15 | * understand more (and determine if any disabled functionality is actually | ||
| 16 | * useful on Windows anyway). | ||
| 17 | * | ||
| 18 | * Future versions of this function that are made more 'open' should thoroughly | ||
| 19 | * consider the case of this code running as a privileged service with saved | ||
| 20 | * user credentials or privilege escalations by other means (e.g. the old | ||
| 21 | * RunAsEx utility.) | ||
| 22 | */ | ||
| 23 | int issetugid(void) | ||
| 24 | { | ||
| 25 | return 1; | ||
| 26 | } | ||
diff --git a/include/unistd.h b/include/unistd.h index 3aecd68..9b12034 100644 --- a/include/unistd.h +++ b/include/unistd.h | |||
| @@ -12,8 +12,4 @@ | |||
| 12 | int getentropy(void *buf, size_t buflen); | 12 | int getentropy(void *buf, size_t buflen); |
| 13 | #endif | 13 | #endif |
| 14 | 14 | ||
| 15 | #ifndef HAVE_ISSETUGID | ||
| 16 | int issetugid(void); | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #endif | 15 | #endif |
