Skip to content

Commit 372fba6

Browse files
committed
wasm: Plug wasm heap leakages
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
1 parent 65722e8 commit 372fba6

File tree

1 file changed

+81
-26
lines changed

1 file changed

+81
-26
lines changed

src/wasm/flb_wasm.c

Lines changed: 81 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -254,42 +254,70 @@ char *flb_wasm_call_function_format_json(struct flb_wasm *fw, const char *functi
254254
const char *exception;
255255
uint8_t *func_result;
256256
wasm_function_inst_t func = NULL;
257+
uint32_t func_args[6] = {0};
258+
size_t args_size = 0;
259+
char *host_copy = NULL;
260+
261+
if (!(func = wasm_runtime_lookup_function(fw->module_inst, function_name))) {
262+
flb_error("The %s wasm function is not found.", function_name);
263+
return NULL;
264+
}
265+
257266
/* We should pass the length that is null terminator included into
258267
* WASM runtime. This is why we add +1 for tag_len and record_len.
259268
*/
260269
fw->tag_buffer = wasm_runtime_module_dup_data(fw->module_inst, tag_data, tag_len+1);
261270
fw->record_buffer = wasm_runtime_module_dup_data(fw->module_inst, record_data, record_len+1);
262-
uint32_t func_args[6] = {fw->tag_buffer, tag_len,
263-
t.tm.tv_sec, t.tm.tv_nsec,
264-
fw->record_buffer, record_len};
265-
size_t args_size = sizeof(func_args) / sizeof(uint32_t);
266271

267-
if (!(func = wasm_runtime_lookup_function(fw->module_inst, function_name))) {
268-
flb_error("The %s wasm function is not found.", function_name);
269-
return NULL;
270-
}
272+
func_args[0] = fw->tag_buffer;
273+
func_args[1] = tag_len;
274+
func_args[2] = t.tm.tv_sec;
275+
func_args[3] = t.tm.tv_nsec;
276+
func_args[4] = fw->record_buffer;
277+
func_args[5] = record_len;
278+
args_size = sizeof(func_args) / sizeof(uint32_t);
271279

272280
if (!wasm_runtime_call_wasm(fw->exec_env, func, args_size, func_args)) {
273281
exception = wasm_runtime_get_exception(fw->module_inst);
274282
flb_error("Got exception running wasm code: %s", exception);
275283
wasm_runtime_clear_exception(fw->module_inst);
276-
return NULL;
284+
goto cleanup_fail;
277285
}
278286

279287
// The return value is stored in the first element of the function argument array.
280288
// It's a WASM pointer to null-terminated c char string.
281289
// WAMR allows us to map WASM pointers to native pointers.
282290
if (!wasm_runtime_validate_app_str_addr(fw->module_inst, func_args[0])) {
283291
flb_warn("[wasm] returned value is invalid");
284-
return NULL;
292+
goto cleanup_fail;
285293
}
286294
func_result = wasm_runtime_addr_app_to_native(fw->module_inst, func_args[0]);
287295

288296
if (func_result == NULL) {
289-
return NULL;
297+
goto cleanup_fail;
290298
}
291299

292-
return (char *)flb_strdup(func_result);
300+
host_copy = (char *) flb_strdup(func_result);
301+
302+
if (fw->tag_buffer) {
303+
wasm_runtime_module_free(fw->module_inst, fw->tag_buffer);
304+
fw->tag_buffer = 0;
305+
}
306+
if (fw->record_buffer) {
307+
wasm_runtime_module_free(fw->module_inst, fw->record_buffer);
308+
fw->record_buffer = 0;
309+
}
310+
return host_copy;
311+
cleanup_fail:
312+
if (fw->tag_buffer) {
313+
wasm_runtime_module_free(fw->module_inst, fw->tag_buffer);
314+
fw->tag_buffer = 0;
315+
}
316+
if (fw->record_buffer) {
317+
wasm_runtime_module_free(fw->module_inst, fw->record_buffer);
318+
fw->record_buffer = 0;
319+
}
320+
return NULL;
293321
}
294322

