Linked List in RIOT OS

Hi…I have been trying to use the list implementation in riot os.

#include "wot_list.h"
#include <stdlib.h>
#include <stdio.h>
#include "kernel_defines.h"

static list_node_t head = { .next = NULL };

wot_cert_t *wot_cert_add(char *name, int name_len, uint8_t *pubkey)
{
    wot_cert_t *node = calloc(1, sizeof(wot_cert_t));
    memcpy(&node->name, name, name_len);
    memcpy(&node->pubkey, pubkey, PUB_KEY_SIZE);
    list_add(&head, &node->next);
    return node;
}

wot_cert_t *wot_cert_find(list_node_t *head, char *name)
{
    for (list_node_t *n = head->next; n; n = n->next) {
        wot_cert_t *node = container_of(n, wot_cert_t, next);
        if (strncmp(node->name, name, sizeof(node->name)) == 0) {
            return node;
        }
    }
    return NULL;
}

and the wot_cert_t structure has the following format.

typedef struct {
    list_node_t next;
    char name[COMMON_NAME_MAX_LEN];
    uint8_t pubkey[PUB_KEY_SIZE];
}wot_cert_t;

using the function wot_cert_add, I am adding a new node to the list.But this operation somehow affects the ifconfig command in riot os. before calling the wot_cert_add function, ifconfig gives the following output.

> ifconfig
ifconfig
Iface  7  HWaddr: CE:1B:08:51:92:1A 
          L2-PDU:1500  MTU:1500  HL:64  Source address length: 6
          Link type: wired
          inet6 addr: fe80::cc1b:8ff:fe51:921a  scope: link  VAL
          inet6 group: ff02::1
          inet6 group: ff02::1:ff51:921a

after adding node in list,for eg. a node with name “alice123”, ifconfig gives the following output.

> ifconfig
ifconfig
Iface  7  HWaddr: CE:1B:08:51:92:1A 
          L2-PDU:1500  MTU:1500  HL:64  Source address length: 6
          Link type: wired
          inet6 addr: fe80::cc1b:8ff:fe51:921a  scope: link  VAL
          inet6 group: ff02::1
          inet6 group: ff02::1:ff51:921a
          alice123s -h

I have not touched the working of ifconfig command, and the last field if the command shows the name of a node,I have added in the list with some garbage.why does this happen ?

Could someone help me to resolve this issue ?

@ad6sh Can you tell me what wot is referring to?

in my usecase,wot refers to web of trust…but the name can be anything. For eg, wot_cert_t can be xyz_cert_t. I just have issue with the List implementation.

list_add(&head, &node->next);

The second arg needs to be &node, its nexr ptr is random garbage at that point.

Btw, don’t omit checking the calloc return value!

@Kaspar thanks for the reply…both parameters of list_add function ,should be of the type list_node_t . and in my code,node refers to structure of the type wot_cert_t. I was trying something like this.

ah, right.

so, to me the list usage looks fine. that means there must be some memory corruption. the calloc call does yield a valid pointer, I guess?

Hey,

On Wed, Mar 09, 2022 at 11:25:49AM +0000, Kaspar Schleiser via RIOT wrote:

so, to me the list usage looks fine. that means there must be some memory corruption. the calloc call does yield a valid pointer, I guess?

just double-checking: which calloc implementation is actually used here?

Cheers Oleg

printk(KERN_CRIT PFX “Reboot didn’t ???\n”); linux-2.6.6/drivers/char/watchdog/softdog.c

@Kaspar calloc does return a valid pointer.The list_add function also works,I think.Because I could search for a stored node using “wot_cert_find(list_node_t *head, char *name)” function used in my code and I get stored node as return.

wot_cert_t *wot_cert_find(list_node_t *head, char *name)
{
    for (list_node_t *n = head->next; n; n = n->next) {
        wot_cert_t *node = container_of(n, wot_cert_t, next);
        if (strncmp(node->name, name, sizeof(node->name)) == 0) {
            return node;
        }
    }
    return NULL;
}

can you share the code (not just the snippets)? your snipped probably unearthed some bug.

@Kaspar

  1. here I am sharing the whole source code of my project.I have added usage and issues in readme file and also how to reproduce the error that I have mentioned.
  2. I have also tested my list implementation separately.But everything seems to work fine there.“ifconfig” produces the same output ,before and after adding items in the list. When I use the same list implementation in my original project,I can see the mentioned issue with “ifconfig”.

Please ping me,If my readme file is not clear to understand :sweat_smile:

Hey Adarsh,

On Thu, Mar 10, 2022 at 07:31:37PM +0000, Adarsh Raghoothaman via RIOT wrote:

  1. here I am sharing the whole source code of my project.I have added usage and issues in readme file and also how to reproduce the error that I have mentioned.

I tried to reproduce the bug by following the instructions using RIOT 2022.01. However I get a segfault in the client application when I call "wotc -v psk ". The segfault happens somewhere in the CBOR code and traces back to wot_parse_cbor_cert().

Probably you have some memory corruption anywhere else. I couldn’t figure it out on the first glance.

Cheers Oleg

The problem with token ring jokes is you need to wait your turn to laugh

@oleg thanks for checking the project.Unfortunately,I was not able to reproduce the segfault and the messages are exchanged as expected.Anyway I will debug check for memory corruption. :+1:

I followed the steps on the readme, also getting a segfault:

