Browse Source

initial OS X support

Well, support may be too concrete of a term. There is a lot that is
missing in OS X, and not everything can be implemented with portability
shims. The time APIs in OS X seem to have frozen with NeXTSTEP and never
advanced with POSIX.
OPENBSD_5_7
Brent Cook 9 years ago
parent
commit
9b4d748b44
9 changed files with 283 additions and 4 deletions
  1. +18
    -0
      Makefile.am
  2. +19
    -0
      bsd-adjfreq.c
  3. +38
    -0
      compat/bsd-setresgid.c
  4. +67
    -0
      compat/bsd-setresuid.c
  5. +47
    -0
      compat/clock_getres.c
  6. +44
    -0
      compat/mach-clock_gettime.c
  7. +17
    -4
      configure.ac
  8. +25
    -0
      include/time.h
  9. +8
    -0
      include/unistd.h

+ 18
- 0
Makefile.am View File

@ -94,6 +94,24 @@ libcompat_la_SOURCES += compat/imsg.c
libcompat_la_SOURCES += compat/imsg-buffer.c
endif
if !HAVE_CLOCK_GETRES
libcompat_la_SOURCES += compat/clock_getres.c
endif
if !HAVE_SETRESGID
libcompat_la_SOURCES += compat/bsd-setresgid.c
endif
if !HAVE_SETRESUID
libcompat_la_SOURCES += compat/bsd-setresuid.c
endif
if !HAVE_CLOCK_GETTIME
if HOST_DARWIN
libcompat_la_SOURCES += compat/mach-clock_gettime.c
endif
endif
if !HAVE_ARC4RANDOM
libcompat_la_SOURCES += compat/arc4random.c


+ 19
- 0
bsd-adjfreq.c View File

@ -30,6 +30,23 @@
#include "ntp.h"
#include "ntpd.h"
#ifndef NTP_ADJTIME
#include <errno.h>
/*
* Some sad but very popular platforms do not appear to provide a mechanism to
* adjust the time frequency at all!
*/
int
adjfreq(const int64_t *freq, int64_t *oldfreq)
{
errno = ENOSYS;
return -1;
}
#else
/*
* adjfreq (old)freq = nanosec. per seconds shifted left 32 bits
* timex.freq is ppm / left shifted by SHIFT_USEC (16 bits), defined in timex.h
@ -69,3 +86,5 @@ adjfreq(const int64_t *freq, int64_t *oldfreq)
return 0;
}
#endif

+ 38
- 0
compat/bsd-setresgid.c View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2004, 2005 Darren Tucker (dtucker at zip com au).
*
* 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 <sys/types.h>
#include <unistd.h>
int
setresgid(gid_t rgid, gid_t egid, gid_t sgid)
{
/* this is the only configuration tested */
if (rgid != egid || egid != sgid)
return -1;
# if defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID)
if (setregid(rgid, egid) == -1)
return -1;
# else
if (setegid(egid) == -1)
return -1;
if (setgid(rgid)) == -1)
return -1;
# endif
return 0;
}

+ 67
- 0
compat/bsd-setresuid.c View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2004, 2005 Darren Tucker (dtucker at zip com au).
*
* 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 <sys/types.h>
#include <errno.h>
#include <unistd.h>
int
setresuid(uid_t ruid, uid_t euid, uid_t suid)
{
uid_t ouid;
int ret = -1;
/* Allow only the tested configuration. */
if (ruid != euid || euid != suid) {
errno = ENOSYS;
return -1;
}
ouid = getuid();
# if defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID)
if ((ret = setreuid(euid, euid)) == -1)
return -1;
# else
# ifndef SETEUID_BREAKS_SETUID
if (seteuid(euid) == -1)
return -1;
# endif
if ((ret = setuid(ruid)) == -1)
return -1;
# endif
/*
* When real, effective and saved uids are the same and we have
* changed uids, sanity check that we cannot restore the old uid.
*/
if (ruid == euid && euid == suid && ouid != ruid &&
setuid(ouid) != -1 && seteuid(ouid) != -1) {
errno = EINVAL;
return -1;
}
/*
* Finally, check that the real and effective uids are what we
* expect.
*/
if (getuid() != ruid || geteuid() != euid) {
errno = EACCES;
return -1;
}
return ret;
}

