diff --git a/MANIFEST b/MANIFEST index a239ab384..e07c6e294 100644 --- a/MANIFEST +++ b/MANIFEST @@ -51,6 +51,7 @@ compat/charclass.h compat/closefrom.c compat/dlfcn.h compat/dlopen.c +compat/endian.h compat/fnmatch.c compat/fnmatch.h compat/getaddrinfo.c diff --git a/compat/endian.h b/compat/endian.h new file mode 100644 index 000000000..608098267 --- /dev/null +++ b/compat/endian.h @@ -0,0 +1,55 @@ +#ifndef _COMPAT_ENDIAN_H +#define _COMPAT_ENDIAN_H + +#ifndef BYTE_ORDER +# undef LITTLE_ENDIAN +# define LITTLE_ENDIAN 1234 +# undef BIG_ENDIAN +# define BIG_ENDIAN 4321 +# undef UNKNOWN_ENDIAN +# define UNKNOWN_ENDIAN 0 + +/* + * Attempt to guess endianness. + * Solaris may define _LITTLE_ENDIAN and _BIG_ENDIAN to 1 + * HP-UX may define __LITTLE_ENDIAN__ and __BIG_ENDIAN__ to 1 + * Otherwise, check for cpu-specific cpp defines. + * Note that some CPUs are bi-endian, including: arm, powerpc, alpha, + * sparc64, mips, hppa, sh4 and ia64. + * We just check for the most common uses. + */ + +/* Solaris defines _LITTLE_ENDIAN and _BIG_ENDIAN to 1 */ +# if (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN == 1) || \ + (defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__ == 1) +# define BYTE_ORDER LITTLE_ENDIAN +# elif (defined(_BIG_ENDIAN) && _BIG_ENDIAN == 1) || \ + (defined(__BIG_ENDIAN__) && __BIG_ENDIAN__ == 1) +# define BYTE_ORDER BIG_ENDIAN +# elif defined(__alpha__) || defined(__alpha) || defined(__amd64) || \ + defined(BIT_ZERO_ON_RIGHT) || defined(i386) || defined(__i386) || \ + defined(MIPSEL) || defined(_MIPSEL) || defined(ns32000) || \ + defined(__ns3200) || defined(sun386) || defined(vax) || \ + defined(__vax) || defined(__x86__) || \ + (defined(sun) && defined(__powerpc)) || \ + (!defined(__hpux) && defined(__ia64)) +# define BYTE_ORDER LITTLE_ENDIAN +# elif defined(__68k__) || defined(apollo) || defined(BIT_ZERO_ON_LEFT) || \ + defined(__convex__) || defined(_CRAY) || defined(DGUX) || \ + defined(__hppa) || defined(__hp9000) || defined(__hp9000s300) || \ + defined(__hp9000s700) || defined(__hp3000s900) || \ + defined(ibm032) || defined(ibm370) || defined(_IBMR2) || \ + defined(is68k) || defined(mc68000) || defined(m68k) || \ + defined(__m68k) || defined(m88k) || defined(__m88k) || \ + defined(MIPSEB) || defined(_MIPSEB) || defined(MPE) || \ + defined(pyr) || defined(__powerpc) || defined(__powerpc__) || \ + defined(sel) || defined(__sparc) || defined(__sparc__) || \ + defined(tahoe) || (defined(__hpux) && defined(__ia64)) || \ + (defined(sun) && defined(__powerpc)) +# define BYTE_ORDER BIG_ENDIAN +# else +# define BYTE_ORDER UNKNOWN_ENDIAN +# endif +#endif /* BYTE_ORDER */ + +#endif /* _COMPAT_ENDIAN_H */ diff --git a/config.h.in b/config.h.in index 2f7855185..5b0ded496 100644 --- a/config.h.in +++ b/config.h.in @@ -134,6 +134,9 @@ /* Define to 1 if the compiler supports the __visibility__ attribute. */ #undef HAVE_DSO_VISIBILITY +/* Define to 1 if you have the header file. */ +#undef HAVE_ENDIAN_H + /* Define to 1 if your system has the F_CLOSEM fcntl. */ #undef HAVE_FCNTL_CLOSEM @@ -352,6 +355,9 @@ /* Define to 1 if you have the `lrand48' function. */ #undef HAVE_LRAND48 +/* Define to 1 if you have the header file. */ +#undef HAVE_MACHINE_ENDIAN_H + /* Define to 1 if you have the header file. */ #undef HAVE_MAILLOCK_H @@ -639,6 +645,9 @@ */ #undef HAVE_SYS_DIR_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_ENDIAN_H + /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H diff --git a/configure b/configure index e12d8ab21..9559831d1 100755 --- a/configure +++ b/configure @@ -15509,6 +15509,19 @@ fi done +for ac_header in endian.h sys/endian.h machine/endian.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + break +fi + +done + for ac_header in procfs.h sys/procfs.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` diff --git a/configure.in b/configure.in index aea690e6a..d7c79d7b8 100644 --- a/configure.in +++ b/configure.in @@ -2093,6 +2093,7 @@ 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([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 #include diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in index 63bc6be52..49c3500e9 100644 --- a/plugins/sudoers/Makefile.in +++ b/plugins/sudoers/Makefile.in @@ -483,7 +483,7 @@ check_addr.o: $(srcdir)/regress/parser/check_addr.c $(top_builddir)/config.h \ $(srcdir)/interfaces.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/parser/check_addr.c check_digest.o: $(srcdir)/regress/parser/check_digest.c \ - $(top_builddir)/config.h $(srcdir)/sha2.h + $(top_builddir)/config.h $(incdir)/missing.h $(srcdir)/sha2.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/parser/check_digest.c check_fill.o: $(srcdir)/regress/parser/check_fill.c $(top_builddir)/config.h \ $(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \ @@ -771,7 +771,8 @@ set_perms.lo: $(srcdir)/set_perms.c $(top_builddir)/config.h \ $(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \ $(incdir)/sudo_debug.h $(incdir)/gettext.h $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/set_perms.c -sha2.lo: $(srcdir)/sha2.c $(top_builddir)/config.h $(srcdir)/sha2.h +sha2.lo: $(srcdir)/sha2.c $(top_builddir)/config.h \ + $(top_srcdir)/compat/endian.h $(srcdir)/sha2.h $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sha2.c sha2.o: sha2.lo sia.lo: $(authdir)/sia.c $(top_builddir)/config.h $(srcdir)/sudoers.h \ diff --git a/plugins/sudoers/sha2.c b/plugins/sudoers/sha2.c index 896ca273e..74ede4099 100644 --- a/plugins/sudoers/sha2.c +++ b/plugins/sudoers/sha2.c @@ -48,6 +48,15 @@ #elif defined(HAVE_INTTYPES_H) # include #endif +#if defined(HAVE_ENDIAN_H) +# include +#elif defined(HAVE_SYS_ENDIAN_H) +# include +#elif defined(HAVE_MACHINE_ENDIAN_H) +# include +#else +# include "compat/endian.h" +#endif #include "sha2.h" @@ -147,10 +156,14 @@ SHA224Final(uint8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *ctx) { SHA256Pad(ctx); if (digest != NULL) { +#if BYTE_ORDER == BIG_ENDIAN + memcpy(digest, ctx->state.st32, SHA224_DIGEST_LENGTH); +#else unsigned int i; for (i = 0; i < 7; i++) BE32TO8(digest + (i * 4), ctx->state.st32[i]); +#endif memset(ctx, 0, sizeof(*ctx)); } } @@ -210,10 +223,14 @@ SHA256Transform(uint32_t state[8], const uint8_t data[SHA256_BLOCK_LENGTH]) /* Copy context state to working vars. */ memcpy(T, state, sizeof(T)); /* Copy data to W in big endian format. */ +#if BYTE_ORDER == BIG_ENDIAN + memcpy(W, data, sizeof(W)); +#else for (j = 0; j < 16; j++) { BE8TO32(W[j], data); data += 4; } +#endif /* 64 operations, partially loop unrolled. */ for (j = 0; j < 64; j += 16) { @@ -283,10 +300,14 @@ SHA256Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *ctx) { SHA256Pad(ctx); if (digest != NULL) { +#if BYTE_ORDER == BIG_ENDIAN + memcpy(digest, ctx->state.st32, SHA256_DIGEST_LENGTH); +#else unsigned int i; for (i = 0; i < 8; i++) BE32TO8(digest + (i * 4), ctx->state.st32[i]); +#endif memset(ctx, 0, sizeof(*ctx)); } } @@ -328,10 +349,14 @@ SHA384Final(uint8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *ctx) { SHA384Pad(ctx); if (digest != NULL) { +#if BYTE_ORDER == BIG_ENDIAN + memcpy(digest, ctx->state.st64, SHA384_DIGEST_LENGTH); +#else unsigned int i; for (i = 0; i < 6; i++) BE64TO8(digest + (i * 8), ctx->state.st64[i]); +#endif memset(ctx, 0, sizeof(*ctx)); } } @@ -415,10 +440,14 @@ SHA512Transform(uint64_t state[8], const uint8_t data[SHA512_BLOCK_LENGTH]) /* Copy context state to working vars. */ memcpy(T, state, sizeof(T)); /* Copy data to W in big endian format. */ +#if BYTE_ORDER == BIG_ENDIAN + memcpy(W, data, sizeof(W)); +#else for (j = 0; j < 16; j++) { BE8TO64(W[j], data); data += 8; } +#endif /* 80 operations, partially loop unrolled. */ for (j = 0; j < 80; j += 16) { @@ -485,10 +514,14 @@ SHA512Final(uint8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *ctx) { SHA512Pad(ctx); if (digest != NULL) { +#if BYTE_ORDER == BIG_ENDIAN + memcpy(digest, ctx->state.st64, SHA512_DIGEST_LENGTH); +#else unsigned int i; for (i = 0; i < 8; i++) BE64TO8(digest + (i * 8), ctx->state.st64[i]); +#endif memset(ctx, 0, sizeof(*ctx)); } }