From c9d7863e5664a169035038628029bb07e090c5ff Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 30 May 2023 14:27:13 +0200 Subject: [PATCH 1/6] gnrc_sixlowpan_iphc: fix NULL pointer dereference --- .../sixlowpan/iphc/gnrc_sixlowpan_iphc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c b/sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c index 81fff4224b..2dac17b3bd 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c +++ b/sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c @@ -1074,12 +1074,18 @@ static size_t _iphc_ipv6_encode(gnrc_pktsnip_t *pkt, uint8_t *iphc_hdr) { gnrc_sixlowpan_ctx_t *src_ctx = NULL, *dst_ctx = NULL; - ipv6_hdr_t *ipv6_hdr = pkt->next->data; + ipv6_hdr_t *ipv6_hdr; bool addr_comp = false; uint16_t inline_pos = SIXLOWPAN_IPHC_HDR_LEN; assert(iface != NULL); + if (pkt->next == NULL) { + DEBUG("6lo iphc: packet missing header\n"); + return 0; + } + ipv6_hdr = pkt->next->data; + /* set initial dispatch value*/ iphc_hdr[IPHC1_IDX] = SIXLOWPAN_IPHC1_DISP; iphc_hdr[IPHC2_IDX] = 0; @@ -1742,6 +1748,14 @@ void gnrc_sixlowpan_iphc_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page) gnrc_sixlowpan_multiplex_by_size(tmp, orig_datagram_size, netif, page); } else { + if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_MINFWD)) { + gnrc_sixlowpan_frag_fb_t *fb = ctx; + + if (fb->pkt == pkt) { + /* free provided fragmentation buffer */ + fb->pkt = NULL; + } + } gnrc_pktbuf_release(pkt); } } From f8a64dfb1c60238320d527c0a06562923ff2a3fb Mon Sep 17 00:00:00 2001 From: Karl Fessel Date: Thu, 25 May 2023 23:04:38 +0200 Subject: [PATCH 2/6] cpu/stm32: stm32f4 BRR from BSRR --- cpu/stm32/include/gpio_ll_arch.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpu/stm32/include/gpio_ll_arch.h b/cpu/stm32/include/gpio_ll_arch.h index 87e0c9d753..7653dd8d63 100644 --- a/cpu/stm32/include/gpio_ll_arch.h +++ b/cpu/stm32/include/gpio_ll_arch.h @@ -77,7 +77,9 @@ static inline void gpio_ll_clear(gpio_port_t port, uword_t mask) #if defined(GPIO_BRR_BR0) && !defined(CPU_FAM_STM32F4) p->BRR = mask; #else - p->BSRR = mask << 16; + /* The first half-word sets GPIOs, the second half-world clears GPIOs */ + volatile uint16_t *brr = (volatile uint16_t *)&(p->BSRR); + brr[1] = (uint16_t)mask; #endif } From 31c6191f6196f1a05c9765cffeadba868e3b0723 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 30 May 2023 14:32:18 +0200 Subject: [PATCH 3/6] gnrc_sixlowpan_frag_sfr: fix ARQ scheduler race-condition --- .../frag/sfr/gnrc_sixlowpan_frag_sfr.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/sfr/gnrc_sixlowpan_frag_sfr.c b/sys/net/gnrc/network_layer/sixlowpan/frag/sfr/gnrc_sixlowpan_frag_sfr.c index c013ef9ff1..adc2054fe6 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/frag/sfr/gnrc_sixlowpan_frag_sfr.c +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/sfr/gnrc_sixlowpan_frag_sfr.c @@ -506,7 +506,6 @@ void gnrc_sixlowpan_frag_sfr_arq_timeout(gnrc_sixlowpan_frag_fb_t *fbuf) int error_no = ETIMEDOUT; /* assume time out for fbuf->pkt */ DEBUG("6lo sfr: ARQ timeout for datagram %u\n", fbuf->tag); - fbuf->sfr.arq_timeout_event.msg.content.ptr = NULL; if (IS_ACTIVE(CONFIG_GNRC_SIXLOWPAN_SFR_MOCK_ARQ_TIMER)) { /* mock-up to emulate time having passed beyond (1us) the ARQ timeout */ now -= (fbuf->sfr.arq_timeout * US_PER_MS) + 1; @@ -681,7 +680,6 @@ static void _clean_slate_datagram(gnrc_sixlowpan_frag_fb_t *fbuf) /* remove potentially scheduled timers for this datagram */ evtimer_del((evtimer_t *)(&_arq_timer), &fbuf->sfr.arq_timeout_event.event); - fbuf->sfr.arq_timeout_event.event.next = NULL; if (gnrc_sixlowpan_frag_sfr_congure_snd_has_inter_frame_gap()) { for (clist_node_t *node = clist_lpop(&_frame_queue); node != NULL; node = clist_lpop(&_frame_queue)) { @@ -1708,13 +1706,26 @@ static void _sched_next_frame(gnrc_sixlowpan_frag_fb_t *fbuf) } } +static inline bool _arq_scheduled(gnrc_sixlowpan_frag_fb_t *fbuf) +{ + evtimer_event_t *ptr = _arq_timer.events; + evtimer_event_t *event = &fbuf->sfr.arq_timeout_event.event; + while (ptr) { + if (ptr == event) { + return true; + } + ptr = ptr->next; + } + return false; +} + static void _sched_arq_timeout(gnrc_sixlowpan_frag_fb_t *fbuf, uint32_t offset) { if (IS_ACTIVE(CONFIG_GNRC_SIXLOWPAN_SFR_MOCK_ARQ_TIMER)) { /* mock does not need to be scheduled */ return; } - if (fbuf->sfr.arq_timeout_event.msg.content.ptr != NULL) { + if (_arq_scheduled(fbuf)) { DEBUG("6lo sfr: ARQ timeout for datagram %u already scheduled\n", (uint8_t)fbuf->tag); return; @@ -1804,7 +1815,6 @@ static void _handle_ack(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt, DEBUG("6lo sfr: cancelling ARQ timeout\n"); evtimer_del((evtimer_t *)(&_arq_timer), &fbuf->sfr.arq_timeout_event.event); - fbuf->sfr.arq_timeout_event.msg.content.ptr = NULL; if ((unaligned_get_u32(hdr->bitmap) == _null_bitmap.u32)) { /* ACK indicates the reassembling endpoint canceled reassembly */ From 1aeb90ee5555ae78b567a6365ae4ab71bfd1404b Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 30 May 2023 14:39:00 +0200 Subject: [PATCH 4/6] gnrc_sixlowpan_frag_rb: fix OOB write in _rbuf_add --- .../sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c b/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c index d406f60576..1112969719 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c @@ -461,6 +461,19 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt, else if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR) && sixlowpan_sfr_rfrag_is(pkt->data)) { entry.super->datagram_size--; + /* Check, if fragment is still small enough to fit datagram size. + * `offset` is 0, as this is the first fragment so it does not have to be added + * here. */ + if (frag_size > entry.super->datagram_size) { + DEBUG_PUTS( + "6lo rfrag: fragment too big for resulting datagram, " + "discarding datagram\n" + ); + gnrc_pktbuf_release(entry.rbuf->pkt); + gnrc_pktbuf_release(pkt); + gnrc_sixlowpan_frag_rb_remove(entry.rbuf); + return RBUF_ADD_ERROR; + } } } } From 9454a50df344274b5bb07756831ffdedfd6d4cd3 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Tue, 30 May 2023 14:35:37 +0200 Subject: [PATCH 5/6] sys/xtimer: improve documentation - Add a deprecation note to xtimer, so that new code hopefully starts using ztimer - Add a hint that `ztimer_xtimer_compat` can be used even after `xtimer` is gone --- sys/include/xtimer.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sys/include/xtimer.h b/sys/include/xtimer.h index 2396599963..13d5ecc216 100644 --- a/sys/include/xtimer.h +++ b/sys/include/xtimer.h @@ -8,11 +8,11 @@ */ /** - * @defgroup sys_xtimer Timers - * @ingroup sys - * @brief Provides a high level timer module to register - * timers, get current system time, and let a thread sleep for - * a certain amount of time. + * @defgroup sys_xtimer xtimer high level timer abstraction layer (deprecated) + * @ingroup sys + * @brief Provides a high level timer module to register + * timers, get current system time, and let a thread sleep for + * a certain amount of time. * * The implementation takes one low-level timer and multiplexes it. * @@ -20,6 +20,19 @@ * number of active timers. The reason for this is that multiplexing is * realized by next-first singly linked lists. * + * @deprecated xtimer has been deprecated in favor of the @ref sys_ztimer + * @note With @ref sys_ztimer_xtimer_compat a compatibility wrapper is + * provided that in the vast majority of cases can function as a + * drop-in replacement. This compatibility wrapper is expected to + * replace `xtimer` in the near future and ensure that code still + * depending on the `xtimer` API continues to function. + * @details Note that at least for long running timers, using + * @ref sys_ztimer instead of the compatibility layer can yield + * lower clock drift and lower power consumption compared to + * using the compatibility layer. For details on how to achieve + * lower clock drift and lower power consumption please consult the + * @ref sys_ztimer documentation. + * * @{ * @file * @brief xtimer interface definitions From 51127f674a3f047dad2218efdbd04c49688b69f7 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Thu, 18 May 2023 00:04:41 +0200 Subject: [PATCH 6/6] drivers/periph/rtc: improve doc on rtc_set_alarm - point out behavior on denormalized time stamps - use errno codes to indicate errors (and adapt the few instances of actual error handling to use them) --- cpu/native/periph/rtc.c | 11 ++++++----- cpu/qn908x/periph/rtc.c | 3 ++- cpu/sam0_common/periph/rtc_rtt.c | 4 +++- drivers/include/periph/rtc.h | 11 ++++++++--- drivers/rtt_rtc/rtt_rtc.c | 1 + 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/cpu/native/periph/rtc.c b/cpu/native/periph/rtc.c index f544c9261d..088e465332 100644 --- a/cpu/native/periph/rtc.c +++ b/cpu/native/periph/rtc.c @@ -22,13 +22,14 @@ * @} */ -#include +#include +#include #include #include -#include +#include -#include "periph/rtc.h" #include "cpu.h" +#include "periph/rtc.h" #include "timex.h" #include "ztimer.h" @@ -206,11 +207,11 @@ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg) { if (!_native_rtc_initialized) { warnx("rtc_set_alarm: not initialized"); - return -1; + return -EIO; } if (!_native_rtc_powered) { warnx("rtc_set_alarm: not powered on"); - return -1; + return -EIO; } struct tm now; diff --git a/cpu/qn908x/periph/rtc.c b/cpu/qn908x/periph/rtc.c index a939fe3a57..968e881e0e 100644 --- a/cpu/qn908x/periph/rtc.c +++ b/cpu/qn908x/periph/rtc.c @@ -20,6 +20,7 @@ * @} */ +#include #include #include "cpu.h" @@ -104,7 +105,7 @@ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg) if (ts <= RTC->SEC) { /* The requested time is in the past at the time of executing this * instruction, so we return invalid time. */ - return -2; + return -EINVAL; } /* If the requested time arrives (SEC_INT should have fired) before we get diff --git a/cpu/sam0_common/periph/rtc_rtt.c b/cpu/sam0_common/periph/rtc_rtt.c index cf46172608..adc7a952dc 100644 --- a/cpu/sam0_common/periph/rtc_rtt.c +++ b/cpu/sam0_common/periph/rtc_rtt.c @@ -26,8 +26,10 @@ * @} */ +#include #include #include + #include "pm_layered.h" #include "periph/rtc.h" #include "periph/rtt.h" @@ -611,7 +613,7 @@ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg) if ((time->tm_year < reference_year) || (time->tm_year > (reference_year + 63))) { - return -2; + return -EINVAL; } /* make sure that preceding changes have been applied */ diff --git a/drivers/include/periph/rtc.h b/drivers/include/periph/rtc.h index aae0b47856..1744cf73da 100644 --- a/drivers/include/periph/rtc.h +++ b/drivers/include/periph/rtc.h @@ -113,9 +113,14 @@ int rtc_get_time_ms(struct tm *time, uint16_t *ms); * @param[in] cb Callback executed when alarm is hit. * @param[in] arg Argument passed to callback when alarm is hit. * - * @return 0 for success - * @return -2 invalid `time` parameter - * @return -1 other errors + * @note The driver must be prepared to work with denormalized time values + * (e.g. seconds > 60). The driver may normalize the value, or just + * keep it denormalized. In either case, the timeout should occur at + * the equivalent normalized time. + * + * @retval 0 success + * @return -EINVAL @p time was invalid (e.g. in the past, out of range) + * @return <0 other error (negative errno code to indicate cause) */ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg); diff --git a/drivers/rtt_rtc/rtt_rtc.c b/drivers/rtt_rtc/rtt_rtc.c index 2e3bed2dc3..139523d3cf 100644 --- a/drivers/rtt_rtc/rtt_rtc.c +++ b/drivers/rtt_rtc/rtt_rtc.c @@ -23,6 +23,7 @@ * @} */ +#include #include #include