+ 47
- 0
compat/clock_getres.c View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org>
* Copyright (c) 2004 Darren Tucker <dtucker at zip com au>
*
* 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 <sys/time.h>
#ifdef HAVE_ADJTIMEX
#include <sys/timex.h>
#endif
int
clock_getres(clockid_t clk_id, struct timespec *tp)
{
# ifdef HAVE_ADJTIMEX
struct timex tmx;
# endif
if (clk_id != CLOCK_REALTIME)
return -1; /* not implemented */
tp->tv_sec = 0;
# ifdef HAVE_ADJTIMEX
tmx.modes = 0;
if (adjtimex(&tmx) == -1)
return -1;
else
tp->tv_nsec = tmx.precision * 1000; /* usec -> nsec */
# else
/* assume default 10ms tick */
tp->tv_nsec = 10000000;
# endif
return 0;
}

+ 44
- 0
compat/mach-clock_gettime.c View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org>
* Copyright (c) 2014 Brent Cook <bcook@openbsd.org>
*
* 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 <mach/mach_time.h>
#include <sys/time.h>
#include <stdint.h>
#include <time.h>
int
clock_gettime(clockid_t clk_id, struct timespec *ts)
{
static uint64_t timebase_factor = 0;
mach_timebase_info_data_t timebase_info;
uint64_t nsec;
if (clk_id != CLOCK_REALTIME)
return -1; /* not implemented */
if (timebase_factor == 0) {
mach_timebase_info(&timebase_info);
timebase_factor = timebase_info.numer / timebase_info.denom;
}
nsec = mach_absolute_time() * timebase_factor;
ts->tv_sec = nsec / 1000000000UL;
ts->tv_nsec = nsec % 1000000000UL;
return 0;
}

+ 17
- 4
configure.ac View File

