Skip to content

Commit 2a04712

Browse files
committed
shared/varlink: add missing terminator in json strings
Should finally fix oss-fuzz-14688. 8688c29 wasn't enough. The buffer retrieved from memstream has the size that the same as the written data. When we write do write(f, s, strlen(s)), then no terminating NUL is written, and the buffer is not (necessarilly) a proper C string.
1 parent c2babfc commit 2a04712

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

src/shared/json.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,9 @@ int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
15551555
size_t sz = 0;
15561556
int r;
15571557

1558+
/* Returns the length of the generated string (without the terminating NUL),
1559+
* or negative on error. */
1560+
15581561
assert_return(v, -EINVAL);
15591562
assert_return(ret, -EINVAL);
15601563

@@ -1567,15 +1570,18 @@ int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
15671570

15681571
json_variant_dump(v, flags, f, NULL);
15691572

1573+
/* Add terminating 0, so that the output buffer is a valid string. */
1574+
fputc('\0', f);
1575+
15701576
r = fflush_and_check(f);
15711577
}
15721578
if (r < 0)
15731579
return r;
15741580

15751581
assert(s);
15761582
*ret = TAKE_PTR(s);
1577-
1578-
return (int) sz;
1583+
assert(sz > 0);
1584+
return (int) sz - 1;
15791585
}
15801586

15811587
void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix) {

src/shared/varlink.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,7 @@ static int varlink_enqueue_json(Varlink *v, JsonVariant *m) {
12121212
r = json_variant_format(m, 0, &text);
12131213
if (r < 0)
12141214
return r;
1215+
assert(text[r] == '\0');
12151216

12161217
if (v->output_buffer_size + r + 1 > VARLINK_BUFFER_MAX)
12171218
return -ENOBUFS;

src/test/test-json.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ static void test_variant(const char *data, Test test) {
8989
r = json_variant_format(v, 0, &s);
9090
assert_se(r >= 0);
9191
assert_se(s);
92+
assert_se((size_t) r == strlen(s));
9293

9394
log_info("formatted normally: %s\n", s);
9495

@@ -105,6 +106,7 @@ static void test_variant(const char *data, Test test) {
105106
r = json_variant_format(v, JSON_FORMAT_PRETTY, &s);
106107
assert_se(r >= 0);
107108
assert_se(s);
109+
assert_se((size_t) r == strlen(s));
108110

109111
log_info("formatted prettily:\n%s", s);
110112

@@ -120,12 +122,14 @@ static void test_variant(const char *data, Test test) {
120122
r = json_variant_format(v, JSON_FORMAT_COLOR, &s);
121123
assert_se(r >= 0);
122124
assert_se(s);
125+
assert_se((size_t) r == strlen(s));
123126
printf("Normal with color: %s\n", s);
124127

125128
s = mfree(s);
126129
r = json_variant_format(v, JSON_FORMAT_COLOR|JSON_FORMAT_PRETTY, &s);
127130
assert_se(r >= 0);
128131
assert_se(s);
132+
assert_se((size_t) r == strlen(s));
129133
printf("Pretty with color:\n%s\n", s);
130134

131135
if (test)

0 commit comments

Comments
 (0)