svc.[ch]: Fix possible out of bounds and NULL ptr deref

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2014-04-12 16:41:20 +02:00
1 parent 1095724e5c
commit 71fff76111
2 files changed
+19 -18

No files matched your search

+17 -16
View File
@@ -133,11 +133,11 @@ svc_t *svc_iterator(int restart)
void svc_bootstrap(void) void svc_bootstrap(void)
{ {
svc_t *svc; svc_t *svc;
svc_cmd_t cmd;
_d("Bootstrapping all services in runlevel S from %s", FINIT_CONF); _d("Bootstrapping all services in runlevel S from %s", FINIT_CONF);
for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) { for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
cmd = svc_enabled(svc, 0, NULL); svc_cmd_t cmd = svc_enabled(svc, 0, NULL);
if (SVC_START == cmd || (SVC_RELOAD == cmd)) if (SVC_START == cmd || (SVC_RELOAD == cmd))
svc_start(svc); svc_start(svc);
} }
@@ -423,13 +423,13 @@ void svc_monitor(void)
/* Remember: svc_enabled() must be called before calling svc_start() */ /* Remember: svc_enabled() must be called before calling svc_start() */
int svc_start(svc_t *svc) int svc_start(svc_t *svc)
{ {
int respawn = svc->pid != 0; int respawn;
pid_t pid; pid_t pid;
sigset_t nmask, omask; sigset_t nmask, omask;
char *args[MAX_NUM_SVC_ARGS];
if (!svc) if (!svc)
return 0; return 0;
respawn = svc->pid != 0;
/* Don't try and start service if it doesn't exist. */ /* Don't try and start service if it doesn't exist. */
if (!fexist(svc->cmd)) { if (!fexist(svc->cmd)) {
@@ -451,24 +451,25 @@ int svc_start(svc_t *svc)
else if (!respawn) else if (!respawn)
print_desc("Starting ", svc->desc); print_desc("Starting ", svc->desc);
/* Block sigchild while forking. */ /* Block sigchild while forking. */
sigemptyset(&nmask); sigemptyset(&nmask);
sigaddset(&nmask, SIGCHLD); sigaddset(&nmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &nmask, &omask); sigprocmask(SIG_BLOCK, &nmask, &omask);
pid = fork(); pid = fork();
sigprocmask(SIG_SETMASK, &omask, NULL); sigprocmask(SIG_SETMASK, &omask, NULL);
if (pid == 0) { if (pid == 0) {
int i = 0; int i = 0;
int uid = getuser(svc->username); int uid = getuser(svc->username);
struct sigaction sa; struct sigaction sa;
char *args[MAX_NUM_SVC_ARGS];
sigemptyset(&nmask); sigemptyset(&nmask);
sigaddset(&nmask, SIGCHLD); sigaddset(&nmask, SIGCHLD);
sigprocmask(SIG_UNBLOCK, &nmask, NULL); sigprocmask(SIG_UNBLOCK, &nmask, NULL);
/* Reset signal handlers that were set by the parent process */ /* Reset signal handlers that were set by the parent process */
for (i = 1; i < NSIG; i++) for (i = 1; i < NSIG; i++)
DFLSIG(sa, i, 0); DFLSIG(sa, i, 0);
/* Set desired user */ /* Set desired user */
@@ -476,7 +477,7 @@ int svc_start(svc_t *svc)
setuid(uid); setuid(uid);
/* Serve copy of args to process in case it modifies them. */ /* Serve copy of args to process in case it modifies them. */
for (i = 0; svc->args[i][0] != 0 && i < MAX_NUM_SVC_ARGS; i++) for (i = 0; i < MAX_NUM_SVC_ARGS && svc->args[i][0] != 0; i++)
args[i] = svc->args[i]; args[i] = svc->args[i];
args[i] = NULL; args[i] = NULL;
@@ -490,7 +491,7 @@ int svc_start(svc_t *svc)
dup2(STDERR_FILENO, fd); dup2(STDERR_FILENO, fd);
} }
for (i = 0; args[i] && i < MAX_NUM_SVC_ARGS; i++) { for (i = 0; i < MAX_NUM_SVC_ARGS && args[i]; i++) {
char arg[MAX_ARG_LEN]; char arg[MAX_ARG_LEN];
snprintf(arg, sizeof(arg), "%s ", args[i]); snprintf(arg, sizeof(arg), "%s ", args[i]);
+2 -2
View File
@@ -81,11 +81,11 @@ typedef struct svc_map svc_map_t;
/* Put services array in shm */ /* Put services array in shm */
static inline svc_t *finit_svc_connect(void) static inline svc_t *finit_svc_connect(void)
{ {
const long ID = FINIT_SHM_ID;
static void *ptr = (void *)-1; static void *ptr = (void *)-1;
if ((void *)-1 == ptr) { if ((void *)-1 == ptr) {
ptr = shmat (shmget (ID, sizeof(svc_t) * MAX_NUM_SVC, 0600 | IPC_CREAT), NULL, 0); ptr = shmat (shmget (FINIT_SHM_ID, sizeof(svc_t) * MAX_NUM_SVC,
0600 | IPC_CREAT), NULL, 0);
if ((void *)-1 == ptr) if ((void *)-1 == ptr)
return NULL; return NULL;
} }