(gdb) bt
#0  0xf7dd7404 in __memcpy_sse2_unaligned () from /usr/lib32/libc.so.6
#1  0x0806757f in iterate_memcpy (dest=0x80730ef "", 
    src=0x80a132b <_listen_buf+11> "rd1cnX@6\337\342\306\371\362\355)\332\n\232\217bhN\221cu\272\020\060\f(\305\344|\373\362_\245\217Rq\240\324\374\336\032\270xZ<xi5\247ϫ\351?\230r\t\332\355\vO\253\303o\307r\370)i5\247ϫ\351?\230r\t\332\355\vO\253\303o\307r\370)^\206\233\265\242W", <incomplete sequence \343>, len=5) at /home/kaspar/src/riot/build/pkg/tinycbor/src/cborparser.c:1180
#2  0x08068247 in iterate_string_chunks (value=<optimized out>, buffer=0x80730ef "", buflen=0x80a4fdc <_msg_stack+15388>, 
    result=0x80a4fab <_msg_stack+15339>, next=0x80a4ffc <_msg_stack+15420>, func=0x8067553 <iterate_memcpy>)
    at /home/kaspar/src/riot/build/pkg/tinycbor/src/cborparser.c:1214
#3  0x080682fe in _cbor_value_copy_string (value=0x80a4ffc <_msg_stack+15420>, buffer=0x80730ef, buflen=0x80a4fdc <_msg_stack+15388>, 
    next=0x80a4ffc <_msg_stack+15420>) at /home/kaspar/src/riot/build/pkg/tinycbor/src/cborparser.c:1302
#4  0x0804e1af in cbor_value_copy_text_string (next=0x80a4ffc <_msg_stack+15420>, buflen=0x80a4fdc <_msg_stack+15388>, buffer=0x80730ef "", 
    value=0x80a4ffc <_msg_stack+15420>) at /home/kaspar/src/riot/build/pkg/tinycbor/src/cbor.h:493
#5  wot_parse_cbor_cert (
    payload=0x80a1329 <_listen_buf+9> "\202erd1cnX@6\337\342\306\371\362\355)\332\n\232\217bhN\221cu\272\020\060\f(\305\344|\373\362_\245\217Rq\240\324\374\336\032\270xZ<xi5\247ϫ\351?\230r\t\332\355\vO\253\303o\307r\370)i5\247ϫ\351?\230r\t\332\355\vO\253\303o\307r\370)^\206\233\265\242W", <incomplete sequence \343>, payload_len=73) at /home/kaspar/tmp/doriot_certificate_exchange/doriot_wot/doriot_wot_cl/wot_cbor.c:84
#6  0x0804e84d in _resp_handler (memo=0x808e128 <_coap_state+8>, pdu=0x80a50f0 <_msg_stack+15664>, remote=0x80a51a4 <_msg_stack+15844>)
    at /home/kaspar/tmp/doriot_certificate_exchange/doriot_wot/doriot_wot_cl/wot_client.c:88
#7  0x0805186d in _process_coap_pdu (sock=sock@entry=0x80a51bc <_msg_stack+15868>, remote=remote@entry=0x80a51a4 <_msg_stack+15844>, 
    buf=buf@entry=0x80a1320 <_listen_buf> "RE\360\032\022\322\301<\377\202erd1cnX@6\337\342\306\371\362\355)\332\n\232\217bhN\221cu\272\020\060\f(\305\344|\373\362_\245\217Rq\240\324\374\336\032\270xZ<xi5\247ϫ\351?\230r\t\332\355\vO\253\303o\307r\370)i5\247ϫ\351?\230r\t\332\355\vO\253\303o\307r\370)^\206\233\265\242W", <incomplete sequence \343>, len=82, truncated=false)
    at /home/kaspar/src/riot/sys/net/application_layer/gcoap/gcoap.c:424
#8  0x08051c5d in _on_sock_dtls_evt (sock=0x80a1080 <_sock_dtls>, type=SOCK_ASYNC_MSG_RECV, arg=0x0)
    at /home/kaspar/src/riot/sys/net/application_layer/gcoap/gcoap.c:265
#9  0x08066be5 in _event_handler (ev=0x80a10ac <_sock_dtls+44>) at /home/kaspar/src/riot/sys/net/sock/async/event/sock_async_event.c:33
#10 0x080509a4 in event_loop_multi (n_queues=1, queues=0x80a13a0 <_queue>) at /home/kaspar/src/riot/sys/include/event.h:409
#11 event_loop (queue=0x80a13a0 <_queue>) at /home/kaspar/src/riot/sys/include/event.h:431
#12 _event_loop (arg=0x0) at /home/kaspar/src/riot/sys/net/application_layer/gcoap/gcoap.c:181
#13 0xf7ca8789 in makecontext () from /usr/lib32/libc.so.6
#14 0x00000000 in ?? ()

For current RIOT master, I had to add a line to the gcoap_listener definition: Untitled · GitHub

@Kaspar thanks for the update :+1:.I have tried to once again to get the segfault.but it just works without any errors :sweat_smile:. Its a bit weird that I’m not able to get the segfault from the same code :grinning:

I’m on RIOT 08c2cf6b279b7c5793de99c5ccf1bf51ed023331, maybe there was a change upstream that causes breakage?

maybe try building the client with BOARD=native make all-asan, enabling the address sanitizer. It has somewhat more info on the thing, and might catch it even if it doesn’t segfault on your system.

1 Like

@Kaspar thanks ! after enabling address sanitizer I can see buffer over flow in my cbor parser :grinning:.

I am using RIOT Version: 2022.01.