core: rework serialization
Let's be more careful with what we serialize: let's ensure we never serialize strings that are longer than LONG_LINE_MAX, so that we know we can read them back with read_line(…, LONG_LINE_MAX, …) safely. In order to implement this all serialization functions are move to serialize.[ch], and internally will do line size checks. We'd rather skip a serialization line (with a loud warning) than write an overly long line out. Of course, this is just a second level protection, after all the data we serialize shouldn't be this long in the first place. While we are at it also clean up logging: while serializing make sure to always log about errors immediately. Also, (void)ify all calls we don't expect errors in (or catch errors as part of the general fflush_and_check() at the end.
This commit is contained in:
+11
-17
@@ -9,6 +9,7 @@
|
||||
#include "fs-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "random-util.h"
|
||||
#include "serialize.h"
|
||||
#include "special.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
@@ -661,21 +662,20 @@ static int timer_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
assert(f);
|
||||
assert(fds);
|
||||
|
||||
unit_serialize_item(u, f, "state", timer_state_to_string(t->state));
|
||||
unit_serialize_item(u, f, "result", timer_result_to_string(t->result));
|
||||
(void) serialize_item(f, "state", timer_state_to_string(t->state));
|
||||
(void) serialize_item(f, "result", timer_result_to_string(t->result));
|
||||
|
||||
if (t->last_trigger.realtime > 0)
|
||||
unit_serialize_item_format(u, f, "last-trigger-realtime", "%" PRIu64, t->last_trigger.realtime);
|
||||
(void) serialize_usec(f, "last-trigger-realtime", t->last_trigger.realtime);
|
||||
|
||||
if (t->last_trigger.monotonic > 0)
|
||||
unit_serialize_item_format(u, f, "last-trigger-monotonic", "%" PRIu64, t->last_trigger.monotonic);
|
||||
(void) serialize_usec(f, "last-trigger-monotonic", t->last_trigger.monotonic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int timer_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
|
||||
Timer *t = TIMER(u);
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(key);
|
||||
@@ -690,6 +690,7 @@ static int timer_deserialize_item(Unit *u, const char *key, const char *value, F
|
||||
log_unit_debug(u, "Failed to parse state value: %s", value);
|
||||
else
|
||||
t->deserialized_state = state;
|
||||
|
||||
} else if (streq(key, "result")) {
|
||||
TimerResult f;
|
||||
|
||||
@@ -698,19 +699,12 @@ static int timer_deserialize_item(Unit *u, const char *key, const char *value, F
|
||||
log_unit_debug(u, "Failed to parse result value: %s", value);
|
||||
else if (f != TIMER_SUCCESS)
|
||||
t->result = f;
|
||||
} else if (streq(key, "last-trigger-realtime")) {
|
||||
|
||||
r = safe_atou64(value, &t->last_trigger.realtime);
|
||||
if (r < 0)
|
||||
log_unit_debug(u, "Failed to parse last-trigger-realtime value: %s", value);
|
||||
|
||||
} else if (streq(key, "last-trigger-monotonic")) {
|
||||
|
||||
r = safe_atou64(value, &t->last_trigger.monotonic);
|
||||
if (r < 0)
|
||||
log_unit_debug(u, "Failed to parse last-trigger-monotonic value: %s", value);
|
||||
|
||||
} else
|
||||
} else if (streq(key, "last-trigger-realtime"))
|
||||
(void) deserialize_usec(value, &t->last_trigger.realtime);
|
||||
else if (streq(key, "last-trigger-monotonic"))
|
||||
(void) deserialize_usec(value, &t->last_trigger.monotonic);
|
||||
else
|
||||
log_unit_debug(u, "Unknown serialization key: %s", key);
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user