conf: escape runtime strings in generated .conf files

The runparts directory and the dbus pidfile and daemon paths are
embedded in double-quoted values of the generated block files.  A
literal quote in either ends the value early and libconfuse rejects
the whole file, and a backslash is read as an escape sequence,
silently mangling the path.  The legacy one-liners had no quoting, so
neither failure existed before the block conversion.

conf_escape() doubles backslashes and escapes quotes; verified by
round-tripping hostile paths through cfg_parse_buf().

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2026-08-01 11:25:40 +02:00
1 parent 2c6547635a
commit 1099d663ab
3 files changed
+29 -3

No files matched your search

+6 -2
View File
@@ -100,6 +100,7 @@ static void setup(void *arg)
{
char *group = DBUS_DAEMONGROUP;
char *user = DBUS_DAEMONUSER;
char esccmd[256];
char pid[300];
char *pidfn;
mode_t prev;
@@ -153,7 +154,10 @@ static void setup(void *arg)
*/
pid[0] = 0;
if (pidfn) {
snprintf(pid, sizeof(pid), "\tpidfile = \"%s\"\n", pidfn);
char esc[280];
snprintf(pid, sizeof(pid), "\tpidfile = \"%s\"\n",
conf_escape(pidfn, esc, sizeof(esc)));
free(pidfn);
}
conf_save_service(SVC_TYPE_SERVICE, "dbus", "dbus.conf",
@@ -163,7 +167,7 @@ static void setup(void *arg)
"\tcgroup system {}\n"
"%s"
"\tcommand = \"%s " DBUS_ARGS "\"\n",
pid, cmd);
pid, conf_escape(cmd, esccmd, sizeof(esccmd)));
free(cmd);
}
+22 -1
View File
@@ -664,6 +664,25 @@ done:
fclose(fp);
}
/*
* Escape backslash and double quote so a runtime string can sit in a
* double-quoted .conf value. Truncates to fit @buf, always returns a
* terminated string.
*/
char *conf_escape(const char *str, char *buf, size_t len)
{
size_t i = 0;
while (*str && i + 2 < len) {
if (*str == '"' || *str == '\\')
buf[i++] = '\\';
buf[i++] = *str++;
}
buf[i] = 0;
return buf;
}
/*
* Called by plugins and similar that dynamically generate system
* services. @body holds the block contents, one indented line per
@@ -2565,6 +2584,7 @@ int conf_init(uev_ctx_t *ctx)
*/
if (runparts && fisdir(runparts) && !rescue) {
char args[10] = { 0 };
char dir[256];
if (debug)
strlcat(args, "-d ", sizeof(args));
@@ -2573,6 +2593,7 @@ int conf_init(uev_ctx_t *ctx)
if (runparts_sysv)
strlcat(args, "-s ", sizeof(args));
conf_escape(runparts, dir, sizeof(dir));
conf_save_service(SVC_TYPE_TASK, "runparts", "runparts.conf",
"\tdescription = \"Calling runparts %s in the background\"\n"
"\trunlevel = \"S\"\n"
@@ -2580,7 +2601,7 @@ int conf_init(uev_ctx_t *ctx)
"\tnotify = \"none\"\n"
"\tlog { file = \"/dev/console\" }\n"
"\tcommand = \"%s %s%s\"\n",
runparts, _PATH_RUNPARTS, args, runparts);
dir, _PATH_RUNPARTS, args, dir);
}
return 0;
+1
View File
@@ -71,6 +71,7 @@ int conf_monitor (void);
void conf_saverc (void);
void conf_save_exec_order (svc_t *svc, char *cmdline, int result);
char *conf_escape (const char *str, char *buf, size_t len);
void conf_save_service (int type, const char *name, char *file, const char *fmt, ...)
__attribute__ ((format (printf, 4, 5)));
void conf_parse_cmdline (int argc, char *argv[]);