mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
Merge pull request #8865 from yuwata/fix-signal
util: fix integer overflow
This commit is contained in:
commit
1ab0a250c2
@ -229,38 +229,67 @@ const char *signal_to_string(int signo) {
|
||||
}
|
||||
|
||||
int signal_from_string(const char *s) {
|
||||
int signo;
|
||||
int offset = 0;
|
||||
unsigned u;
|
||||
const char *p;
|
||||
int signo, r;
|
||||
|
||||
/* Check that the input is a signal number. */
|
||||
if (safe_atoi(s, &signo) >= 0) {
|
||||
if (SIGNAL_VALID(signo))
|
||||
return signo;
|
||||
else
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
/* Drop "SIG" prefix. */
|
||||
if (startswith(s, "SIG"))
|
||||
s += 3;
|
||||
|
||||
/* Check that the input is a signal name. */
|
||||
signo = __signal_from_string(s);
|
||||
if (signo > 0)
|
||||
return signo;
|
||||
|
||||
if (startswith(s, "RTMIN+")) {
|
||||
s += 6;
|
||||
offset = SIGRTMIN;
|
||||
/* Check that the input is RTMIN or
|
||||
* RTMIN+n (0 <= n <= SIGRTMAX-SIGRTMIN). */
|
||||
p = startswith(s, "RTMIN");
|
||||
if (p) {
|
||||
if (*p == '\0')
|
||||
return SIGRTMIN;
|
||||
if (*p != '+')
|
||||
return -EINVAL;
|
||||
|
||||
r = safe_atoi(p, &signo);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (signo < 0 || signo > SIGRTMAX - SIGRTMIN)
|
||||
return -ERANGE;
|
||||
|
||||
return signo + SIGRTMIN;
|
||||
}
|
||||
if (safe_atou(s, &u) >= 0) {
|
||||
signo = (int) u + offset;
|
||||
if (SIGNAL_VALID(signo))
|
||||
return signo;
|
||||
|
||||
/* Check that the input is RTMAX or
|
||||
* RTMAX-n (0 <= n <= SIGRTMAX-SIGRTMIN). */
|
||||
p = startswith(s, "RTMAX");
|
||||
if (p) {
|
||||
if (*p == '\0')
|
||||
return SIGRTMAX;
|
||||
if (*p != '-')
|
||||
return -EINVAL;
|
||||
|
||||
r = safe_atoi(p, &signo);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (signo > 0 || signo < SIGRTMIN - SIGRTMAX)
|
||||
return -ERANGE;
|
||||
|
||||
return signo + SIGRTMAX;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int signal_from_string_try_harder(const char *s) {
|
||||
int signo;
|
||||
assert(s);
|
||||
|
||||
signo = signal_from_string(s);
|
||||
if (signo <= 0)
|
||||
if (startswith(s, "SIG"))
|
||||
return signal_from_string(s+3);
|
||||
|
||||
return signo;
|
||||
}
|
||||
|
||||
void nop_signal_handler(int sig) {
|
||||
/* nothing here */
|
||||
}
|
||||
|
@ -24,8 +24,6 @@ int sigprocmask_many(int how, sigset_t *old, ...);
|
||||
const char *signal_to_string(int i) _const_;
|
||||
int signal_from_string(const char *s) _pure_;
|
||||
|
||||
int signal_from_string_try_harder(const char *s);
|
||||
|
||||
void nop_signal_handler(int sig);
|
||||
|
||||
static inline void block_signals_reset(sigset_t *ss) {
|
||||
|
@ -4042,7 +4042,7 @@ int config_parse_set_status(
|
||||
|
||||
r = safe_atoi(temp, &val);
|
||||
if (r < 0) {
|
||||
val = signal_from_string_try_harder(temp);
|
||||
val = signal_from_string(temp);
|
||||
|
||||
if (val <= 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse value, ignoring: %s", word);
|
||||
|
@ -1465,7 +1465,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
|
||||
case 's':
|
||||
arg_signal = signal_from_string_try_harder(optarg);
|
||||
arg_signal = signal_from_string(optarg);
|
||||
if (arg_signal < 0) {
|
||||
log_error("Failed to parse signal string %s.", optarg);
|
||||
return -EINVAL;
|
||||
|
@ -2879,7 +2879,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
|
||||
case 's':
|
||||
arg_signal = signal_from_string_try_harder(optarg);
|
||||
arg_signal = signal_from_string(optarg);
|
||||
if (arg_signal < 0) {
|
||||
log_error("Failed to parse signal string %s.", optarg);
|
||||
return -EINVAL;
|
||||
|
@ -972,7 +972,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
|
||||
case ARG_KILL_SIGNAL:
|
||||
arg_kill_signal = signal_from_string_try_harder(optarg);
|
||||
arg_kill_signal = signal_from_string(optarg);
|
||||
if (arg_kill_signal < 0) {
|
||||
log_error("Cannot parse signal: %s", optarg);
|
||||
return -EINVAL;
|
||||
|
@ -109,7 +109,7 @@ DEFINE_BUS_APPEND_PARSE("i", log_level_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", parse_errno);
|
||||
DEFINE_BUS_APPEND_PARSE("i", sched_policy_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", secure_bits_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", signal_from_string_try_harder);
|
||||
DEFINE_BUS_APPEND_PARSE("i", signal_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", socket_protocol_from_name);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, ioprio_parse_priority);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, parse_nice);
|
||||
@ -1189,7 +1189,7 @@ static int bus_append_kill_property(sd_bus_message *m, const char *field, const
|
||||
|
||||
if (streq(field, "KillSignal"))
|
||||
|
||||
return bus_append_signal_from_string_try_harder(m, field, eq);
|
||||
return bus_append_signal_from_string(m, field, eq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1298,7 +1298,7 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
|
||||
|
||||
r = safe_atoi(word, &val);
|
||||
if (r < 0) {
|
||||
val = signal_from_string_try_harder(word);
|
||||
val = signal_from_string(word);
|
||||
if (val < 0)
|
||||
return log_error_errno(r, "Invalid status or signal %s in %s: %m", word, field);
|
||||
|
||||
|
@ -927,7 +927,7 @@ int config_parse_signal(
|
||||
assert(rvalue);
|
||||
assert(sig);
|
||||
|
||||
r = signal_from_string_try_harder(rvalue);
|
||||
r = signal_from_string(rvalue);
|
||||
if (r <= 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse signal name, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
|
@ -7601,7 +7601,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
|
||||
case 's':
|
||||
arg_signal = signal_from_string_try_harder(optarg);
|
||||
arg_signal = signal_from_string(optarg);
|
||||
if (arg_signal < 0) {
|
||||
log_error("Failed to parse signal string %s.", optarg);
|
||||
return -EINVAL;
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "signal-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
#include "process-util.h"
|
||||
|
||||
#define info(sig) log_info(#sig " = " STRINGIFY(sig) " = %d", sig)
|
||||
@ -23,6 +25,91 @@ static void test_rt_signals(void) {
|
||||
assert(SIGRTMAX - SIGRTMIN >= 24);
|
||||
}
|
||||
|
||||
static void test_signal_to_string_one(int val) {
|
||||
const char *p;
|
||||
|
||||
assert_se(p = signal_to_string(val));
|
||||
|
||||
assert_se(signal_from_string(p) == val);
|
||||
|
||||
p = strjoina("SIG", p);
|
||||
assert_se(signal_from_string(p) == val);
|
||||
}
|
||||
|
||||
static void test_signal_from_string_one(const char *s, int val) {
|
||||
const char *p;
|
||||
|
||||
assert_se(signal_from_string(s) == val);
|
||||
|
||||
p = strjoina("SIG", s);
|
||||
assert_se(signal_from_string(p) == val);
|
||||
}
|
||||
|
||||
static void test_signal_from_string_number(const char *s, int val) {
|
||||
const char *p;
|
||||
|
||||
assert_se(signal_from_string(s) == val);
|
||||
|
||||
p = strjoina("SIG", s);
|
||||
assert_se(signal_from_string(p) == -EINVAL);
|
||||
}
|
||||
|
||||
static void test_signal_from_string(void) {
|
||||
char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1];
|
||||
|
||||
test_signal_to_string_one(SIGHUP);
|
||||
test_signal_to_string_one(SIGTERM);
|
||||
test_signal_to_string_one(SIGRTMIN);
|
||||
test_signal_to_string_one(SIGRTMIN+3);
|
||||
test_signal_to_string_one(SIGRTMAX-4);
|
||||
|
||||
test_signal_from_string_one("RTMIN", SIGRTMIN);
|
||||
test_signal_from_string_one("RTMAX", SIGRTMAX);
|
||||
|
||||
xsprintf(buf, "RTMIN+%d", SIGRTMAX-SIGRTMIN);
|
||||
test_signal_from_string_one(buf, SIGRTMAX);
|
||||
|
||||
xsprintf(buf, "RTMIN+%d", INT_MAX);
|
||||
test_signal_from_string_one(buf, -ERANGE);
|
||||
|
||||
xsprintf(buf, "RTMAX-%d", SIGRTMAX-SIGRTMIN);
|
||||
test_signal_from_string_one(buf, SIGRTMIN);
|
||||
|
||||
xsprintf(buf, "RTMAX-%d", INT_MAX);
|
||||
test_signal_from_string_one(buf, -ERANGE);
|
||||
|
||||
test_signal_from_string_one("", -EINVAL);
|
||||
test_signal_from_string_one("hup", -EINVAL);
|
||||
test_signal_from_string_one("HOGEHOGE", -EINVAL);
|
||||
|
||||
test_signal_from_string_one("RTMIN-5", -EINVAL);
|
||||
test_signal_from_string_one("RTMIN- 5", -EINVAL);
|
||||
test_signal_from_string_one("RTMIN -5", -EINVAL);
|
||||
test_signal_from_string_one("RTMIN+ 5", -EINVAL);
|
||||
test_signal_from_string_one("RTMIN +5", -EINVAL);
|
||||
test_signal_from_string_one("RTMIN+100", -ERANGE);
|
||||
test_signal_from_string_one("RTMIN+-3", -EINVAL);
|
||||
test_signal_from_string_one("RTMIN++3", -EINVAL);
|
||||
test_signal_from_string_one("RTMIN+HUP", -EINVAL);
|
||||
test_signal_from_string_one("RTMIN3", -EINVAL);
|
||||
|
||||
test_signal_from_string_one("RTMAX+5", -EINVAL);
|
||||
test_signal_from_string_one("RTMAX+ 5", -EINVAL);
|
||||
test_signal_from_string_one("RTMAX +5", -EINVAL);
|
||||
test_signal_from_string_one("RTMAX- 5", -EINVAL);
|
||||
test_signal_from_string_one("RTMAX -5", -EINVAL);
|
||||
test_signal_from_string_one("RTMAX-100", -ERANGE);
|
||||
test_signal_from_string_one("RTMAX-+3", -EINVAL);
|
||||
test_signal_from_string_one("RTMAX--3", -EINVAL);
|
||||
test_signal_from_string_one("RTMAX-HUP", -EINVAL);
|
||||
|
||||
test_signal_from_string_number("3", 3);
|
||||
test_signal_from_string_number("+5", 5);
|
||||
test_signal_from_string_number(" +5", 5);
|
||||
test_signal_from_string_number("10000", -ERANGE);
|
||||
test_signal_from_string_number("-2", -ERANGE);
|
||||
}
|
||||
|
||||
static void test_block_signals(void) {
|
||||
sigset_t ss;
|
||||
|
||||
@ -61,6 +148,7 @@ static void test_ignore_signals(void) {
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_rt_signals();
|
||||
test_signal_from_string();
|
||||
test_block_signals();
|
||||
test_ignore_signals();
|
||||
|
||||
|
3
test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8064
Normal file
3
test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8064
Normal file
@ -0,0 +1,3 @@
|
||||
service
|
||||
[Service]
|
||||
RestartForceExitStatus=RTMIN+2147483644
|
@ -26,4 +26,5 @@ fuzz_regression_tests = '''
|
||||
fuzz-unit-file/oss-fuzz-6917
|
||||
fuzz-unit-file/oss-fuzz-6977
|
||||
fuzz-unit-file/oss-fuzz-7004
|
||||
fuzz-unit-file/oss-fuzz-8064
|
||||
'''.split()
|
||||
|
Loading…
x
Reference in New Issue
Block a user