Skip to content

Commit 86edb55

Browse files
authored
Merge pull request #491 from igaw/harden-json-parser
Enforce correct JSON config format
2 parents e1e8a95 + 15b5855 commit 86edb55

1 file changed

Lines changed: 45 additions & 5 deletions

File tree

src/nvme/json.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,43 @@ static void json_parse_host(nvme_root_t r, struct json_object *host_obj)
158158
}
159159
}
160160

161+
static struct json_object *parse_json(nvme_root_t r, int fd)
162+
{
163+
char buf[JSON_FILE_BUF_SIZE];
164+
struct json_object *obj = NULL;
165+
struct printbuf *pb;
166+
json_tokener *tok = NULL;
167+
int ret;
168+
169+
pb = printbuf_new();
170+
if (!pb)
171+
return NULL;
172+
173+
while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0)
174+
printbuf_memappend(pb, buf, ret);
175+
176+
if (ret < 0)
177+
goto out;
178+
179+
tok = json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
180+
if (!tok)
181+
goto out;
182+
183+
/* Enforce correctly formatted JSON */
184+
tok->flags = JSON_TOKENER_STRICT;
185+
186+
obj = json_tokener_parse_ex(tok, pb->buf, printbuf_length(pb));
187+
if (!obj)
188+
nvme_msg(r, LOG_DEBUG, "JSON parsing failed: %s\n",
189+
json_util_get_last_err());
190+
out:
191+
if (tok)
192+
json_tokener_free(tok);
193+
printbuf_free(pb);
194+
195+
return obj;
196+
}
197+
161198
int json_read_config(nvme_root_t r, const char *config_file)
162199
{
163200
struct json_object *json_root, *host_obj;
@@ -169,12 +206,16 @@ int json_read_config(nvme_root_t r, const char *config_file)
169206
config_file, strerror(errno));
170207
return fd;
171208
}
172-
json_root = json_object_from_fd(fd);
209+
json_root = parse_json(r, fd);
210+
close(fd);
173211
if (!json_root) {
174-
nvme_msg(r, LOG_DEBUG, "Failed to read %s, %s\n",
175-
config_file, json_util_get_last_err());
176212
errno = EPROTO;
177-
close(fd);
213+
return -1;
214+
}
215+
if (!json_object_is_type(json_root, json_type_array)) {
216+
nvme_msg(r, LOG_DEBUG, "Wrong format, expected array\n");
217+
json_object_put(json_root);
218+
errno = EPROTO;
178219
return -1;
179220
}
180221
for (h = 0; h < json_object_array_length(json_root); h++) {
@@ -183,7 +224,6 @@ int json_read_config(nvme_root_t r, const char *config_file)
183224
json_parse_host(r, host_obj);
184225
}
185226
json_object_put(json_root);
186-
close(fd);
187227
return 0;
188228
}
189229

0 commit comments

Comments
 (0)