summaryrefslogtreecommitdiff
path: root/src/lib/libc
diff options
context:
space:
mode:
authormillert <>2022-05-21 00:53:53 +0000
committermillert <>2022-05-21 00:53:53 +0000
commit8441124e76190c2ec4fcefa7dbcf7d58e9073703 (patch)
tree70c0e24d4949a08de861fac0155fae30208c3b6c /src/lib/libc
parentb5af5cafd4a1747b4045aad01cc9aad108dd4580 (diff)
downloadopenbsd-8441124e76190c2ec4fcefa7dbcf7d58e9073703.tar.gz
openbsd-8441124e76190c2ec4fcefa7dbcf7d58e9073703.tar.bz2
openbsd-8441124e76190c2ec4fcefa7dbcf7d58e9073703.zip
system(3) should ignore SIGINT and SIGQUIT until the shell exits.
This got broken when system.c was converted from signal(3) to sigaction(2). Also add SIGINT and SIGQUIT to the set of blocked signals and unblock them in the parent after the signal handlers are installed. Based on a diff from Leon Fischer. OK deraadt@
Diffstat (limited to 'src/lib/libc')
-rw-r--r--src/lib/libc/stdlib/system.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
index fe718276b9..28f01a9c5d 100644
--- a/src/lib/libc/stdlib/system.c
+++ b/src/lib/libc/stdlib/system.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: system.c,v 1.12 2016/03/13 18:34:21 guenther Exp $ */ 1/* $OpenBSD: system.c,v 1.13 2022/05/21 00:53:53 millert Exp $ */
2/* 2/*
3 * Copyright (c) 1988 The Regents of the University of California. 3 * Copyright (c) 1988 The Regents of the University of California.
4 * All rights reserved. 4 * All rights reserved.
@@ -33,6 +33,7 @@
33#include <errno.h> 33#include <errno.h>
34#include <signal.h> 34#include <signal.h>
35#include <stdlib.h> 35#include <stdlib.h>
36#include <string.h>
36#include <unistd.h> 37#include <unistd.h>
37#include <paths.h> 38#include <paths.h>
38 39
@@ -40,7 +41,7 @@ int
40system(const char *command) 41system(const char *command)
41{ 42{
42 pid_t pid, cpid; 43 pid_t pid, cpid;
43 struct sigaction intsave, quitsave; 44 struct sigaction intsave, quitsave, sa;
44 sigset_t mask, omask; 45 sigset_t mask, omask;
45 int pstat; 46 int pstat;
46 char *argp[] = {"sh", "-c", NULL, NULL}; 47 char *argp[] = {"sh", "-c", NULL, NULL};
@@ -52,6 +53,8 @@ system(const char *command)
52 53
53 sigemptyset(&mask); 54 sigemptyset(&mask);
54 sigaddset(&mask, SIGCHLD); 55 sigaddset(&mask, SIGCHLD);
56 sigaddset(&mask, SIGINT);
57 sigaddset(&mask, SIGQUIT);
55 sigprocmask(SIG_BLOCK, &mask, &omask); 58 sigprocmask(SIG_BLOCK, &mask, &omask);
56 switch (cpid = vfork()) { 59 switch (cpid = vfork()) {
57 case -1: /* error */ 60 case -1: /* error */
@@ -63,11 +66,21 @@ system(const char *command)
63 _exit(127); 66 _exit(127);
64 } 67 }
65 68
66 sigaction(SIGINT, NULL, &intsave); 69 /* Ignore SIGINT and SIGQUIT while waiting for command to complete. */
67 sigaction(SIGQUIT, NULL, &quitsave); 70 memset(&sa, 0, sizeof(sa));
71 sigemptyset(&sa.sa_mask);
72 sa.sa_handler = SIG_IGN;
73 sigaction(SIGINT, &sa, &intsave);
74 sigaction(SIGQUIT, &sa, &quitsave);
75 sigemptyset(&mask);
76 sigaddset(&mask, SIGINT);
77 sigaddset(&mask, SIGQUIT);
78 sigprocmask(SIG_UNBLOCK, &mask, NULL);
79
68 do { 80 do {
69 pid = waitpid(cpid, &pstat, 0); 81 pid = waitpid(cpid, &pstat, 0);
70 } while (pid == -1 && errno == EINTR); 82 } while (pid == -1 && errno == EINTR);
83
71 sigprocmask(SIG_SETMASK, &omask, NULL); 84 sigprocmask(SIG_SETMASK, &omask, NULL);
72 sigaction(SIGINT, &intsave, NULL); 85 sigaction(SIGINT, &intsave, NULL);
73 sigaction(SIGQUIT, &quitsave, NULL); 86 sigaction(SIGQUIT, &quitsave, NULL);