summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rdate
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/rdate')
-rw-r--r--usr.sbin/rdate/rdate.c82
1 files changed, 69 insertions, 13 deletions
diff --git a/usr.sbin/rdate/rdate.c b/usr.sbin/rdate/rdate.c
index 363fc2a1cb6..5da04a596d6 100644
--- a/usr.sbin/rdate/rdate.c
+++ b/usr.sbin/rdate/rdate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rdate.c,v 1.32 2015/02/09 23:00:14 deraadt Exp $ */
+/* $OpenBSD: rdate.c,v 1.33 2015/10/29 03:16:15 deraadt Exp $ */
/* $NetBSD: rdate.c,v 1.4 1996/03/16 12:37:45 pk Exp $ */
/*
@@ -40,6 +40,7 @@
#include <sys/socket.h>
#include <sys/time.h>
+#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
@@ -62,6 +63,12 @@ void ntp_client(const char *, int, struct timeval *, struct timeval *, int);
extern char *__progname;
__dead void usage(void);
+struct {
+ char message[256];
+ struct timeval new;
+ struct timeval adjust;
+} pdata;
+
__dead void
usage(void)
{
@@ -76,11 +83,9 @@ main(int argc, char **argv)
int slidetime = 0, corrleaps = 0;
char *hname;
extern int optind;
- int c;
+ int c, p[2], pid;
int family = PF_UNSPEC;
- struct timeval new, adjust;
-
while ((c = getopt(argc, argv, "46psanocv")) != -1) {
switch (c) {
case '4':
@@ -127,34 +132,85 @@ main(int argc, char **argv)
usage();
hname = argv[optind];
- if (ntp)
- ntp_client(hname, family, &new, &adjust, corrleaps);
- else
- rfc868time_client(hname, family, &new, &adjust, corrleaps);
+ /*
+ * Privilege separation increases safety, with a slight reduction
+ * in precision because the time values have to return over a pipe.
+ */
+ if (pipe(p) == -1)
+ err(1, "pipe");
+ switch ((pid = fork())) {
+ case -1:
+ err(1, "fork");
+ break;
+ case 0:
+ if (pledge("stdio inet dns", NULL) == -1)
+ err(1, "fork");
+
+ close(p[0]); /* read side of pipe */
+ dup2(p[1], STDIN_FILENO);
+ if (p[1] != STDIN_FILENO)
+ close(p[1]);
+ dup2(STDIN_FILENO, STDOUT_FILENO);
+ dup2(STDOUT_FILENO, STDERR_FILENO);
+ setvbuf(stdout, NULL, _IOFBF, 0);
+ setvbuf(stderr, NULL, _IOFBF, 0);
+
+ if (ntp)
+ ntp_client(hname, family, &pdata.new,
+ &pdata.adjust, corrleaps);
+ else
+ rfc868time_client(hname, family, &pdata.new,
+ &pdata.adjust, corrleaps);
+
+ if (write(STDOUT_FILENO, &pdata, sizeof pdata) != sizeof pdata)
+ exit(1);
+ exit(0);
+ }
+
+ if (pledge("stdio rpath wpath settime", NULL) == -1)
+ err(1, "pledge");
+
+ close(p[1]); /* write side of pipe */
+ if (read(p[0], &pdata, sizeof pdata) < 1)
+ err(1, "child did not collect time");
+ if (waitpid(pid, NULL, 0) == -1)
+ err(1, "waitpid");
+
+ /*
+ * A viable timestamp from the child contains no message.
+ */
+ if (pdata.message[0]) {
+ pdata.message[sizeof(pdata.message)- 1] = '\0';
+ write(STDERR_FILENO, pdata.message, strlen(pdata.message));
+ exit(1);
+ }
if (!pr) {
if (!slidetime) {
logwtmp("|", "date", "");
- if (settimeofday(&new, NULL) == -1)
+ if (settimeofday(&pdata.new, NULL) == -1)
err(1, "Could not set time of day");
logwtmp("{", "date", "");
} else {
- if (adjtime(&adjust, NULL) == -1)
+ if (adjtime(&pdata.adjust, NULL) == -1)
err(1, "Could not adjust time of day");
}
}
+ if (pledge("stdio rpath", NULL) == -1)
+ err(1, "pledge");
+
if (!silent) {
struct tm *ltm;
char buf[80];
- time_t tim = new.tv_sec;
+ time_t tim = pdata.new.tv_sec;
double adjsec;
ltm = localtime(&tim);
(void) strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y\n", ltm);
(void) fputs(buf, stdout);
- adjsec = adjust.tv_sec + adjust.tv_usec / 1.0e6;
+ adjsec = pdata.adjust.tv_sec + pdata.adjust.tv_usec / 1.0e6;
if (slidetime || verbose) {
if (ntp)
@@ -164,7 +220,7 @@ main(int argc, char **argv)
else
(void) fprintf(stdout,
"%s: adjust local clock by %lld seconds\n",
- __progname, (long long)adjust.tv_sec);
+ __progname, (long long)pdata.adjust.tv_sec);
}
}