{"id":56714,"date":"2024-05-09T20:29:54","date_gmt":"2024-05-09T16:29:54","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/178525\/HNS-2024-07-riot.txt"},"modified":"2024-05-09T20:29:54","modified_gmt":"2024-05-09T16:29:54","slug":"riot-2024-01-buffer-overflows-lack-of-size-checks-out-of-bound-access","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/riot-2024-01-buffer-overflows-lack-of-size-checks-out-of-bound-access\/","title":{"rendered":"RIOT 2024.01 Buffer Overflows \/ Lack Of Size Checks \/ Out-Of-Bound Access"},"content":{"rendered":"<p>&#8211;[ HNS-2024-07 &#8211; HN Security Advisory &#8211; https:\/\/security.humanativaspa.it\/<\/p>\n<p>* Title: Multiple vulnerabilities in RIOT OS<br \/>* OS: RIOT &lt;= 2024.01<br \/>* Author: Marco Ivaldi &lt;marco.ivaldi@hnsecurity.it&gt;<br \/>* Date: 2024-05-07<br \/>* CVE ID and severity:<br \/>* CVE-2024-31225 &#8211; High<br \/>* CVE-2024-32017 &#8211; Critical<br \/>* CVE-2024-32018 &#8211; High<br \/>(low-severity vulnerabilities were not assigned a CVE ID)<br \/>* Vendor URL: https:\/\/www.riot-os.org\/<br \/>* Advisory URLs: <br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-2572-7q7c-3965<br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-v97j-w9m6-c4h3<br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-899m-q6pp-hmp3<br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-x3j5-hfrr-5x6q<br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-pw2r-pp35-xfmj<br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-c4p4-vv7v-3hx8<br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-r87w-9vw9-f7cx<br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-2hx7-c324-3rxv<br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-frp5-4gfp-84j3<br \/>* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-x27v-gqp4-7jq3<\/p>\n<p>&#8211;[ 0 &#8211; Table of contents<\/p>\n<p>1 &#8211; Summary<br \/>2 &#8211; Background<br \/>3 &#8211; Vulnerabilities<br \/>3.1 &#8211; CVE-2024-31225 &#8211; Lack of size check and buffer overflow in RIOT \/sys\/net\/application_layer\/cord\/lc\/cord_lc.c<br \/>3.2 &#8211; CVE-2024-32017 &#8211; Buffer overflows in RIOT \/sys\/net\/application_layer\/gcoap\/<br \/>3.3 &#8211; CVE-2024-32018 &#8211; Ineffective size check due to assert() and buffer overflow in RIOT \/pkg\/nimble\/scanlist\/nimble_scanlist.c<br \/>3.4 &#8211; Unsafe use of the return value of vsnprintf() and out-of-bounds memory access in RIOT \/cpu\/esp_common\/lib_printf.c<br \/>3.5 &#8211; Ineffective size check due to assert() and buffer overflow in RIOT \/sys\/net\/ble\/skald\/skald_eddystone.c<br \/>3.6 &#8211; Ineffective size check due to assert() and buffer overflow in RIOT \/sys\/suit\/handlers_command_seq.c<br \/>3.7 &#8211; Integer wraparound and buffer overflow in RIOT \/drivers\/mtd_emulated\/mtd_emulated.c<br \/>3.8 &#8211; Off-by-one buffer overflow and unterminated string in RIOT \/pkg\/lwext4\/fs\/lwext4_fs.c<br \/>3.9 &#8211; Unsafe use of the return value of snprintf() and out-of-bounds memory access in RIOT \/sys\/shell\/cmds\/vfs.c<br \/>3.10 &#8211; Lack of size checks and buffer overflows in RIOT \/sys\/net\/application_layer\/emcute\/emcute.c<br \/>4 &#8211; Affected products<br \/>5 &#8211; Remediation<br \/>6 &#8211; Disclosure timeline<br \/>7 &#8211; Acknowledgments<br \/>8 &#8211; References<\/p>\n<p>&#8211;[ 1 &#8211; Summary<\/p>\n<p>&#8220;Where there is parsing, there are bugs.&#8221; <br \/>&#8212; Dr. Silvio Cesare<\/p>\n<p>RIOT [1] is a free, open-source, real-time operating system developed by a<br \/>grassroots community gathering companies, academia, and hobbyists, distributed<br \/>all around the world. It supports most low-power IoT devices, microcontroller<br \/>architectures (32-bit, 16-bit, 8-bit), and external devices. RIOT aims to<br \/>implement all relevant open standards supporting an Internet of Things that is<br \/>connected, secure, durable, and privacy friendly.<\/p>\n<p>We reviewed RIOT&#8217;s source code hosted on GitHub [2] and identified multiple<br \/>security vulnerabilities that may cause memory corruption. Their impacts range<br \/>from denial of service to potential arbitrary code execution.<\/p>\n<p>&#8211;[ 2 &#8211; Background<\/p>\n<p>Continuing our recent vulnerability research work in the IoT space [3] [4], we<br \/>keep assisting open-source projects in finding and fixing vulnerabilities by<br \/>reviewing their source code, with the final goal to make IoT more secure. In<br \/>January 2024, RIOT was selected as a target of interest.<\/p>\n<p>During the source code review, we put our Semgrep C\/C++ ruleset [5] and weggli<br \/>pattern collection [6] to good use to identify hotspots in code on which to<br \/>focus our attention.<\/p>\n<p>&#8211;[ 3 &#8211; Vulnerabilities<\/p>\n<p>The vulnerabilities resulting from our source code review are briefly described<br \/>in the following sections.<\/p>\n<p>&#8211;[ 3.1 &#8211; CVE-2024-31225 &#8211; Lack of size check and buffer overflow in RIOT \/sys\/net\/application_layer\/cord\/lc\/cord_lc.c<\/p>\n<p>We spotted the lack of a size check that may lead to a buffer overflow in RIOT<br \/>source code at:<\/p>\n<p>* \/sys\/net\/application_layer\/cord\/lc\/cord_lc.c<\/p>\n<p>The `_on_rd_init()` function does not implement a size check before copying<br \/>data to the `_result_buf` static buffer. If an attacker can craft a long enough<br \/>payload, they could cause a buffer overflow.<\/p>\n<p>See the marked line below:<br \/>&#8220;`c<br \/>static void _on_rd_init(const gcoap_request_memo_t *memo, coap_pkt_t *pdu,<br \/>const sock_udp_ep_t *remote)<br \/>{<br \/>(void)remote;<\/p>\n<p>thread_flags_t flag = FLAG_NORSC;<\/p>\n<p>if (memo-&gt;state == GCOAP_MEMO_RESP) {<br \/>unsigned ct = coap_get_content_type(pdu);<br \/>if (ct != COAP_FORMAT_LINK) {<br \/>DEBUG(&#8220;cord_lc: error payload not in link format: %u\\n&#8221;, ct);<br \/>goto end;<br \/>}<br \/>if (pdu-&gt;payload_len == 0) {<br \/>DEBUG(&#8220;cord_lc: error empty payload\\n&#8221;);<br \/>goto end;<br \/>}<br \/>memcpy(_result_buf, pdu-&gt;payload, pdu-&gt;payload_len); \/\/ VULN: lack of size check and potential buffer overflow<br \/>_result_buf_len = pdu-&gt;payload_len;<br \/>_result_buf[_result_buf_len] = &#8216;\\0&#8217;;<br \/>flag = FLAG_SUCCESS;<br \/>} else if (memo-&gt;state == GCOAP_MEMO_TIMEOUT) {<br \/>flag = FLAG_TIMEOUT;<br \/>}<\/p>\n<p>end:<br \/>if (flag != FLAG_SUCCESS) {<br \/>_result_buf = NULL;<br \/>_result_buf_len = 0;<br \/>}<br \/>thread_flags_set(_waiter, flag);<br \/>}<br \/>&#8220;`<\/p>\n<p>Note that the `_on_lookup()` function in the same file does implement such an<br \/>explicit size check:<br \/>&#8220;`c<br \/>static void _on_lookup(const gcoap_request_memo_t *memo, coap_pkt_t *pdu,<br \/>const sock_udp_ep_t *remote)<br \/>{<br \/>(void)remote;<\/p>\n<p>thread_flags_t flag = FLAG_ERR;<\/p>\n<p>if (memo-&gt;state == GCOAP_MEMO_RESP) {<br \/>unsigned ct = coap_get_content_type(pdu);<br \/>if (ct != COAP_FORMAT_LINK) {<br \/>DEBUG(&#8220;cord_lc: unsupported content format: %u\\n&#8221;, ct);<br \/>thread_flags_set(_waiter, flag);<br \/>}<br \/>if (pdu-&gt;payload_len == 0) {<br \/>flag = FLAG_NORSC;<br \/>thread_flags_set(_waiter, flag);<br \/>}<br \/>if (pdu-&gt;payload_len &gt;= _result_buf_len) { \/\/ CHECK<br \/>flag = FLAG_OVERFLOW;<br \/>thread_flags_set(_waiter, flag);<br \/>}<br \/>memcpy(_result_buf, pdu-&gt;payload, pdu-&gt;payload_len);<br \/>memset(_result_buf + pdu-&gt;payload_len, 0,<br \/>_result_buf_len &#8211; pdu-&gt;payload_len);<br \/>_result_buf_len = pdu-&gt;payload_len;<br \/>flag = FLAG_SUCCESS;<br \/>} else if (memo-&gt;state == GCOAP_MEMO_TIMEOUT) {<br \/>flag = FLAG_TIMEOUT;<br \/>}<\/p>\n<p>thread_flags_set(_waiter, flag);<br \/>}<br \/>&#8220;`<\/p>\n<p>If the unchecked input above is attacker-controlled and crosses a security<br \/>boundary, the impact of the buffer overflow vulnerability could range from<br \/>denial of service to arbitrary code execution.<\/p>\n<p>Fixes:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20547<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-2572-7q7c-3965<\/p>\n<p>&#8211;[ 3.2 &#8211; CVE-2024-32017 &#8211; Buffer overflows in RIOT \/sys\/net\/application_layer\/gcoap\/<\/p>\n<p>We spotted a typo in a size check that may lead to a buffer overflow in RIOT<br \/>source code at:<\/p>\n<p>* \/sys\/net\/application_layer\/gcoap\/dns.c<\/p>\n<p>We also spotted another potential buffer overflow in RIOT source code at:<\/p>\n<p>* \/sys\/net\/application_layer\/gcoap\/forward_proxy.c<\/p>\n<p>The size check in the `gcoap_dns_server_proxy_get()` function contains a small<br \/>typo that may lead to a buffer overflow in the subsequent `strcpy()`. The<br \/>length of the `_uri` string is checked instead of the length of the `_proxy`<br \/>string.<\/p>\n<p>See the marked lines below:<br \/>&#8220;`c<br \/>ssize_t gcoap_dns_server_proxy_get(char *proxy, size_t proxy_len)<br \/>{<br \/>ssize_t res = 0;<br \/>mutex_lock(&amp;_client_mutex);<br \/>if (_dns_server_uri_isset()) {<br \/>res = strlen(_uri); \/\/ VULN: typo, should be strlen(_proxy)<br \/>if (((size_t)res + 1) &gt; proxy_len) {<br \/>\/* account for trailing \\0 *\/<br \/>res = -ENOBUFS;<br \/>}<br \/>else {<br \/>strcpy(proxy, _proxy); \/\/ VULN: potential buffer overflow<br \/>}<br \/>}<br \/>mutex_unlock(&amp;_client_mutex);<br \/>return res;<br \/>}<br \/>&#8220;`<\/p>\n<p>The `_gcoap_forward_proxy_copy_options()` function does not implement an<br \/>explicit size check before copying data to the `cep-&gt;req_etag` buffer that is<br \/>`COAP_ETAG_LENGTH_MAX` bytes long. If an attacker can craft input so that<br \/>optlen becomes larger than `COAP_ETAG_LENGTH_MAX`, they can cause a buffer<br \/>overflow.<\/p>\n<p>See the marked line below:<br \/>&#8220;`c<br \/>static int _gcoap_forward_proxy_copy_options(coap_pkt_t *pkt,<br \/>coap_pkt_t *client_pkt,<br \/>client_ep_t *cep,<br \/>uri_parser_result_t *urip)<br \/>{<br \/>\/* copy all options from client_pkt to pkt *\/<br \/>coap_optpos_t opt = {0, 0};<br \/>uint8_t *value;<br \/>bool uri_path_added = false;<br \/>bool etag_added = false;<\/p>\n<p>for (int i = 0; i &lt; client_pkt-&gt;options_len; i++) {<br \/>ssize_t optlen = coap_opt_get_next(client_pkt, &amp;opt, &amp;value, !i);<br \/>\/* wrt to ETag option slack: we always have at least the Proxy-URI option in the client_pkt,<br \/>* so we should hit at least once (and it&#8217;s opt_num is also &gt;= COAP_OPT_ETAG) *\/<br \/>if (optlen &gt;= 0) {<br \/>if (IS_USED(MODULE_NANOCOAP_CACHE) &amp;&amp; !etag_added &amp;&amp; (opt.opt_num &gt;= COAP_OPT_ETAG)) {<br \/>static const uint8_t tmp[COAP_ETAG_LENGTH_MAX] = { 0 };<br \/>\/* add slack to maybe add an ETag on stale cache hit later, as is done in<br \/>* gcoap_req_send() (which we circumvented in _gcoap_forward_proxy_via_coap()) *\/<br \/>if (coap_opt_add_opaque(pkt, COAP_OPT_ETAG, tmp, sizeof(tmp))) {<br \/>etag_added = true;<br \/>}<br \/>}<br \/>if (IS_USED(MODULE_NANOCOAP_CACHE) &amp;&amp; opt.opt_num == COAP_OPT_ETAG) {<br \/>if (_cep_get_req_etag_len(cep) == 0) {<br \/>\/* TODO: what to do on multiple ETags? *\/<br \/>_cep_set_req_etag_len(cep, (uint8_t)optlen);<br \/>#if IS_USED(MODULE_NANOCOAP_CACHE)<br \/>\/* req_tag in cep is pre-processor guarded so we need to as well *\/<br \/>memcpy(cep-&gt;req_etag, value, optlen); \/\/ VULN: potential buffer overflow if optlen can become larger than COAP_ETAG_LENGTH_MAX<br \/>#endif<br \/>&#8230;<br \/>&#8220;`<\/p>\n<p>If the input above is attacker-controlled and crosses a security boundary, the<br \/>impact of the buffer overflow vulnerabilities could range from denial of<br \/>service to arbitrary code execution.<\/p>\n<p>Fixes:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20561<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20579<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-v97j-w9m6-c4h3<\/p>\n<p>&#8211;[ 3.3 &#8211; CVE-2024-32018 &#8211; Ineffective size check due to assert() and buffer overflow in RIOT \/pkg\/nimble\/scanlist\/nimble_scanlist.c<\/p>\n<p>We spotted an ineffective size check implemented via `assert()` that may lead<br \/>to a buffer overflow in RIOT source code at:<\/p>\n<p>* \/pkg\/nimble\/scanlist\/nimble_scanlist.c<\/p>\n<p>Most codebases define assertion macros which compile to a no-op on non-debug<br \/>builds. If assertions are the only line of defense against untrusted input, the<br \/>software may be exposed to attacks that leverage the lack of proper input<br \/>checks.<\/p>\n<p>In detail, in the `nimble_scanlist_update()` function below, `len` is checked<br \/>in an assertion and subsequently used in a call to `memcpy()`. If an attacker<br \/>is able to provide a larger `len` value while assertions are compiled-out, they<br \/>can write past the end of the fixed-length `e-&gt;ad` buffer.<\/p>\n<p>See the marked lines below:<br \/>&#8220;`c<br \/>\/**<br \/>* @brief Data structure for holding a single scanlist entry<br \/>*\/<br \/>typedef struct {<br \/>clist_node_t node; \/**&lt; list node *\/<br \/>ble_addr_t addr; \/**&lt; a node&#8217;s BLE address *\/<br \/>uint8_t ad[BLE_ADV_PDU_LEN]; \/**&lt; the received raw advertising data *\/<br \/>uint8_t ad_len; \/**&lt; length of the advertising data *\/<br \/>int8_t last_rssi; \/**&lt; last RSSI of a scanned node *\/<br \/>uint32_t adv_msg_cnt; \/**&lt; number of adv packets by a node *\/<br \/>uint32_t first_update; \/**&lt; first packet timestamp *\/<br \/>uint32_t last_update; \/**&lt; last packet timestamp *\/<br \/>uint8_t type; \/**&lt; advertising packet type *\/<br \/>uint8_t phy_pri; \/**&lt; primary PHY used *\/<br \/>uint8_t phy_sec; \/**&lt; secondary PHY advertised *\/<br \/>} nimble_scanlist_entry_t;<\/p>\n<p>&#8230;<\/p>\n<p>void nimble_scanlist_update(uint8_t type, const ble_addr_t *addr,<br \/>const nimble_scanner_info_t *info,<br \/>const uint8_t *ad, size_t len)<br \/>{<br \/>assert(addr);<br \/>assert(len &lt;= BLE_ADV_PDU_LEN); \/\/ VULN: len is checked to be &lt;= BLE_ADV_PDU_LEN only via an assertion<\/p>\n<p>uint32_t now = (uint32_t)ztimer_now(ZTIMER_USEC);<br \/>nimble_scanlist_entry_t *e = _find(addr);<\/p>\n<p>if (!e) {<br \/>e = (nimble_scanlist_entry_t *)clist_lpop(&amp;_pool);<br \/>if (!e) {<br \/>\/* no space available, dropping newly discovered node *\/<br \/>return;<br \/>}<br \/>memcpy(&amp;e-&gt;addr, addr, sizeof(ble_addr_t));<br \/>if (ad) {<br \/>memcpy(e-&gt;ad, ad, len); \/\/ VULN: if len is actually larger than BLE_ADV_PDU_LEN there&#8217;s a potential buffer overflow<br \/>}<br \/>e-&gt;ad_len = len;<br \/>e-&gt;last_rssi = info-&gt;rssi;<br \/>e-&gt;first_update = now;<br \/>e-&gt;adv_msg_cnt = 1;<br \/>e-&gt;type = type;<br \/>e-&gt;phy_pri = info-&gt;phy_pri;<br \/>e-&gt;phy_sec = info-&gt;phy_sec;<br \/>clist_rpush(&amp;_list, (clist_node_t *)e);<br \/>}<br \/>else {<br \/>e-&gt;adv_msg_cnt++;<br \/>}<\/p>\n<p>e-&gt;last_update = now;<br \/>}<br \/>&#8220;`<\/p>\n<p>If the unchecked input above is attacker-controlled and crosses a security<br \/>boundary, the impact of the buffer overflow vulnerability could range from<br \/>denial of service to arbitrary code execution.<\/p>\n<p>Fixes:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20555<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-899m-q6pp-hmp3<\/p>\n<p>&#8211;[ 3.4 &#8211; Unsafe use of the return value of vsnprintf() and out-of-bounds memory access in RIOT \/cpu\/esp_common\/lib_printf.c<\/p>\n<p>We spotted an unsafe use of the return value of `vsnprintf()` that leads to an<br \/>out-of-bounds memory access in RIOT source code at:<\/p>\n<p>* \/cpu\/esp_common\/lib_printf.c<\/p>\n<p>The `vsnprintf()` API function returns the number of characters (excluding the<br \/>terminating NUL byte) which would have been written to the destination string<br \/>if enough space had been available. <\/p>\n<p>If an attacker is able to craft input so that the final string would become<br \/>larger than `PRINTF_BUFSIZ`, they can exploit this bug to overwrite a &#8216;\\n&#8217;,<br \/>&#8216;\\r&#8217; or &#8216; &#8216; byte (or a sequence of such bytes) with a NUL byte in memory past<br \/>the end of the `_printf_buf` static buffer. In addition, the tainted `len`<br \/>value is returned at the end of the `_lib_printf()` function and may be used<br \/>unsafely (e.g., as an array index) elsewhere in the code.<\/p>\n<p>See the marked lines below:<br \/>&#8220;`c<br \/>static char _printf_buf[PRINTF_BUFSIZ];<\/p>\n<p>static int _lib_printf(int level, const char* tag, const char* format, va_list arg)<br \/>{<br \/>if (level &gt; LOG_LEVEL) {<br \/>return 0;<br \/>}<\/p>\n<p>int len = vsnprintf(_printf_buf, PRINTF_BUFSIZ &#8211; 1, format, arg); \/\/ VULN: vsnprintf() returns the total length of the string it tried to create, which may be larger than the actual size of the destination string<\/p>\n<p>\/*<br \/>* Since ESP_EARLY_LOG macros add a line break at the end, a terminating<br \/>* line break in the output must be removed if there is one.<br \/>*\/<br \/>_printf_buf[PRINTF_BUFSIZ &#8211; 1] = 0;<br \/>int i;<br \/>for (i = len &#8211; 1; i &gt;= 0; &#8211;i) {<br \/>if (_printf_buf[i] != &#8216;\\n&#8217; &amp;&amp; _printf_buf[i] != &#8216;\\r&#8217; &amp;&amp; _printf_buf[i] != &#8216; &#8216;) {<br \/>break;<br \/>}<br \/>_printf_buf[i] = 0; \/\/ VULN: very limited oob array write access<br \/>}<br \/>if (i &gt; 0) {<br \/>ESP_EARLY_LOGI(tag, &#8220;%s&#8221;, _printf_buf);<br \/>}<br \/>va_end(arg);<br \/>return len; \/\/ VULN: tainted len value is returned<br \/>}<br \/>&#8220;`<\/p>\n<p>In our understanding, the impact of this vulnerability in this specific case is<br \/>quite limited. However, all bugs that have the potential to cause memory<br \/>corruption should be taken seriously and fixed as security bugs.<\/p>\n<p>Fixes:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20596<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-x3j5-hfrr-5x6q<\/p>\n<p>&#8211;[ 3.5 &#8211; Ineffective size check due to assert() and buffer overflow in RIOT \/sys\/net\/ble\/skald\/skald_eddystone.c<\/p>\n<p>We spotted an ineffective size check implemented via `assert()` that may lead<br \/>to a buffer overflow in RIOT source code at:<\/p>\n<p>* \/sys\/net\/ble\/skald\/skald_eddystone.c<\/p>\n<p>Most codebases define assertion macros which compile to a no-op on non-debug<br \/>builds. If assertions are the only line of defense against untrusted input, the<br \/>software may be exposed to attacks that leverage the lack of proper input<br \/>checks. <\/p>\n<p>In detail, in the `skald_eddystone_url_adv()` function below, `len` is checked<br \/>in an assertion and subsequently used in a call to `memcpy()`. If an attacker<br \/>is able to provide a large `url` while assertions are compiled-out, they can<br \/>write past the end of the `pdu-&gt;url` buffer.<\/p>\n<p>See the marked lines below:<br \/>&#8220;`c<br \/>void skald_eddystone_url_adv(skald_ctx_t *ctx,<br \/>uint8_t scheme, const char *url, uint8_t tx_pwr,<br \/>uint32_t adv_itvl_ms)<br \/>{<br \/>assert(url &amp;&amp; ctx);<br \/>size_t len = strlen(url);<br \/>assert(len &lt;= (NETDEV_BLE_PDU_MAXLEN &#8211; (URL_HDR_LEN + PREAMBLE_LEN))); \/\/ VULN: len is checked only via an assertion<\/p>\n<p>eddy_url_t *pdu = (eddy_url_t *)ctx-&gt;pkt.pdu;<br \/>_init_pre(&amp;pdu-&gt;pre, EDDYSTONE_URL, (URL_HDR_LEN + len));<\/p>\n<p>\/* set remaining service data fields *\/<br \/>pdu-&gt;tx_pwr = tx_pwr;<br \/>pdu-&gt;scheme = scheme;<br \/>memcpy(pdu-&gt;url, url, len); \/\/ VULN: if len is actually larger than expected there&#8217;s a potential buffer overflow<\/p>\n<p>\/* start advertising *\/<br \/>ctx-&gt;pkt.len = (sizeof(pre_t) + 2 + len);<br \/>ctx-&gt;adv_itvl_ms = adv_itvl_ms;<br \/>skald_adv_start(ctx);<br \/>}<br \/>&#8220;`<\/p>\n<p>If the unchecked input above is attacker-controlled and crosses a security<br \/>boundary, the impact of the buffer overflow vulnerability could range from<br \/>denial of service to arbitrary code execution.<\/p>\n<p>Fixes:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20577<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-pw2r-pp35-xfmj<\/p>\n<p>&#8211;[ 3.6 &#8211; Ineffective size check due to assert() and buffer overflow in RIOT \/sys\/suit\/handlers_command_seq.c<\/p>\n<p>We spotted an ineffective size check implemented via `assert()` that may lead<br \/>to a buffer overflow in RIOT source code at:<\/p>\n<p>* \/sys\/suit\/handlers_command_seq.c<\/p>\n<p>Most codebases define assertion macros which compile to a no-op on non-debug<br \/>builds. If assertions are the only line of defense against untrusted input, the<br \/>software may be exposed to attacks that leverage the lack of proper input<br \/>checks. <\/p>\n<p>In detail, in the `_dtv_fetch()` function below, `url_len` is checked in an<br \/>assertion and subsequently used in a call to `memcpy()`. If an attacker is able<br \/>to provide a large `url` while assertions are compiled-out, they can write past<br \/>the end of the `manifest-&gt;urlbuf` buffer.<\/p>\n<p>See the marked lines below:<br \/>&#8220;`c<br \/>static int _dtv_fetch(suit_manifest_t *manifest, int key,<br \/>nanocbor_value_t *_it)<br \/>{<br \/>(void)key; (void)_it;<br \/>LOG_DEBUG(&#8220;_dtv_fetch() key=%i\\n&#8221;, key);<\/p>\n<p>const uint8_t *url;<br \/>size_t url_len;<\/p>\n<p>\/* Check the policy before fetching anything *\/<br \/>int res = suit_policy_check(manifest);<br \/>if (res) {<br \/>return SUIT_ERR_POLICY_FORBIDDEN;<br \/>}<\/p>\n<p>suit_component_t *comp = _get_component(manifest);<\/p>\n<p>\/* Deny the fetch if the component was already fetched before *\/<br \/>if (suit_component_check_flag(comp, SUIT_COMPONENT_STATE_FETCHED)) {<br \/>LOG_ERROR(&#8220;Component already fetched before\\n&#8221;);<br \/>return SUIT_ERR_INVALID_MANIFEST;<br \/>}<\/p>\n<p>nanocbor_value_t param_uri;<br \/>suit_param_ref_to_cbor(manifest, &amp;comp-&gt;param_uri,<br \/>&amp;param_uri);<br \/>int err = nanocbor_get_tstr(&amp;param_uri, &amp;url, &amp;url_len);<br \/>if (err &lt; 0) {<br \/>LOG_DEBUG(&#8220;URL parsing failed\\n)&#8221;);<br \/>return err;<br \/>}<\/p>\n<p>assert(manifest-&gt;urlbuf &amp;&amp; url_len &lt; manifest-&gt;urlbuf_len); \/\/ VULN: url_len is checked only via an assertion<br \/>memcpy(manifest-&gt;urlbuf, url, url_len); \/\/ VULN: if url_len is actually larger than expected there&#8217;s a potential buffer overflow<br \/>manifest-&gt;urlbuf[url_len] = &#8216;\\0&#8217;;<br \/>&#8230;<br \/>&#8220;`<\/p>\n<p>If the unchecked input above is attacker-controlled and crosses a security<br \/>boundary, the impact of the buffer overflow vulnerability could range from<br \/>denial of service to arbitrary code execution.<\/p>\n<p>Fixes:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20559<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-c4p4-vv7v-3hx8<\/p>\n<p>&#8211;[ 3.7 &#8211; Integer wraparound and buffer overflow in RIOT \/drivers\/mtd_emulated\/mtd_emulated.c<\/p>\n<p>We spotted an integer wraparound in a size check that leads to a buffer<br \/>overflow in RIOT source code at:<\/p>\n<p>* \/drivers\/mtd_emulated\/mtd_emulated.c<\/p>\n<p>If an attacker is able to provide arbitrary values for the `num` and `sector`<br \/>arguments to the `_erase_sector()` function, they can cause an integer<br \/>wraparound to bypass the size check and cause a buffer overflow.<\/p>\n<p>See the marked lines below:<br \/>&#8220;`c<br \/>static int _erase_sector(mtd_dev_t *dev, uint32_t sector, uint32_t num)<br \/>{<br \/>mtd_emulated_t *mtd = (mtd_emulated_t *)dev;<\/p>\n<p>(void)mtd;<br \/>assert(mtd);<\/p>\n<p>if (\/* sector must not exceed the number of sectors *\/<br \/>(sector &gt;= mtd-&gt;base.sector_count) ||<br \/>\/* sector + num must not exceed the number of sectors *\/<br \/>((sector + num) &gt; mtd-&gt;base.sector_count)) { \/\/ VULN: integer wraparound in size check<br \/>return -EOVERFLOW;<br \/>}<\/p>\n<p>memset(mtd-&gt;memory + (sector * (mtd-&gt;base.pages_per_sector * mtd-&gt;base.page_size)),<br \/>0xff, num * (mtd-&gt;base.pages_per_sector * mtd-&gt;base.page_size)); \/\/ VULN: buffer overflow<\/p>\n<p>return 0;<br \/>}<br \/>&#8220;`<\/p>\n<p>We put together a quick proof-of-concept to demonstrate this issue:<br \/>&#8220;`<br \/>raptor@blumenkraft Research % cat wraparound5.c<br \/>#include &lt;stdio.h&gt;<br \/>#include &lt;stdlib.h&gt;<br \/>#include &lt;inttypes.h&gt;<\/p>\n<p>#define SECTOR_COUNT 256<\/p>\n<p>static int _erase_sector(uint32_t sector, uint32_t num)<br \/>{<br \/>if (\/* sector must not exceed the number of sectors *\/<br \/>(sector &gt;= SECTOR_COUNT) ||<br \/>\/* sector + num must not exceed the number of sectors *\/<br \/>((sector + num) &gt; SECTOR_COUNT)) { \/\/ VULN: wraparound<br \/>printf(&#8220;OVERFLOW\\n&#8221;);<br \/>return 1;<br \/>}<\/p>\n<p>printf(&#8220;sector + num = %&#8221;PRIu32&#8243;\\n&#8221;, sector + num);<\/p>\n<p>return 0;<br \/>}<\/p>\n<p>int main(int argc, char **argv)<br \/>{<br \/>if (argc &lt; 3)<br \/>return 1;<\/p>\n<p>return _erase_sector(atoi(argv[1]), atoi(argv[2]));<br \/>}<br \/>raptor@blumenkraft Research % make wraparound5<br \/>cc wraparound5.c -o wraparound5<br \/>raptor@blumenkraft Research % .\/wraparound5 250 10<br \/>OVERFLOW<br \/>raptor@blumenkraft Research % .\/wraparound5 250 4294967295<br \/>sector + num = 249<br \/>&#8220;`<\/p>\n<p>If the input above is attacker-controlled and crosses a security boundary, the<br \/>impact of the buffer overflow vulnerability could range from denial of service<br \/>to (less likely in this case) arbitrary code execution.<\/p>\n<p>Fixes:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20587<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-r87w-9vw9-f7cx<\/p>\n<p>&#8211;[ 3.8 &#8211; Off-by-one buffer overflow and unterminated string in RIOT \/pkg\/lwext4\/fs\/lwext4_fs.c<\/p>\n<p>We spotted an off-by-one buffer overflow in RIOT source code at:<\/p>\n<p>* \/pkg\/lwext4\/fs\/lwext4_fs.c<\/p>\n<p>We also spotted the lack of explicit NUL-termination after strncpy() in the<br \/>same file.<\/p>\n<p>If an attacker is able to make `mount_point` at least `CONFIG_EXT4_MAX_MP_NAME`<br \/>bytes large, `strcat()` would write a NUL byte past the end of the `mp.name`<br \/>buffer, thus potentially overwriting the next member of the `ext4_mountpoint`<br \/>struct [7].<\/p>\n<p>See the marked line below:<br \/>&#8220;`c<br \/>static int prepare(lwext4_desc_t *fs, const char *mount_point)<br \/>{<br \/>mtd_dev_t *dev = fs-&gt;dev;<br \/>struct ext4_blockdev_iface *iface = &amp;fs-&gt;iface;<\/p>\n<p>memset(&amp;fs-&gt;mp, 0, sizeof(fs-&gt;mp));<br \/>memset(&amp;fs-&gt;bdev, 0, sizeof(fs-&gt;bdev));<br \/>memset(&amp;fs-&gt;iface, 0, sizeof(fs-&gt;iface));<\/p>\n<p>strncpy(fs-&gt;mp.name, mount_point, CONFIG_EXT4_MAX_MP_NAME);<br \/>strcat(fs-&gt;mp.name, &#8220;\/&#8221;); \/\/ VULN: off-by-one buffer overflow<\/p>\n<p>int res = mtd_init(dev);<br \/>if (res) {<br \/>return res;<br \/>}<br \/>&#8230;<br \/>&#8220;`<\/p>\n<p>Since `sizeof(dirent-&gt;name)` is 255 and `sizeof(entry-&gt;d_name)` is only 32, if<br \/>an attacker can control the input to `strncpy()` they would be able to create a<br \/>non NUL-terminated string in `entry-&gt;d_name`. When such corrupted string is<br \/>used in other parts of the code, it may cause information leakage or memory<br \/>corruption.<\/p>\n<p>See the marked line below:<br \/>&#8220;`c<br \/>static int _readdir(vfs_DIR *dirp, vfs_dirent_t *entry)<br \/>{<br \/>ext4_dir *dir = _get_ext4_dir(dirp);<\/p>\n<p>const ext4_direntry *dirent = ext4_dir_entry_next(dir);<br \/>if (dirent == NULL) {<br \/>return 0;<br \/>}<\/p>\n<p>strncpy(entry-&gt;d_name, (char *)dirent-&gt;name, sizeof(entry-&gt;d_name)); \/\/ VULN<\/p>\n<p>return 1;<br \/>}<br \/>&#8220;`<\/p>\n<p>In our understanding, the impact of these vulnerabilities in this specific case<br \/>is quite limited. However, all bugs that have the potential to cause memory<br \/>corruption should be taken seriously and fixed as security bugs.<\/p>\n<p>Fixes:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20586<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-2hx7-c324-3rxv<\/p>\n<p>&#8211;[ 3.9 &#8211; Unsafe use of the return value of snprintf() and out-of-bounds memory access in RIOT \/sys\/shell\/cmds\/vfs.c<\/p>\n<p>We spotted an unsafe use of the return value of `snprintf()` that leads to an<br \/>out-of-bounds memory access in RIOT source code at:<\/p>\n<p>* \/sys\/shell\/cmds\/vfs.c<\/p>\n<p>The `snprintf()` function returns the number of characters (excluding the<br \/>terminating NUL byte) which would have been written to the destination string<br \/>if enough space had been available. <\/p>\n<p>If an attacker is able to craft input so that the final string would become<br \/>larger than `bs`, they can exploit this bug to cause a buffer overflow.<\/p>\n<p>See the marked lines below:<br \/>&#8220;`c<br \/>static void _write_block(int fd, unsigned bs, unsigned i)<br \/>{<br \/>char block[bs];<br \/>char *buf = block;<\/p>\n<p>buf += snprintf(buf, bs, &#8220;|%03u|&#8221;, i); \/\/ VULN: snprintf() returns the total length of the string it tried to create, which may be larger than bs<\/p>\n<p>memset(buf, _get_char(i), &amp;block[bs] &#8211; buf); \/\/ VULN: buf can point past the block buffer, in addition &amp;block[bs] &#8211; buf would be negative and become a large unsigned value<br \/>block[bs &#8211; 1] = &#8216;\\n&#8217;;<\/p>\n<p>vfs_write(fd, block, bs);<br \/>}<br \/>&#8220;`<\/p>\n<p>We put together a quick proof-of-concept to demonstrate this issue:<br \/>&#8220;`<br \/>raptor@blumenkraft Research % cat ret1.c<br \/>#include &lt;stdio.h&gt;<br \/>#include &lt;string.h&gt;<br \/>#include &lt;stdlib.h&gt;<\/p>\n<p>static char _get_char(unsigned i)<br \/>{<br \/>i %= 62; \/* a-z, A-Z, 0..9, -&gt; 62 characters *\/<\/p>\n<p>if (i &lt; 10) {<br \/>return &#8216;0&#8217; + i;<br \/>}<br \/>i -= 10;<\/p>\n<p>if (i &lt;= &#8216;z&#8217; &#8211; &#8216;a&#8217;) {<br \/>return &#8216;a&#8217; + i;<br \/>}<br \/>i -= 1 + &#8216;z&#8217; &#8211; &#8216;a&#8217;;<\/p>\n<p>return &#8216;A&#8217; + i;<br \/>}<\/p>\n<p>static void _write_block(unsigned bs, unsigned i)<br \/>{<br \/>char block[bs];<br \/>char *buf = block;<\/p>\n<p>buf += snprintf(buf, bs, &#8220;|%03u|&#8221;, i); \/\/ VULN: unsafe use of return value<\/p>\n<p>memset(buf, _get_char(i), &amp;block[bs] &#8211; buf); \/\/ VULN: oob memory write, size becomes a large unsigned value<br \/>block[bs &#8211; 1] = &#8216;\\n&#8217;;<br \/>}<\/p>\n<p>int main(int argc, char **argv)<br \/>{<br \/>if (argc &lt; 3)<br \/>return 1;<\/p>\n<p>_write_block(atoi(argv[1]), atoi(argv[2]));<\/p>\n<p>return 0;<br \/>}<br \/>raptor@blumenkraft Research % make ret1<br \/>cc ret1.c -o ret1<br \/>raptor@blumenkraft Research % .\/ret1 5 10<br \/>raptor@blumenkraft Research % .\/ret1 5 1000000<br \/>zsh: segmentation fault .\/ret1 5 1000000<br \/>&#8220;`<\/p>\n<p>If the input above is attacker-controlled and crosses a security boundary, the<br \/>impact of the buffer overflow vulnerability could range from denial of service<br \/>to (less likely in this case) arbitrary code execution.<\/p>\n<p>Fixes:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20546<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/pull\/20595<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-frp5-4gfp-84j3<\/p>\n<p>&#8211;[ 3.10 &#8211; Lack of size checks and buffer overflows in RIOT \/sys\/net\/application_layer\/emcute\/emcute.c<\/p>\n<p>We spotted the lack of size checks that may lead to buffer overflows in RIOT<br \/>source code at:<\/p>\n<p>* \/sys\/net\/application_layer\/emcute\/emcute.c<\/p>\n<p>The `emcute_con()` function does not implement a size check before copying data<br \/>to the `tbuf` static buffer. If an attacker can craft a long enough payload,<br \/>they could cause a buffer overflow.<\/p>\n<p>See the marked line below:<br \/>&#8220;`c<br \/>int emcute_con(sock_udp_ep_t *remote, bool clean, const char *will_topic,<br \/>const void *will_msg, size_t will_msg_len, unsigned will_flags)<br \/>{<br \/>int res;<br \/>size_t len;<\/p>\n<p>assert(!will_topic || (will_topic &amp;&amp; will_msg &amp;&amp; !(will_flags &amp; ~PUB_FLAGS)));<\/p>\n<p>mutex_lock(&amp;txlock);<\/p>\n<p>\/* check for existing connections and copy given UDP endpoint *\/<br \/>if (gateway.port != 0) {<br \/>return EMCUTE_NOGW;<br \/>}<br \/>memcpy(&amp;gateway, remote, sizeof(sock_udp_ep_t));<\/p>\n<p>\/* figure out which flags to set *\/<br \/>uint8_t flags = (clean) ? EMCUTE_CS : 0;<br \/>if (will_topic) {<br \/>flags |= EMCUTE_WILL;<br \/>}<\/p>\n<p>\/* compute packet size *\/<br \/>len = (strlen(cli_id) + 6);<br \/>tbuf[0] = (uint8_t)len;<br \/>tbuf[1] = CONNECT;<br \/>tbuf[2] = flags;<br \/>tbuf[3] = PROTOCOL_VERSION;<br \/>byteorder_htobebufs(&amp;tbuf[4], CONFIG_EMCUTE_KEEPALIVE);<br \/>memcpy(&amp;tbuf[6], cli_id, strlen(cli_id)); \/\/ VULN: lack of size check and potential buffer overflow<br \/>&#8230;<br \/>&#8220;`<\/p>\n<p>The `emcute_unsub()` function does not implement a size check before copying<br \/>data to the `tbuf` static buffer. If an attacker can craft a long enough<br \/>payload, they could cause a buffer overflow.<\/p>\n<p>See the marked line below:<br \/>&#8220;`c<br \/>int emcute_unsub(emcute_sub_t *sub)<br \/>{<br \/>assert(sub &amp;&amp; sub-&gt;topic.name);<\/p>\n<p>if (gateway.port == 0) {<br \/>return EMCUTE_NOGW;<br \/>}<\/p>\n<p>mutex_lock(&amp;txlock);<\/p>\n<p>tbuf[0] = (strlen(sub-&gt;topic.name) + 5);<br \/>tbuf[1] = UNSUBSCRIBE;<br \/>tbuf[2] = 0;<br \/>byteorder_htobebufs(&amp;tbuf[3], id_next);<br \/>waitonid = id_next++;<br \/>memcpy(&amp;tbuf[5], sub-&gt;topic.name, strlen(sub-&gt;topic.name)); \/\/ VULN: lack of size check and potential buffer overflow<\/p>\n<p>int res = syncsend(UNSUBACK, (size_t)tbuf[0], false);<br \/>if (res == EMCUTE_OK) {<br \/>if (subs == sub) {<br \/>subs = sub-&gt;next;<br \/>}<br \/>else {<br \/>emcute_sub_t *s;<br \/>for (s = subs; s; s = s-&gt;next) {<br \/>if (s-&gt;next == sub) {<br \/>s-&gt;next = sub-&gt;next;<br \/>break;<br \/>}<br \/>}<br \/>}<br \/>}<\/p>\n<p>mutex_unlock(&amp;txlock);<br \/>return res;<br \/>}<br \/>&#8220;`<\/p>\n<p>If the unchecked input above is attacker-controlled and crosses a security<br \/>boundary, the impact of the buffer overflow vulnerabilities could range from<br \/>denial of service to arbitrary code execution.<\/p>\n<p>There is currently no fix for these issues. RIOT maintainers do not consider<br \/>them to be security critical bugs and therefore they are currently discussing<br \/>them publicly.<\/p>\n<p>See also:<br \/>https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-x27v-gqp4-7jq3<\/p>\n<p>&#8211;[ 4 &#8211; Affected products<\/p>\n<p>RIOT 2024.01 and (likely) earlier versions are affected by the vulnerabilities<br \/>discussed in this advisory.<\/p>\n<p>&#8211;[ 5 &#8211; Remediation<\/p>\n<p>RIOT maintainers have fixed all the vulnerabilities discussed in this advisory,<br \/>except for those reported in GHSA-x27v-gqp4-7jq3, which are not considered<br \/>security critical bugs and are currently being discussed publicly.<\/p>\n<p>Please check the official RIOT channels for further information about fixes.<\/p>\n<p>&#8211;[ 6 &#8211; Disclosure timeline<\/p>\n<p>We reported the vulnerabilities discussed in this advisory to RIOT maintainers<br \/>in January 2024, via the handy private reporting feature [8] that is available<br \/>on GitHub.<\/p>\n<p>We are not sure of the reason of the significant delay in the initial<br \/>maintainers&#8217; response. However, once we got their attention they quickly<br \/>triaged and fixed all vulnerabilities. They also informed us that:<\/p>\n<p>* They are treating such delay as an additional security incident.<br \/>* They added another maintainer to the security group as an immediate action.<br \/>* They plan on discussing this shortcoming on the next maintainer assembly to<br \/>find a long term solution.<\/p>\n<p>The coordinated disclosure timeline follows:<\/p>\n<p>2024-01-10: Reported the first vulnerability to the RIOT project.<br \/>2024-01-11: Reported four more vulnerabilities.<br \/>2024-01-12: Reported the rest of the vulnerabilities.<br \/>2024-02-09: Asked for feedback on &lt;security@riot-os.org&gt;.<br \/>2024-03-05: Asked again for feedback on &lt;security@riot-os.org&gt;.<br \/>2024-04-05: Asked again for feedback via GitHub and got the first reply.<br \/>2024-04-06: Started collaborating with RIOT to evaluate proposed fixes.<br \/>2024-04-10: First security advisory published on GitHub.<br \/>2024-04-17: Another security advisory published on GitHub.<br \/>2024-04-24: Asked for a status update on the remaining reports.<br \/>2024-04-25: Two more security advisories published on GitHub.<br \/>2024-04-26: Another security advisory published on GitHub.<br \/>2024-04-30: Three more security advisories published on GitHub.<br \/>2024-05-07: Published advisory and writeup.<\/p>\n<p>&#8211;[ 7 &#8211; Acknowledgments<\/p>\n<p>We would like to thank RIOT maintainers for triaging and fixing the reported<br \/>vulnerabilities in a particularly friendly and professional way. We really<br \/>appreciated working with them!<\/p>\n<p>&#8211;[ 8 &#8211; References<\/p>\n[1] https:\/\/www.riot-os.org\/<br \/>[2] https:\/\/github.com\/RIOT-OS\/RIOT<br \/>[3] https:\/\/security.humanativaspa.it\/ost2-zephyr-rtos-and-a-bunch-of-cves\/<br \/>[4] https:\/\/security.humanativaspa.it\/multiple-vulnerabilities-in-rt-thread-rtos\/<br \/>[5] https:\/\/security.humanativaspa.it\/big-update-to-my-semgrep-c-cpp-ruleset\/<br \/>[6] https:\/\/security.humanativaspa.it\/a-collection-of-weggli-patterns-for-c-cpp-vulnerability-research\/<br \/>[7] https:\/\/github.com\/gkostka\/lwext4\/blob\/58bcf89a121b72d4fb66334f1693d3b30e4cb9c5\/src\/ext4.c#L75<br \/>[8] https:\/\/docs.github.com\/en\/code-security\/security-advisories<\/p>\n<p>Copyright (c) 2024 Marco Ivaldi and Humanativa Group. All rights reserved.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8211;[ HNS-2024-07 &#8211; HN Security Advisory &#8211; https:\/\/security.humanativaspa.it\/ * Title: Multiple vulnerabilities in RIOT OS* OS: RIOT &lt;= 2024.01* Author: Marco Ivaldi &lt;marco.ivaldi@hnsecurity.it&gt;* Date: 2024-05-07* CVE ID and severity:* CVE-2024-31225 &#8211; High* CVE-2024-32017 &#8211; Critical* CVE-2024-32018 &#8211; High(low-severity vulnerabilities were not assigned a CVE ID)* Vendor URL: https:\/\/www.riot-os.org\/* Advisory URLs: * https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-2572-7q7c-3965* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-v97j-w9m6-c4h3* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-899m-q6pp-hmp3* https:\/\/github.com\/RIOT-OS\/RIOT\/security\/advisories\/GHSA-x3j5-hfrr-5x6q* &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-56714","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/56714","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=56714"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/56714\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=56714"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=56714"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=56714"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}