Fix issue with pid://../run/foo..pid parser

Unfortunately we cannot use realpath(3) here since the the PID files
usually do not yet exist at this point.

Add and modify my ugly de_dotdot() from Merecat httpd.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2023-02-05 18:16:27 +01:00
parent a67b2ba9a7
commit 82c6e4680f
5 changed files with 52 additions and 6 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
* TODO fix pid parser, //run/foo.pid -> /var/run///run/foo.pid
* DONE fix pid parser, //run/foo.pid -> /var/run///run/foo.pid
** DONE test framework refactor 'texec sh -c ...' -> 'run ...'
* TODO Clean up tests a bit
* TODO Drop tenv or common and rename tenv-root
+5 -1
View File
@@ -149,6 +149,8 @@ int pid_file_create(svc_t *svc)
int pid_file_set(svc_t *svc, char *file, int not)
{
char buf[sizeof(svc->pidfile)];
if (!file) {
file = pid_file(svc);
if (!file)
@@ -165,7 +167,9 @@ int pid_file_set(svc_t *svc, char *file, int not)
not = 1;
}
pid_runpath(file, &svc->pidfile[not], sizeof(svc->pidfile) - not);
de_dotdot(file);
pid_runpath(file, buf, sizeof(buf));
strlcpy(&svc->pidfile[not], buf, sizeof(svc->pidfile) - not);
if (not)
svc->pidfile[0] = '!';
+4 -4
View File
@@ -51,6 +51,7 @@ static inline char *pid_runpath(const char *file, char *path, size_t len)
{
static char *prefix = "/var/run";
static int unknown = 1;
char *ptr;
int rc;
if (unknown) {
@@ -59,10 +60,9 @@ static inline char *pid_runpath(const char *file, char *path, size_t len)
unknown = 0;
}
if (!strncmp(file, "/var/run/", 9))
file += 9;
else if (!strncmp(file, "/run/", 5))
file += 5;
ptr = strstr(file, "/run/");
if (ptr)
file = ptr + 5;
rc = paste(path, len, prefix, file);
if (rc < 0 || (size_t)rc >= len)
+41
View File
@@ -467,6 +467,47 @@ char *sanitize(char *arg, size_t len)
return arg;
}
void de_dotdot(char *file)
{
char *cp, *cp2;
int l;
/* Remove leading ./ and any /./ sequences. */
while (strncmp(file, "./", 2) == 0)
memmove(file, file + 2, strlen(file) - 1);
while ((cp = strstr(file, "/./")))
memmove(cp, cp + 2, strlen(cp) - 1);
/* Alternate between removing leading ../ and removing xxx/../ */
for (;;) {
while (strncmp(file, "../", 3) == 0)
memmove(file, file + 3, strlen(file) - 2);
cp = strstr(file, "/../");
if (!cp)
break;
for (cp2 = cp - 1; cp2 >= file && *cp2 != '/'; --cp2)
continue;
memmove(cp2 + 1, cp + 4, strlen(cp + 3));
}
/* Also elide any xxx/.. at the end. */
while ((l = strlen(file)) > 3 && strcmp((cp = file + l - 3), "/..") == 0) {
for (cp2 = cp - 1; cp2 >= file && *cp2 != '/'; --cp2)
continue;
if (cp2 < file)
break;
*cp2 = '\0';
}
/* Collapse any multiple / sequences. */
while ((cp = strstr(file, "//"))) {
cp2 = cp + 1;
memmove(cp, cp2, strlen(cp2) + 1);
}
}
static int hasopt(char *opts, char *opt)
{
char buf[strlen(opts) + 1];
+1
View File
@@ -72,6 +72,7 @@ char *uptime (long secs, char *buf, size_t len);
char *memsz (uint64_t sz, char *buf, size_t len);
char *sanitize (char *arg, size_t len);
void de_dotdot (char *file);
int ismnt (char *file, char *dir, char *mode);
int fismnt (char *dir);