NIKSS-vSwitch / nikss

Native In-Kernel P4-programmable Software Switch for Software-Defined Networking (previously PSA-eBPF)
Apache License 2.0
47 stars 4 forks source link

Double free in `value_set get` - unsuccessful value_set read #71

Closed tatry closed 1 year ago

tatry commented 1 year ago
  1. Create any value_set in the parser.
  2. Try to read its whole content. Result:
    {
      "IngressParserImpl_p_pvs": []
    double free or corruption (top)
    Aborted

    Exit code: 134


Stack trace leading to free_btf (line numbers after applying PR #68):

free_btf                         btf.c:274
psabpf_table_entry_ctx_free      psabpf_table.c:57
psabpf_value_set_get_next_entry  psabpf_value_set.c:140
get_and_print_value_set_json     value_set.c:70
do_value_set_get                 value_set.c:194
cmd_select                       main.c:48
do_value_set                     main.c:158
cmd_select                       main.c:48
main                             main.c:188
__libc_start_main                0x00007ffff7d17083
_start                           0x000055555555b08e

Second stack trace leading to free_btf:

free_btf                       btf.c:274
psabpf_value_set_context_free  psabpf_value_set.c:51
do_value_set_get               value_set.c:198
cmd_select                     main.c:48
do_value_set                   main.c:158
cmd_select                     main.c:48
main                           main.c:188
__libc_start_main              0x00007ffff7d17083
_start                         0x000055555555b08e

Difference between these stack traces is that free_btf is called twice - once inside psabpf_value_set_get_next_entry and second time in psabpf_value_set_context_free. free_btf should be called only once in the later function.

There is second problem in psabpf_value_set_get_next_entry - each entry returned by this function must be freed, otherwise there is a memory leak.


PVS definition (instance must be used later in the parser code):

value_set<bit<16>>(4) pvs;

Command to read PVS:

psabpf-ctl value-set get pipe 1 IngressParserImpl_p_pvs