Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Sep 2019 14:06:16 -0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r345738 - in stable/12/lib/libutil: . tests
Message-ID:  <201903301742.x2UHgRZr032904@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Sat Mar 30 17:42:27 2019
New Revision: 345738
URL: https://svnweb.freebsd.org/changeset/base/345738

Log:
  MFC r345596:
  Fix pidfile_open(3) to handle relative paths with multiple components.

Modified:
  stable/12/lib/libutil/pidfile.c
  stable/12/lib/libutil/tests/pidfile_test.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/lib/libutil/pidfile.c
==============================================================================
--- stable/12/lib/libutil/pidfile.c	Sat Mar 30 17:24:56 2019	(r345737)
+++ stable/12/lib/libutil/pidfile.c	Sat Mar 30 17:42:27 2019	(r345738)
@@ -100,8 +100,9 @@ pidfile_read(int dirfd, const char *filename, pid_t *p
 }
 
 struct pidfh *
-pidfile_open(const char *path, mode_t mode, pid_t *pidptr)
+pidfile_open(const char *pathp, mode_t mode, pid_t *pidptr)
 {
+	char path[MAXPATHLEN];
 	struct pidfh *pfh;
 	struct stat sb;
 	int error, fd, dirfd, dirlen, filenamelen, count;
@@ -112,19 +113,22 @@ pidfile_open(const char *path, mode_t mode, pid_t *pid
 	if (pfh == NULL)
 		return (NULL);
 
-	if (path == NULL) {
+	if (pathp == NULL) {
 		dirlen = snprintf(pfh->pf_dir, sizeof(pfh->pf_dir),
 		    "/var/run/");
 		filenamelen = snprintf(pfh->pf_filename,
 		    sizeof(pfh->pf_filename), "%s.pid", getprogname());
 	} else {
-		dirlen = snprintf(pfh->pf_dir, sizeof(pfh->pf_dir),
-		    "%s", path);
-		filenamelen = snprintf(pfh->pf_filename,
-		    sizeof(pfh->pf_filename), "%s", path);
-
-		dirname(pfh->pf_dir);
-		basename(pfh->pf_filename);
+		if (strlcpy(path, pathp, sizeof(path)) >= sizeof(path)) {
+			free(pfh);
+			errno = ENAMETOOLONG;
+			return (NULL);
+		}
+		dirlen = strlcpy(pfh->pf_dir, dirname(path),
+		    sizeof(pfh->pf_dir));
+		(void)strlcpy(path, pathp, sizeof(path));
+		filenamelen = strlcpy(pfh->pf_filename, basename(path),
+		    sizeof(pfh->pf_filename));
 	}
 
 	if (dirlen >= (int)sizeof(pfh->pf_dir) ||

Modified: stable/12/lib/libutil/tests/pidfile_test.c
==============================================================================
--- stable/12/lib/libutil/tests/pidfile_test.c	Sat Mar 30 17:24:56 2019	(r345737)
+++ stable/12/lib/libutil/tests/pidfile_test.c	Sat Mar 30 17:42:27 2019	(r345738)
@@ -263,6 +263,40 @@ test_pidfile_inherited(void)
 	return (result);
 }
 
+/*
+ * Make sure we handle relative pidfile paths correctly.
+ */
+static const char *
+test_pidfile_relative(void)
+{
+	char path[PATH_MAX], pid[32], tmpdir[PATH_MAX];
+	struct pidfh *pfh;
+	int fd;
+
+	(void)snprintf(tmpdir, sizeof(tmpdir), "%s.XXXXXX", __func__);
+	if (mkdtemp(tmpdir) == NULL)
+		return (strerror(errno));
+	(void)snprintf(path, sizeof(path), "%s/pidfile", tmpdir);
+
+	pfh = pidfile_open(path, 0600, NULL);
+	if (pfh == NULL)
+		return (strerror(errno));
+	if (pidfile_write(pfh) != 0)
+		return (strerror(errno));
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return (strerror(errno));
+	if (read(fd, pid, sizeof(pid)) < 0)
+		return (strerror(errno));
+	if (atoi(pid) != getpid())
+		return ("pid mismatch");
+	if (close(fd) != 0)
+		return (strerror(errno));
+	if (pidfile_close(pfh) != 0)
+		return (strerror(errno));
+	return (NULL);
+}
+
 static struct test {
 	const char *name;
 	const char *(*func)(void);
@@ -271,6 +305,7 @@ static struct test {
 	{ "pidfile_self", test_pidfile_self },
 	{ "pidfile_contested", test_pidfile_contested },
 	{ "pidfile_inherited", test_pidfile_inherited },
+	{ "pidfile_relative", test_pidfile_relative },
 };
 
 int





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201903301742.x2UHgRZr032904>