[gpsd] fix PPS without -N

Miroslav Lichvar mlichvar at fedoraproject.org
Tue Aug 23 12:09:56 UTC 2011


commit 3b8ff12d03f5ebe0fdcf4665a1345e5fe4a26bd4
Author: Miroslav Lichvar <mlichvar at redhat.com>
Date:   Mon Aug 22 17:15:15 2011 +0200

    fix PPS without -N

 gpsd-priv.patch |  193 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gpsd.spec       |    2 +
 2 files changed, 195 insertions(+), 0 deletions(-)
---
diff --git a/gpsd-priv.patch b/gpsd-priv.patch
new file mode 100644
index 0000000..8d3afe7
--- /dev/null
+++ b/gpsd-priv.patch
@@ -0,0 +1,193 @@
+commit 76fbaa2fd53baf74cccc1fb03c68f731672bc921
+Author: Eric S. Raymond <esr at 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 at 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 at 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 at 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 at 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)
diff --git a/gpsd.spec b/gpsd.spec
index 7436064..473f3c0 100644
--- a/gpsd.spec
+++ b/gpsd.spec
@@ -12,6 +12,7 @@ Source11: gpsd.sysconfig
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 # fix RPATH, CFLAGS and revision.h
 Patch0:   gpsd-scons.patch
+Patch1:   gpsd-priv.patch
 
 BuildRequires: dbus-devel dbus-glib-devel ncurses-devel xmlto python-devel
 BuildRequires: scons desktop-file-utils bluez-libs-devel pps-tools-devel
@@ -73,6 +74,7 @@ can run on a serial terminal or terminal emulator.
 %prep
 %setup -q
 %patch0 -p1 -b .scons
+%patch1 -p1 -b .priv
 
 echo '#define REVISION "release-%{version}-%{release}"' > revision.h
 


More information about the scm-commits mailing list