gpsd/gpsd-priv.patch

194 lines
6.4 KiB
Diff
Raw Normal View History

2011-08-22 15:15:15 +00:00
commit 76fbaa2fd53baf74cccc1fb03c68f731672bc921
Author: Eric S. Raymond <esr@thyrsus.com>
Date: Fri Aug 19 04:04:42 2011 -0400
The -N option no longer drops privileges.
The price is that only devices specified on the gpsd commmand line will
do PPS, because the calls to set line discipline stop being available
after we drop privileges. In practice, this shouldn't be a problem,
as PPS devices ar RS232 ports that can't be hotplugged and thus *must*
be specified on the command line.
All regression tests pass.
diff --git a/NEWS b/NEWS
index 6090e43..473c68b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+* Fri Aug 19 2011 Eric S. Raymond <esr@snark.thyrsus.com> - 3.1~dev
+ Change -N semantics so it only suppresses backgrounding; privileges
+ are now dropped as in normal background operation.
+
* Fri Aug 19 2011 Eric S. Raymond <esr@snark.thyrsus.com> - 3.0
POLL subobject name changes: fixes -> tpv, skyview -> sky.
Fix a timestamp-clobbering bug in the C library revealed by an
diff --git a/gpsd.c b/gpsd.c
index d854567..177033c 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -1780,6 +1780,7 @@ int main(int argc, char *argv[])
bool go_background = true;
struct timeval tv;
const struct gps_type_t **dp;
+ bool in_restart;
#ifdef PPS_ENABLE
/*@-nullpass@*/
@@ -1989,16 +1990,22 @@ int main(int argc, char *argv[])
gpsd_report(LOG_PROG, "shared-segment creation succeeded,\n");
#endif /* SHM_EXPORT_ENABLE */
- /*
- * Drop privileges.
- *
- * Yes, the test for this is non-orthogonal and ugly. The problem
- * is that there is a line-discipline setup call in the PPS
- * support, way later on, that require root (see ntpshm.c and
- * look for "requires root"). We've overloaded -N with the meaning
- * "don't drop privileges" pending a better solution.
+ /*
+ * We open devices specified on the command line *before* dropping
+ * privileges in case one of them is a serial device with PPS support
+ * and we need to set the line discipline, which requires root.
*/
- if (getuid() == 0 && go_background) {
+ in_restart = false;
+ for (i = optind; i < argc; i++) {
+ if (!add_device(argv[i])) {
+ gpsd_report(LOG_ERROR,
+ "initial GPS device %s open failed\n",
+ argv[i]);
+ }
+ }
+
+ /* drop privileges */
+ if (getuid() == 0) {
struct passwd *pw;
struct stat stb;
@@ -2049,6 +2056,7 @@ int main(int argc, char *argv[])
if (allocated_device(&devices[dfd]))
(void)gpsd_wrap(&devices[dfd]);
}
+ in_restart = true;
gpsd_report(LOG_WARN, "gpsd restarted by SIGHUP\n");
}
@@ -2072,13 +2080,19 @@ int main(int argc, char *argv[])
/* initialize the GPS context's time fields */
gpsd_time_init(&context, time(NULL));
- for (i = optind; i < argc; i++) {
- if (!add_device(argv[i])) {
- gpsd_report(LOG_ERROR,
- "GPS device %s open failed\n",
- argv[i]);
+ /*
+ * If we got here via SIGINT, reopen any command-line devices. PPS
+ * through these won't work, as we've dropped privileges and can
+ * no longer change line disciplines.
+ */
+ if (in_restart)
+ for (i = optind; i < argc; i++) {
+ if (!add_device(argv[i])) {
+ gpsd_report(LOG_ERROR,
+ "GPS device %s open failed\n",
+ argv[i]);
+ }
}
- }
while (0 == signalled) {
(void)memcpy((char *)&rfds, (char *)&all_fds, sizeof(rfds));
diff --git a/gpsd.xml b/gpsd.xml
index d548372..1ecbfee 100644
--- a/gpsd.xml
+++ b/gpsd.xml
@@ -193,8 +193,8 @@ nonexistent in USB GPSes which lack a DTR line.)</para>
</varlistentry>
<varlistentry>
<term>-N</term>
-<listitem><para>Don't daemonize; run in foreground. Also suppresses
-privilege-dropping. This switch is mainly useful for debugging.</para>
+<listitem><para>Don't daemonize; run in foreground.
+This switch is mainly useful for debugging.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -795,6 +795,12 @@ supported.</para>
<para>The ISGPS used for RTCM2 and subframes decoder logic is
sufficiently convoluted to confuse some compiler optimizers, notably
in GCC 3.x at -O2, into generating bad code.</para>
+
+<para>Devices meant to to use PPS for high-precision timekeeping may
+fail if they are specifed after startup by a control-socket command,
+as opposed to on the daemon's original command line. (Root privileges
+are dropped early, and some Unix varients require them in order to set
+the PPS line discipline.)</para>
</refsect1>
<refsect1 id='files'><title>FILES</title>
commit a59c0026a531f338a1140c55a039792e31fd14e1
Author: Eric S. Raymond <esr@thyrsus.com>
Date: Mon Aug 22 14:44:10 2011 -0400
Try to open the right chrony socket...
...now that command-line devices are opened vefore privilege-dropping.
diff --git a/ntpshm.c b/ntpshm.c
index 0c43146..305df88 100644
--- a/ntpshm.c
+++ b/ntpshm.c
@@ -565,21 +565,15 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
char chrony_path[PATH_MAX];
gpsd_report(LOG_PROG, "PPS Create Thread gpsd_ppsmonitor\n");
- /* TODO the socket for root would be
- * /var/run/chrony.ttyXX.sock
- * for now it is always
- * /tmp/chrony.ttyXX.sock
- */
-#ifdef __UNUSED__
- /* sadly root was dropped very early, until a way if found to run this
- * before dropping root it will not work. */
- if( 0 == getuid() ) {
- /* only root can use /var/run */
+
+ if ( 0 == getuid() ) {
+ /* this case will fire on command-line devices;
+ * they're opened before priv-dropping. Matters because
+ * only root can use /var/run.
+ */
(void)snprintf(chrony_path, sizeof (chrony_path),
"/var/run/chrony.%s.sock", basename(session->gpsdata.dev.path));
- } else
-#endif
- {
+ } else {
(void)snprintf(chrony_path, sizeof (chrony_path),
"/tmp/chrony.%s.sock", basename(session->gpsdata.dev.path));
}
commit 056da4ced52bc009a5f5bbfaaae475076164cc61
Author: Gary E. Miller <gem@rellim.com>
Date: Mon Aug 22 15:19:25 2011 -0700
Fix typo in log message.
diff --git a/ntpshm.c b/ntpshm.c
index 305df88..74af002 100644
--- a/ntpshm.c
+++ b/ntpshm.c
@@ -579,7 +579,7 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
}
if (access(chrony_path, F_OK) != 0) {
- gpsd_report(LOG_PROG, "PPS chrony socket %s doesn't exist", chrony_path);
+ gpsd_report(LOG_PROG, "PPS chrony socket %s doesn't exist\n", chrony_path);
} else {
chronyfd = netlib_localsocket(chrony_path, SOCK_DGRAM);
if (chronyfd < 0)