295323
/*
@@ -335,42 +363,69 @@ char *flb_wasm_call_function_format_msgpack(struct flb_wasm *fw, const char *fun
335363
const char *exception;
336364
uint8_t *func_result;
337365
wasm_function_inst_t func = NULL;
338-
/* We should pass the length that is null terminator included into
339-
* WASM runtime. This is why we add +1 for tag_len and record_len.
340-
*/
341-
fw->tag_buffer = wasm_runtime_module_dup_data(fw->module_inst, tag_data, tag_len+1);
342-
fw->record_buffer = wasm_runtime_module_dup_data(fw->module_inst, records, records_len);
343-
uint32_t func_args[6] = {fw->tag_buffer, tag_len,
344-
t.tm.tv_sec, t.tm.tv_nsec,
345-
fw->record_buffer, records_len};
346-
size_t args_size = sizeof(func_args) / sizeof(uint32_t);
366+
uint32_t func_args[6] = {0};
367+
size_t args_size = 0;
368+
char *host_copy = NULL;
347369

348370
if (!(func = wasm_runtime_lookup_function(fw->module_inst, function_name))) {
349371
flb_error("The %s wasm function is not found.", function_name);
350372
return NULL;
351373
}
352374

375+
/* Tag is a C string: duplicate it with +1 to include the null terminator.
376+
* Records is binary data: pass its length as-is (do not add +1).
377+
* The WASM function treats `records` as binary rather than a string.
378+
*/
379+
fw->tag_buffer = wasm_runtime_module_dup_data(fw->module_inst, tag_data, tag_len+1);
380+
fw->record_buffer = wasm_runtime_module_dup_data(fw->module_inst, records, records_len);
381+
382+
func_args[0] = (uint32_t) fw->tag_buffer;
383+
func_args[1] = (uint32_t) tag_len;
384+
func_args[2] = (uint32_t) t.tm.tv_sec;
385+
func_args[3] = (uint32_t) t.tm.tv_nsec;
386+
func_args[4] = (uint32_t) fw->record_buffer;
387+
func_args[5] = (uint32_t) records_len;
388+
args_size = sizeof(func_args) / sizeof(func_args[0]);
389+
353390
if (!wasm_runtime_call_wasm(fw->exec_env, func, args_size, func_args)) {
354391
exception = wasm_runtime_get_exception(fw->module_inst);
355392
flb_error("Got exception running wasm code: %s", exception);
356393
wasm_runtime_clear_exception(fw->module_inst);
357-
return NULL;
394+
goto cleanup_fail;
358395
}
359396

360397
// The return value is stored in the first element of the function argument array.
361398
// It's a WASM pointer to null-terminated c char string.
362399
// WAMR allows us to map WASM pointers to native pointers.
363400
if (!wasm_runtime_validate_app_str_addr(fw->module_inst, func_args[0])) {
364401
flb_warn("[wasm] returned value is invalid");
365-
return NULL;
402+
goto cleanup_fail;
366403
}
367404
func_result = wasm_runtime_addr_app_to_native(fw->module_inst, func_args[0]);
368-
369405
if (func_result == NULL) {
370-
return NULL;
406+
goto cleanup_fail;
371407
}
372408

373-
return (char *)flb_strdup(func_result);
409+
host_copy = (char *) flb_strdup(func_result);
410+
if (fw->tag_buffer) {
411+
wasm_runtime_module_free(fw->module_inst, fw->tag_buffer);
412+
fw->tag_buffer = 0;
413+
}
414+
if (fw->record_buffer) {
415+
wasm_runtime_module_free(fw->module_inst, fw->record_buffer);
416+
fw->record_buffer = 0;
417+
}
418+
return host_copy;
419+
cleanup_fail:
420+
if (fw->tag_buffer) {
421+
wasm_runtime_module_free(fw->module_inst, fw->tag_buffer);
422+
fw->tag_buffer = 0;
423+
}
424+
if (fw->record_buffer) {
425+
wasm_runtime_module_free(fw->module_inst, fw->record_buffer);
426+
fw->record_buffer = 0;
427+
}
428+
return NULL;
374429
}
375430

376431
int flb_wasm_call_wasi_main(struct flb_wasm *fw)

0 commit comments

Comments
 (0)