@ -12,6 +12,10 @@ CFLAGS="$CFLAGS -Wall -std=gnu99 -g"
case $host_os in
*darwin*)
HOST_OS=darwin
AC_DEFINE(SETEUID_BREAKS_SETUID,[],[setuid after seteuid doesn't work])
AC_DEFINE(BROKEN_SETREUID,[], [Broken setreuid])
AC_DEFINE(BROKEN_SETREGID,[], [Broken setregid])
AC_DEFINE(YYSTYPE_IS_DECLARED,[], [Broken bison])
;;
*freebsd*)
HOST_OS=freebsd
@ -41,6 +45,9 @@ AM_CONDITIONAL([HOST_SOLARIS], [test x$HOST_OS = xsolaris])
AC_CHECK_FUNC([clock_gettime],,
[AC_SEARCH_LIBS([clock_gettime],[rt posix4])])
AC_CHECK_FUNC([clock_getres],,
[AC_SEARCH_LIBS([clock_getres],[rt posix4])])
AC_CHECK_FUNC([dl_iterate_phdr],,
[AC_SEARCH_LIBS([dl_iterate_phdr],[dl])])
@ -74,9 +81,11 @@ CFLAGS="$CFLAGS $CLANG_CFLAGS"
LDFLAGS="$LDFLAGS $CLANG_FLAGS"
# check functions that are expected to be in libc
AC_CHECK_FUNCS([adjfreq arc4random_uniform asprintf explicit_bzero])
AC_CHECK_FUNCS([adjfreq ntp_adjtime adjtimex])
AC_CHECK_FUNCS([arc4random_uniform asprintf explicit_bzero])
AC_CHECK_FUNCS([getentropy memmem poll reallocarray])
AC_CHECK_FUNCS([setproctitle setgroups])
AC_CHECK_FUNCS([setregid setresgid setreuid setresuid])
AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strtonum])
# check auxiliary libraries that might contain other functions
@ -92,21 +101,25 @@ AM_CONDITIONAL([HAVE_ADJFREQ], [test "x$ac_cv_func_adjfreq" = xyes])
AM_CONDITIONAL([HAVE_ARC4RANDOM], [test "x$ac_cv_func_arc4random" = xyes])
AM_CONDITIONAL([HAVE_ARC4RANDOM_UNIFORM], [test "x$ac_cv_func_arc4random_uniform" = xyes])
AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes])
AM_CONDITIONAL([HAVE_CLOCK_GETRES], [test "x$ac_cv_func_clock_getres" = xyes])
AM_CONDITIONAL([HAVE_CLOCK_GETTIME], [test "x$ac_cv_func_clock_gettime" = xyes])
AM_CONDITIONAL([HAVE_EXPLICIT_BZERO], [test "x$ac_cv_func_explicit_bzero" = xyes])
AM_CONDITIONAL([HAVE_GETENTROPY], [test "x$ac_cv_func_getentropy" = xyes])
AM_CONDITIONAL([HAVE_IMSG], [test "x$ac_cv_func_ibuf_open" = xyes])
AM_CONDITIONAL([HAVE_MD5], [test "x$ac_cv_func_MD5Init" = xyes])
AM_CONDITIONAL([HAVE_MEMMEM], [test "x$ac_cv_func_memmem" = xyes])
AM_CONDITIONAL([HAVE_POLL], [test "x$ac_cv_func_poll" = xyes])
AM_CONDITIONAL([HAVE_REALLOCARRAY], [test "x$ac_cv_func_reallocarray" = xyes])
AM_CONDITIONAL([HAVE_SETGROUPS], [test "x$ac_cv_func_setgroups" = xyes])
AM_CONDITIONAL([HAVE_SETRESGID], [test "x$ac_cv_func_setresgid" = xyes])
AM_CONDITIONAL([HAVE_SETRESUID], [test "x$ac_cv_func_setresuid" = xyes])
AM_CONDITIONAL([HAVE_SETPROCTITLE], [test "x$ac_cv_func_setproctitle" = xyes])
AM_CONDITIONAL([HAVE_SHA512], [test "x$ac_cv_func_SHA512Init" = xyes])
AM_CONDITIONAL([HAVE_STRLCAT], [test "x$ac_cv_func_strlcat" = xyes])
AM_CONDITIONAL([HAVE_STRLCPY], [test "x$ac_cv_func_strlcpy" = xyes])
AM_CONDITIONAL([HAVE_STRNDUP], [test "x$ac_cv_func_strndup" = xyes])
AM_CONDITIONAL([HAVE_STRNLEN], [test "x$ac_cv_func_strnlen" = xyes])
AM_CONDITIONAL([HAVE_STRTONUM], [test "x$ac_cv_func_strtonum" = xyes])
AM_CONDITIONAL([HAVE_MD5], [test "x$ac_cv_func_MD5Init" = xyes])
AM_CONDITIONAL([HAVE_SHA512], [test "x$ac_cv_func_SHA512Init" = xyes])
AM_CONDITIONAL([HAVE_IMSG], [test "x$ac_cv_func_ibuf_open" = xyes])
# overrides for arc4random_buf implementations with known issues
AM_CONDITIONAL([HAVE_ARC4RANDOM],


+ 25
- 0
include/time.h View File

@ -0,0 +1,25 @@
/*
* Public domain
* time.h compatibility shim
*/
#include_next <time.h>
#ifndef LIBCOMPAT_TIME_H
#define LIBCOMPAT_TIME_H
#ifndef CLOCK_REALTIME
typedef int clockid_t;
#define CLOCK_REALTIME 1
#define CLOCK_MONOTONIC 2
#endif
#ifndef HAVE_CLOCK_GETRES
int clock_getres(clockid_t clk_id, struct timespec *res);
#endif
#ifndef HAVE_CLOCK_GETTIME
int clock_gettime(clockid_t clk_id, struct timespec *ts);
#endif
#endif

+ 8
- 0
include/unistd.h View File

@ -18,4 +18,12 @@ int getentropy(void *buf, size_t buflen);
int setgroups(int ngroups, const gid_t *gidset);
#endif
#ifndef HAVE_SETRESGID
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
#endif
#ifndef HAVE_SETRESUID
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
#endif
#endif

Loading…
Cancel
Save