mirror of
https://github.com/troglobit/finit.git
synced 2026-10-17 10:49:34 +00:00
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:
3 files changed
+29
-3
No files matched your search
+6
-2
@@ -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
@@ -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;
|
||||
|
||||
@@ -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[]);
|
||||
|
||||
Reference in new issue
Block a user