akheron / jansson

C library for encoding, decoding and manipulating JSON data
http://www.digip.org/jansson/
Other
3.02k stars 807 forks source link

Infinite loop into hashtable code #642

Open roccof opened 1 year ago

roccof commented 1 year ago

libjansson goes sometime in an infinite loop while parsing a JSON, attached two backtraces and the code loop. Tested with version v2.13.1 and v2.14.

Backtraces v2.13.1:

#0  0x76efe20a in hashtable_find_pair (hashtable=hashtable@entry=0xb57708, bucket=0xb57738, key=key@entry=0xb66a48 "private_key", hash=703574673) at hashtable.c:85
#1  0x76efe44e in hashtable_get (hashtable=hashtable@entry=0xb57708, key=key@entry=0xb66a48 "private_key") at hashtable.c:251
#2  0x76f00b20 in json_object_get (json=json@entry=0xb57700, key=key@entry=0xb66a48 "private_key") at value.c:102
#3  0x76f01432 in json_object_equal (object2=0xb57700, object1=0xb58060) at value.c:315
#4  json_equal (json1=0xb58060, json2=0xb57700) at value.c:986
#5  0x76f0143a in json_object_equal (object2=0xb294b0, object1=0xb676f0) at value.c:317
#6  json_equal (json1=0xb676f0, json2=0xb294b0) at value.c:986
#7  0x76f0147c in json_array_equal (array2=0xaaeb80, array1=0xb4e8c0) at value.c:611
#8  json_equal (json1=0xb4e8c0, json2=0xaaeb80) at value.c:988
#9  0x76f0143a in json_object_equal (object2=0xb56a40, object1=0xb57260) at value.c:317
#10 json_equal (json1=0xb57260, json2=0xb56a40) at value.c:986
#11 0x0001594e in _config_validate (oconf=0xaaeb30, nconf=0xb46420) at ../confd/config.c:256
#12 0x00015cfe in config_validate (conf=0xb46420) at ../confd/config.c:422
#13 0x0001d628 in _ubus_conf_validate_update (ctx=0x76e2bc00, obj=0x4a644 <conf_object>, req=0x7e9e2d74, method=0xa98020 "validate", msg=0xa98044, update=0) at ../confd/ubus.c:92
#14 0x0001d892 in ubus_conf_validate (ctx=0x76e2bc00, obj=0x4a644 <conf_object>, req=0x7e9e2d74, method=0xa98020 "validate", msg=0xa98044) at ../confd/ubus.c:211
#15 0x76f16066 in ubus_process_invoke (ctx=0x76e2bc00, hdr=<optimized out>, obj=0x4a644 <conf_object>, attrbuf=<optimized out>, fd=-1) at libubus-obj.c:95
#16 0x76f1618c in ubus_process_obj_msg (ctx=0x76e2bc00, buf=0x76e2bc64, fd=-1) at libubus-obj.c:142
#17 0x76f15618 in ubus_process_msg (ctx=ctx@entry=0x76e2bc00, buf=buf@entry=0x76e2bc64, fd=<optimized out>) at libubus.c:106
#18 0x76f15de8 in ubus_handle_data (u=0x76e2bc2c, events=<optimized out>) at libubus-io.c:314
#19 0x0001d45a in ubus_handle_event (ctx=0x76e2bc00) at ../../../host/arm-buildroot-linux-musleabihf/sysroot/usr/include/libubus.h:263
#20 0x0001dd1c in ubus_io_handler (io=0x4ac20 <ubus_io>, events=1) at ../confd/ubus.c:459
#21 0x76f4be44 in evloop_handle_ios (timeout=14472) at ../lib/evloop-io.c:159
#22 0x76f4ba8a in evloop_run () at ../lib/evloop.c:37
#23 0x0001a0f6 in main (argc=1, argv=0x7e9e2ee4) at ../confd/main.c:163

#0  hashtable_find_pair (hashtable=hashtable@entry=0x23c978, bucket=0x23c9d0, key=key@entry=0x3767c "web_filtering", hash=2806414854) at hashtable.c:88
#1  0x76e4b44e in hashtable_get (hashtable=hashtable@entry=0x23c978, key=key@entry=0x3767c "web_filtering") at hashtable.c:251
#2  0x76e4db20 in json_object_get (json=json@entry=0x23c970, key=key@entry=0x3767c "web_filtering") at value.c:102
#3  0x76e4cace in unpack_object (ap=0x7ee399dc, root=0x23c970, s=0x7ee399e0) at pack_unpack.c:536
#4  unpack (s=s@entry=0x7ee399e0, root=root@entry=0x23c970, ap=ap@entry=0x7ee399dc) at pack_unpack.c:671
#5  0x76e4d5be in json_vunpack_ex (root=0x23c970, error=error@entry=0x0, flags=flags@entry=0, fmt=fmt@entry=0x76e4d631 <json_unpack+22> "\260]\370\004\353\003\260pG", ap=..., ap@entry=...)
    at pack_unpack.c:898
