]> granicus.if.org Git - sudo/commitdiff
When waiting for the parent to grant us the tty, use nanosleep
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 12 Jan 2017 17:44:26 +0000 (10:44 -0700)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 12 Jan 2017 17:44:26 +0000 (10:44 -0700)
instead of spinning to avoid hogging the CPU.

MANIFEST
config.h.in
configure
configure.ac
include/sudo_compat.h
lib/util/Makefile.in
lib/util/nanosleep.c [new file with mode: 0644]
mkdep.pl
src/exec_pty.c

index db59f42928e74f49cb6fa0648682bde2927302ca..ea8f458b16ed5e043dccb7e5fc4ee7d92253d9df 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -107,6 +107,7 @@ lib/util/mksiglist.h
 lib/util/mksigname.c
 lib/util/mksigname.h
 lib/util/mktemp.c
+lib/util/nanosleep.c
 lib/util/parseln.c
 lib/util/progname.c
 lib/util/pw_dup.c
index 61462e4b595ca8ec665767f5c1efbf90105fbd28..14275b252a08d5e6a35c8586a86a46bd108edd6e 100644 (file)
 /* Define to 1 if you have the <mps/ldap_ssl.h> header file. */
 #undef HAVE_MPS_LDAP_SSL_H
 
+/* Define to 1 if you have the `nanosleep' function. */
+#undef HAVE_NANOSLEEP
+
 /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
 #undef HAVE_NDIR_H
 
index ae14da3068cddbe164e14b0c21862aeb61f61cc8..892fc28d7d5af2851fec4ab28ecf3a63b5e91af7 100755 (executable)
--- a/configure
+++ b/configure
@@ -19688,6 +19688,68 @@ esac
     done
 
 
