From 941a2d85aa6404dba0bbb0e2093407a3b5c1c5e2 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 30 Apr 2023 19:49:27 +0200 Subject: [PATCH] src/confd: system() replacement without /bin/sh intermediary Signed-off-by: Joachim Wiberg --- src/confd/src/Makefile.am | 2 +- src/confd/src/systemv.c | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/confd/src/systemv.c diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index fa985c4b..ac96e2ff 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -8,4 +8,4 @@ confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(libite_CFLAGS) $(sysrepo_CFLAGS) $( confd_plugin_la_LIBADD = $(augeas_LIBS) $(libite_LIBS) $(sysrepo_LIBS) confd_plugin_la_LDFLAGS = -module -avoid-version -shared confd_plugin_la_SOURCES = core.c core.h helpers.c helpers.h srx_module.c srx_module.h srx_val.c srx_val.h \ - ietf-system.c ietf-interfaces.c + ietf-system.c ietf-interfaces.c systemv.c diff --git a/src/confd/src/systemv.c b/src/confd/src/systemv.c new file mode 100644 index 00000000..7c213d26 --- /dev/null +++ b/src/confd/src/systemv.c @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include +#include +#include /* strerror() */ +#include +#include +#include +#include + +/** + * Reimplementation of system() without /bin/sh intermediary + */ +int fsystemv(char **args, FILE *in, FILE *out, FILE *err) +{ + struct sigaction sa = { .sa_handler = SIG_IGN }; + sigset_t oldmask; + int rc = -1; + pid_t pid; + + if (!args) { + errno = EINVAL; + return -1; + } + + /* Wait for last child to terminate, see waitpid(2) */ + sigaddset(&sa.sa_mask, SIGCHLD); + sigprocmask(SIG_BLOCK, &sa.sa_mask, &oldmask); + + pid = fork(); + if (0 == pid) { + sigprocmask(SIG_SETMASK, &oldmask, NULL); + + if (in) + dup2(fileno(in), STDIN_FILENO); + if (out) + dup2(fileno(out), STDOUT_FILENO); + if (err) + dup2(fileno(err), STDERR_FILENO); + + _exit(execvp(args[0], args)); + } + if (pid == -1 || waitpid(pid, &rc, 0) == -1) + goto fail; + + if (WIFEXITED(rc)) { + errno = 0; + rc = WEXITSTATUS(rc); + } else if (WIFSIGNALED(rc)) { + errno = EINTR; + rc = -1; + } +fail: + sigprocmask(SIG_SETMASK, &oldmask, NULL); + return rc; +} + +int systemv(char **args) +{ + return fsystemv(args, NULL, NULL, NULL); +} + +int systemv_silent(char **args) +{ + FILE *out = fopen("/dev/null", "w"); + int rc; + + rc = fsystemv(args, NULL, out, out); + if (out) + fclose(out); + + return rc; +} + +#ifdef UNITTEST +int main(void) +{ + char *args[] = { + "ls", "/etc", NULL + }; + int rc; + + rc = systemv_silent(args); + printf("=> %d\n", rc); +} +#endif