#6  0x76e4d630 in json_unpack (root=<optimized out>, fmt=0x375e4 "{s:b,s:b,s:b,s:{s:b,s:o},s:{s:b,s:o},s:{s:b},s?{s:b}}") at pack_unpack.c:931
#7  0x00029e28 in fortinet_ssid_parse (o=0x23c970, conf=0x0) at ../confd/fortinet_ssid.c:349
#8  0x00029fba in fortinet_ssid_validate (o=0x23c970) at ../confd/fortinet_ssid.c:395
#9  0x00022dd4 in wifi_parse_ssid (ssid=0x23cc40, sc=0x7ee39cc0) at ../confd/wifi.c:729
#10 0x00023168 in wifi_setup_ssid (country=0x22ea00 "US", r=0x5b65c <wifi_radios>, rc=0x7ee39db0, j_ssid=0x23cc40) at ../confd/wifi.c:865
#11 0x00023f84 in __wifi_setup (o=0x24da70) at ../confd/wifi.c:1304
#12 0x00024598 in wifi_setup (o=0x24da70) at ../confd/wifi.c:1512
#13 0x00015866 in _apply_config (oconf=0x23ce50, nconf=0x22ecf0) at ../confd/config.c:204
#14 0x00015e88 in config_apply_timeout_handler (t=0x4b2a0 <apply_timeo>) at ../confd/config.c:453
#15 0x76e993fa in evloop_handle_timeouts () at ../lib/evloop-timeout.c:75
#16 0x76e98a62 in evloop_run () at ../lib/evloop.c:28
#17 0x0001a202 in main (argc=1, argv=0x7ee39ee4) at ../confd/main.c:163

Backtrace v2.14:

#0  hashtable_find_pair (hashtable=hashtable@entry=0x187a058, bucket=0x187a0a0, key=key@entry=0x3768c "botnet_protection", key_len=key_len@entry=17, hash=327024876) at hashtable.c:89
#1  0x76e2a568 in hashtable_get (hashtable=hashtable@entry=0x187a058, key=key@entry=0x3768c "botnet_protection", key_len=17) at hashtable.c:268
#2  0x76e2cc60 in json_object_getn (json=json@entry=0x187a050, key=key@entry=0x3768c "botnet_protection", key_len=<optimized out>) at value.c:113
#3  0x76e2cc80 in json_object_get (json=json@entry=0x187a050, key=key@entry=0x3768c "botnet_protection") at value.c:103
#4  0x76e2bbfe in unpack_object (ap=0x7e8549dc, root=0x187a050, s=0x7e8549e0) at pack_unpack.c:536
#5  unpack (s=s@entry=0x7e8549e0, root=root@entry=0x187a050, ap=ap@entry=0x7e8549dc) at pack_unpack.c:673
#6  0x76e2c6fe in json_vunpack_ex (root=0x187a050, error=error@entry=0x0, flags=flags@entry=0, fmt=fmt@entry=0x76e2c771 <json_unpack+22> "\260]\370\004\353\003\260pG", ap=..., ap@entry=...)
    at pack_unpack.c:900
#7  0x76e2c770 in json_unpack (root=<optimized out>, fmt=0x375e4 "{s:b,s:b,s:b,s:{s:b,s:o},s:{s:b,s:o},s:{s:b},s?{s:b}}") at pack_unpack.c:933
#8  0x00029e28 in fortinet_ssid_parse (o=0x187a050, conf=0x0) at ../confd/fortinet_ssid.c:349
#9  0x00029fba in fortinet_ssid_validate (o=0x187a050) at ../confd/fortinet_ssid.c:395
#10 0x00022dd4 in wifi_parse_ssid (ssid=0x1840cf0, sc=0x7e854cc0) at ../confd/wifi.c:729
#11 0x00023168 in wifi_setup_ssid (country=0x185e2b0 "US", r=0x5b65c <wifi_radios>, rc=0x7e854db0, j_ssid=0x1840cf0) at ../confd/wifi.c:865
#12 0x00023f84 in __wifi_setup (o=0x1840f00) at ../confd/wifi.c:1304
#13 0x00024598 in wifi_setup (o=0x1840f00) at ../confd/wifi.c:1512
#14 0x00015866 in _apply_config (oconf=0x186e630, nconf=0x1840d50) at ../confd/config.c:204
#15 0x00015e88 in config_apply_timeout_handler (t=0x4b2a0 <apply_timeo>) at ../confd/config.c:453
#16 0x76e783fa in evloop_handle_timeouts () at ../lib/evloop-timeout.c:75
#17 0x76e77a62 in evloop_run () at ../lib/evloop.c:28
#18 0x0001a202 in main (argc=1, argv=0x7e854ee4) at ../confd/main.c:163

Code loop v2.14:

81          pair = list_to_pair(list);
(gdb) 
82          if (pair->hash == hash && pair->key_len == key_len &&
(gdb) 
86          if (list == bucket->last)
(gdb) 
89          list = list->next;
(gdb) 
81          pair = list_to_pair(list);
(gdb) 
82          if (pair->hash == hash && pair->key_len == key_len &&
(gdb) 
86          if (list == bucket->last)
(gdb) 
89          list = list->next;
(gdb) 
81          pair = list_to_pair(list);
(gdb) 
82          if (pair->hash == hash && pair->key_len == key_len &&
(gdb) 
86          if (list == bucket->last)
(gdb) 
89          list = list->next;
(gdb) 
81          pair = list_to_pair(list);
(gdb) 
82          if (pair->hash == hash && pair->key_len == key_len &&
(gdb) 
86          if (list == bucket->last)
(gdb) 
89          list = list->next;
(gdb) 
81          pair = list_to_pair(list);
(gdb) 
82          if (pair->hash == hash && pair->key_len == key_len &&
(gdb) 
86          if (list == bucket->last)
(gdb) 
89          list = list->next;
(gdb) 
81          pair = list_to_pair(list);
(gdb) 
82          if (pair->hash == hash && pair->key_len == key_len &&

Do you have an idea why this may happen?

I'll try to make it more reproducible with a simpler snippet.