+fi
+done
+
+for ac_func in nanosleep
+do :
+  ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep"
+if test "x$ac_cv_func_nanosleep" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_NANOSLEEP 1
+_ACEOF
+
+else
+
+    # On Solaris, nanosleep is in librt
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5
+$as_echo_n "checking for nanosleep in -lrt... " >&6; }
+if ${ac_cv_lib_rt_nanosleep+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char nanosleep ();
+int
+main ()
+{
+return nanosleep ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_rt_nanosleep=yes
+else
+  ac_cv_lib_rt_nanosleep=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5
+$as_echo "$ac_cv_lib_rt_nanosleep" >&6; }
+if test "x$ac_cv_lib_rt_nanosleep" = xyes; then :
+  REPLAY_LIBS="${REPLAY_LIBS} -lrt"
+else
+  case " $LIBOBJS " in
+  *" nanosleep.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS nanosleep.$ac_objext"
+ ;;
+esac
+
+fi
+
+
 fi
 done
 
index 9d09eea7d87bae98384e52a516d8ea001b799bfb..c3f85cad39d4a573628ebc275c791bdc90ba3dc2 100644 (file)
@@ -1,7 +1,7 @@
 dnl
 dnl Use the top-level autogen.sh script to generate configure and config.h.in
 dnl
-dnl Copyright (c) 1994-1996,1998-2016 Todd C. Miller <Todd.Miller@courtesan.com>
+dnl Copyright (c) 1994-1996,1998-2017 Todd C. Miller <Todd.Miller@courtesan.com>
 dnl
 AC_PREREQ([2.59])
 AC_INIT([sudo], [1.8.19p1], [https://bugzilla.sudo.ws/], [sudo])
@@ -2578,6 +2578,10 @@ AC_CHECK_FUNCS([memset_s], [], [
     AC_LIBOBJ(memset_s)
     SUDO_APPEND_COMPAT_EXP(sudo_memset_s)
 ])
+AC_CHECK_FUNCS(nanosleep, [], [
+    # On Solaris, nanosleep is in librt
+    AC_CHECK_LIB(rt, nanosleep, [REPLAY_LIBS="${REPLAY_LIBS} -lrt"], [AC_LIBOBJ(nanosleep)])
+])
 AC_CHECK_FUNCS([pw_dup], [], [
     AC_LIBOBJ(pw_dup)
     SUDO_APPEND_COMPAT_EXP(sudo_pw_dup)
index 3642a3465d5d48ef038cd2d4404524afe332ba6b..311c4440a395939b7651c4425f0cff1ac50a49bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2008, 2009-2016
+ * Copyright (c) 1996, 1998-2005, 2008, 2009-2017
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
 #undef ISSET
 #define ISSET(t, f)     ((t) & (f))
 
+/*
+ * Some systems define this in <sys/param.h> but we don't include that anymore.
+ */
+#ifndef howmany
+# define howmany(x, y) (((x) + ((y) - 1)) / (y))
+#endif
+
 /*
  * Simple isblank() macro and function for systems without it.
  */
@@ -468,6 +475,11 @@ __dso_public int sudo_mkstemps(char *path, int slen);
 # undef mkstemps
 # define mkstemps(_a, _b) sudo_mkstemps((_a), (_b))
 #endif /* !HAVE_MKDTEMP || !HAVE_MKSTEMPS */
+#ifndef HAVE_NANOSLEEP
+__dso_public int sudo_nanosleep(const struct timespec *timeout, struct timespec *remainder);
+#undef nanosleep
+# define nanosleep(_a, _b) sudo_nanosleep((_a), (_b))
+#endif
 #ifndef HAVE_PW_DUP
 __dso_public struct passwd *sudo_pw_dup(const struct passwd *pw);
 # undef pw_dup
index eb3ebdb7dd00103684288b18249e244106aabd08..3eecc241049bc748ce8cba3d71ba7a9a7f2f708d 100644 (file)
@@ -463,6 +463,10 @@ mktemp_test.lo: $(srcdir)/regress/mktemp/mktemp_test.c \
                 $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
                 $(top_builddir)/config.h
        $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/mktemp/mktemp_test.c
+nanosleep.lo: $(srcdir)/nanosleep.c $(incdir)/compat/stdbool.h \
+              $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+              $(top_builddir)/config.h
+       $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/nanosleep.c
 parse_gids_test.lo: $(srcdir)/regress/parse_gids/parse_gids_test.c \
                     $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
                     $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
diff --git a/lib/util/nanosleep.c b/lib/util/nanosleep.c
new file mode 100644 (file)
index 0000000..02fb561
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009-2011, 2013, 2017 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
+ * 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 <config.h>
+
+#ifndef HAVE_NANOSLEEP
+
+#include <sys/types.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+#if TIME_WITH_SYS_TIME
+# include <time.h>
+#endif
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+int
+sudo_nanosleep(const struct timespec *ts, struct timespec *rts)
+{
+    struct timeval timeout, endtime, now;
+    int rval;
+
+    if (ts->tv_sec == 0 && ts->tv_nsec < 1000) {
+       timeout.tv_sec = 0;
+       timeout.tv_usec = 1;
+    } else {
+       TIMESPEC_TO_TIMEVAL(&timeout, ts);
+    }
+    if (rts != NULL) {
+       if (gettimeofday(&endtime, NULL) == -1)
+           return -1;
+       sudo_timevaladd(&endtime, &timeout, &endtime);
+    }
+    rval = select(0, NULL, NULL, NULL, &timeout);
+    if (rts != NULL && rval == -1 && errno == EINTR) {
+       if (gettimeofday(&now, NULL) == -1)
+           return -1;
+       sudo_timevalsub(&endtime, &now, &endtime);
+       TIMEVAL_TO_TIMESPEC(&endtime, rts);
+    }
+    return rval;
+}
+#endif /* HAVE_NANOSLEEP */
index 6c8f55b47f5fd0d51f57fe2d6c2bb2a2d28c800a..5a83c7f9260b20b7cbbe4c77f981cf08e37ade3a 100755 (executable)
--- a/mkdep.pl
+++ b/mkdep.pl
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 #
-# Copyright (c) 2011-2014 Todd C. Miller <Todd.Miller@courtesan.com>
+# Copyright (c) 2011-2017 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
@@ -70,7 +70,7 @@ sub mkdep {
     $makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo solaris_audit.lo sssd.lo:;
     # XXX - fill in AUTH_OBJS from contents of the auth dir instead
     $makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
-    $makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo strtonum.lo utimens.lo vsyslog.lo:;
+    $makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo strtonum.lo utimens.lo vsyslog.lo:;
 
     # Parse OBJS lines
     my %objs;
index f317146bf84e02bf1e0b2c82ccad1166c4b0158a..7403506380730924bea51c3994a65b02bbfb39d0 100644 (file)
@@ -1556,8 +1556,9 @@ exec_pty(struct command_details *details,
 
     /* Wait for parent to grant us the tty if we are foreground. */
     if (foreground && !ISSET(details->flags, CD_EXEC_BG)) {
+       struct timespec ts = { 0, 1000 };  /* 1us */
        while (tcgetpgrp(io_fds[SFD_SLAVE]) != self)
-           continue; /* spin */
+           nanosleep(&ts, NULL);
     }
 
     /* We have guaranteed that the slave fd is > 2 */