journal-gatewayd: fix signed overflow in n_skip handling

request_reader_entries() negated m->n_skip in signed context before
casting to uint64_t, which is undefined behaviour for
n_skip == INT64_MIN.

Follow-up for 77ad3b93de
Follow-up for a7bfb9f76b
This commit is contained in:
Luca Boccassi
2026-06-24 13:39:33 +01:00
parent 45f561bf12
commit f8891704d3
2 changed files with 17 additions and 3 deletions

View File

@@ -184,9 +184,12 @@ static ssize_t request_reader_entries(
m->n_entries <= 0)
return MHD_CONTENT_READER_END_OF_STREAM;
if (m->n_skip < 0)
if (m->n_skip < 0) {
/* request_parse_range_skip_and_n_entries() rejects INT64_MIN, so the negation
* below cannot overflow. */
assert(m->n_skip >= -INT64_MAX);
r = sd_journal_previous_skip(m->journal, (uint64_t) -m->n_skip + 1);
else if (m->n_skip > 0) {
} else if (m->n_skip > 0) {
r = sd_journal_next_skip(m->journal, (uint64_t) m->n_skip + 1);
if (r < 0) {
log_error_errno(r, "Failed to skip journal entries: %m");
@@ -194,7 +197,7 @@ static ssize_t request_reader_entries(
}
/* We skipped beyond the end, make sure entries between the cursor and n_skip offset
* from it are not returned. */
if (r < m->n_skip + 1) {
if ((uint64_t) r < (uint64_t) m->n_skip + 1) {
m->n_skip -= r;
if (!m->follow)
@@ -348,6 +351,11 @@ static int request_parse_range_skip_and_n_entries(
r = safe_atoi64(t, &m->n_skip);
if (r < 0)
return r;
/* The consumer negates n_skip, and negating INT64_MIN in signed arithmetic is undefined
* behaviour, so reject it up front. */
if (m->n_skip == INT64_MIN)
return -ERANGE;
}
p = (colon2 ?: colon) + 1;

View File

@@ -88,6 +88,12 @@ curl -LSfs \
--header "Range: entries=$TEST_CURSOR:1:1" \
http://localhost:19531/entries?SYSLOG_IDENTIFIER="$TEST_TAG" >"$LOG_FILE"
jq -se "length == 0" "$LOG_FILE"
# A skip of INT64_MIN must not crash the daemon
curl -LSs \
--header "Accept: application/json" \
--header "Range: entries=:-9223372036854775808:1" \
http://localhost:19531/entries >/dev/null || true
curl -LSfs http://localhost:19531/entries >"$LOG_FILE"
# Check if the specified cursor refers to an existing entry and return just that entry
curl -LSfs \
--header "Accept: application/json" \