mirror of
https://github.com/systemd/systemd.git
synced 2024-10-27 18:55:40 +03:00
udev: do not import property value from truncated line of program result
This commit is contained in:
parent
7056adbf16
commit
6b6e471a32
@ -17,7 +17,7 @@ static void test_event_spawn_core(bool with_pidfd, const char *cmd, char result_
|
||||
|
||||
assert_se(sd_device_new_from_syspath(&dev, "/sys/class/net/lo") >= 0);
|
||||
assert_se(event = udev_event_new(dev, 0, NULL, LOG_DEBUG));
|
||||
assert_se(udev_event_spawn(event, 5 * USEC_PER_SEC, SIGKILL, false, cmd, result_buf, BUF_SIZE) == 0);
|
||||
assert_se(udev_event_spawn(event, 5 * USEC_PER_SEC, SIGKILL, false, cmd, result_buf, BUF_SIZE, NULL) == 0);
|
||||
|
||||
assert_se(unsetenv("SYSTEMD_PIDFD") >= 0);
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ typedef struct Spawn {
|
||||
char *result;
|
||||
size_t result_size;
|
||||
size_t result_len;
|
||||
bool truncated;
|
||||
} Spawn;
|
||||
|
||||
UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl, int log_level) {
|
||||
@ -569,7 +570,6 @@ int udev_check_format(const char *value, size_t *offset, const char **hint) {
|
||||
static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
|
||||
Spawn *spawn = userdata;
|
||||
char buf[4096], *p;
|
||||
bool full = false;
|
||||
size_t size;
|
||||
ssize_t l;
|
||||
int r;
|
||||
@ -601,7 +601,7 @@ static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userd
|
||||
log_device_warning(spawn->device, "Truncating stdout of '%s' up to %zu byte.",
|
||||
spawn->cmd, spawn->result_size);
|
||||
l--;
|
||||
full = true;
|
||||
spawn->truncated = true;
|
||||
}
|
||||
|
||||
p[l] = '\0';
|
||||
@ -624,7 +624,7 @@ static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userd
|
||||
fd == spawn->fd_stdout ? "out" : "err", *q);
|
||||
}
|
||||
|
||||
if (l == 0 || full)
|
||||
if (l == 0 || spawn->truncated)
|
||||
return 0;
|
||||
|
||||
reenable:
|
||||
@ -763,12 +763,16 @@ static int spawn_wait(Spawn *spawn) {
|
||||
return sd_event_loop(e);
|
||||
}
|
||||
|
||||
int udev_event_spawn(UdevEvent *event,
|
||||
usec_t timeout_usec,
|
||||
int timeout_signal,
|
||||
bool accept_failure,
|
||||
const char *cmd,
|
||||
char *result, size_t ressize) {
|
||||
int udev_event_spawn(
|
||||
UdevEvent *event,
|
||||
usec_t timeout_usec,
|
||||
int timeout_signal,
|
||||
bool accept_failure,
|
||||
const char *cmd,
|
||||
char *result,
|
||||
size_t ressize,
|
||||
bool *ret_truncated) {
|
||||
|
||||
_cleanup_close_pair_ int outpipe[2] = {-1, -1}, errpipe[2] = {-1, -1};
|
||||
_cleanup_strv_free_ char **argv = NULL;
|
||||
char **envp = NULL;
|
||||
@ -859,6 +863,9 @@ int udev_event_spawn(UdevEvent *event,
|
||||
if (result)
|
||||
result[spawn.result_len] = '\0';
|
||||
|
||||
if (ret_truncated)
|
||||
*ret_truncated = spawn.truncated;
|
||||
|
||||
return r; /* 0 for success, and positive if the program failed */
|
||||
}
|
||||
|
||||
@ -1133,7 +1140,7 @@ void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec, int timeout_s
|
||||
|
||||
log_device_debug(event->dev, "Running command \"%s\"", command);
|
||||
|
||||
r = udev_event_spawn(event, timeout_usec, timeout_signal, false, command, NULL, 0);
|
||||
r = udev_event_spawn(event, timeout_usec, timeout_signal, false, command, NULL, 0, NULL);
|
||||
if (r < 0)
|
||||
log_device_warning_errno(event->dev, r, "Failed to execute '%s', ignoring: %m", command);
|
||||
else if (r > 0) /* returned value is positive when program fails */
|
||||
|
@ -66,7 +66,8 @@ int udev_event_spawn(
|
||||
bool accept_failure,
|
||||
const char *cmd,
|
||||
char *result,
|
||||
size_t ressize);
|
||||
size_t ressize,
|
||||
bool *ret_truncated);
|
||||
int udev_event_execute_rules(
|
||||
UdevEvent *event,
|
||||
int inotify_fd,
|
||||
|
@ -1740,7 +1740,7 @@ static int udev_rule_apply_token_to_event(
|
||||
|
||||
log_rule_debug(dev, rules, "Running PROGRAM '%s'", buf);
|
||||
|
||||
r = udev_event_spawn(event, timeout_usec, timeout_signal, true, buf, result, sizeof(result));
|
||||
r = udev_event_spawn(event, timeout_usec, timeout_signal, true, buf, result, sizeof(result), NULL);
|
||||
if (r != 0) {
|
||||
if (r < 0)
|
||||
log_rule_warning_errno(dev, rules, r, "Failed to execute \"%s\": %m", buf);
|
||||
@ -1826,7 +1826,7 @@ static int udev_rule_apply_token_to_event(
|
||||
|
||||
log_rule_debug(dev, rules, "Importing properties from results of '%s'", buf);
|
||||
|
||||
r = udev_event_spawn(event, timeout_usec, timeout_signal, true, buf, result, sizeof result);
|
||||
r = udev_event_spawn(event, timeout_usec, timeout_signal, true, buf, result, sizeof result, &truncated);
|
||||
if (r != 0) {
|
||||
if (r < 0)
|
||||
log_rule_warning_errno(dev, rules, r, "Failed to execute '%s', ignoring: %m", buf);
|
||||
@ -1835,6 +1835,18 @@ static int udev_rule_apply_token_to_event(
|
||||
return token->op == OP_NOMATCH;
|
||||
}
|
||||
|
||||
if (truncated) {
|
||||
bool found = false;
|
||||
|
||||
/* Drop the last line. */
|
||||
for (char *p = buf + strlen(buf) - 1; p >= buf; p--)
|
||||
if (strchr(NEWLINE, *p)) {
|
||||
*p = '\0';
|
||||
found = true;
|
||||
} else if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
r = strv_split_newlines_full(&lines, result, EXTRACT_RETAIN_ESCAPE);
|
||||
if (r < 0)
|
||||
log_rule_warning_errno(dev, rules, r,
|
||||
|
Loading…
Reference in New Issue
Block a user