From fe3f7fc6365bfaac3418a72256b8c11603e80cbf Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Tue, 10 Feb 2015 23:49:31 -0600 Subject: [PATCH] Add experimental AIX support. This includes a WIP failsafe issetugid for now, while research continues on the proper way to do this in a race-free fashion in AIX. --- configure.ac | 5 ++ crypto/Makefile.am | 7 +++ crypto/compat/arc4random.h | 5 +- crypto/compat/issetugid_aix.c | 107 ++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 crypto/compat/issetugid_aix.c diff --git a/configure.ac b/configure.ac index 67266cb..75a1ec2 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,10 @@ LT_INIT CFLAGS="$CFLAGS -Wall -std=gnu99" case $host_os in + *aix*) + HOST_OS=aix + AC_SUBST([PLATFORM_LDADD], ['-lperfstat -lpthread']) + ;; *cygwin*) HOST_OS=cygwin ;; @@ -68,6 +72,7 @@ case $host_os in *) ;; esac +AM_CONDITIONAL([HOST_AIX], [test x$HOST_OS = xaix]) AM_CONDITIONAL([HOST_CYGWIN], [test x$HOST_OS = xcygwin]) AM_CONDITIONAL([HOST_DARWIN], [test x$HOST_OS = xdarwin]) AM_CONDITIONAL([HOST_FREEBSD], [test x$HOST_OS = xfreebsd]) diff --git a/crypto/Makefile.am b/crypto/Makefile.am index e350cda..83bf0c6 100644 --- a/crypto/Makefile.am +++ b/crypto/Makefile.am @@ -69,6 +69,9 @@ if !HAVE_ARC4RANDOM_BUF libcompat_la_SOURCES += compat/arc4random.c if !HAVE_GETENTROPY +if HOST_AIX +libcompat_la_SOURCES += compat/getentropy_aix.c +endif if HOST_FREEBSD libcompat_la_SOURCES += compat/getentropy_freebsd.c endif @@ -95,6 +98,9 @@ endif endif if !HAVE_ISSETUGID +if HOST_AIX +libcompat_la_SOURCES += compat/issetugid_aix.c +endif if HOST_LINUX libcompat_la_SOURCES += compat/issetugid_linux.c endif @@ -111,6 +117,7 @@ endif noinst_HEADERS = noinst_HEADERS += compat/arc4random.h +noinst_HEADERS += compat/arc4random_aix.h noinst_HEADERS += compat/arc4random_freebsd.h noinst_HEADERS += compat/arc4random_hpux.h noinst_HEADERS += compat/arc4random_linux.h diff --git a/crypto/compat/arc4random.h b/crypto/compat/arc4random.h index ce1bbea..762aec2 100644 --- a/crypto/compat/arc4random.h +++ b/crypto/compat/arc4random.h @@ -3,7 +3,10 @@ #include -#if defined(__FreeBSD__) +#if defined(_AIX) +#include "arc4random_aix.h" + +#elif defined(__FreeBSD__) #include "arc4random_freebsd.h" #elif defined(__hpux) diff --git a/crypto/compat/issetugid_aix.c b/crypto/compat/issetugid_aix.c new file mode 100644 index 0000000..16f0a6d --- /dev/null +++ b/crypto/compat/issetugid_aix.c @@ -0,0 +1,107 @@ +/* $OpenBSD: $ */ + +/* + * Copyright (c) 2015 Michael Felt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include +#include + +#include +#include + +/* + * AIX does not have issetugid(). + * This experimental implementation uses getpriv() and get*id(). + * First, try getpriv() and check equality of pv_priv values + * When these values are equal, using get*id() including login uid. + * + */ +int issetugid(void) +{ + /* + * Return fail-safe while we evaluate primitives in AIX. There does + * not yet appear to be a single atomic test to tell if privileges of + * the process changed from that of the user who is in control of the + * environment. + */ + return (1); + +#define PEPRIV(a,b) a.pv_priv[b] + /* + * effective priv is what I can do now + * inherited priv is what the caller gave or could have given + * basically when inherited == 0 and effective != 0 then + * some kind of priv escalation has occurred + * when 'demoted' -- inherited != 0 but effective == 0 + * there is also a change, so, will report 1 as well - to be safe + * PROBABLY there needs more study re: how RBAC subtley affects + * the priv_t values - for now, they are either zero - nothing added + * or non-zero - something added + */ + priv_t effective,inherited; + int luid; + int euid, ruid; + + getpriv(PRIV_EFFECTIVE, &effective, sizeof(priv_t)); + getpriv(PRIV_INHERITED, &inherited, sizeof(priv_t)); + + if (PEPRIV(effective,0) | PEPRIV(effective,1)) { /* have something */ + if ((PEPRIV(inherited,0) | PEPRIV(inherited,1)) == 0) /* had nothing - classic u+s bit */ + return (1); + } else { + /* + * effective priv elevation is NULL/NONE + * was there something and removed via setuid()? + */ + if (PEPRIV(inherited,0) | PEPRIV(inherited,1)) + return (1); + } + + /* + * if we get this far, then "no" differences in process priv noted + * compare the different uid + * the comparision of login id with effective says "TRUE" when different. + * this may not work as expected when using sudo for elevation + * again, looking at RBAC affects on priv may be more truthful + * + * ruid - real uid + * euid - effictive uid + * luid - login uid + */ + + /* + * if these differ (not common on AIX), return changed + */ + ruid = getuid(); + euid = geteuid(); + if (euid != ruid) + return (1); + + if (getgid() != getegid()) + return (1); + + /* + * luid == login id, su/sudo do not/cannot change this afaik + * perhaps this is "too strict", but same as in + * issetugid_win.c - err on the safe side for now + */ + luid = getuidx(ID_LOGIN); + if (euid != luid) + return (1); + + return (0); +}