Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global-buffer-overflow in coap_parse_oscore_conf_mem function in src/coap_oscore.c #1117

Closed
grandnew opened this issue May 21, 2023 · 3 comments · Fixed by #1118
Closed

Global-buffer-overflow in coap_parse_oscore_conf_mem function in src/coap_oscore.c #1117

grandnew opened this issue May 21, 2023 · 3 comments · Fixed by #1118

Comments

@grandnew
Copy link

grandnew commented May 21, 2023

Environment

  • libcoap version: v4.3.1-162-g6f79db0
  • Build System: Make
  • Operating System: Linux
  • Operating System Version: Debian GNU/Linux 11 (bullseye)
  • Hosted Environment: None

Problem Description

There is a global-buffer-overflow bug in the coap_parse_oscore_conf_mem function in src/coap_oscore.c.

Expected Behavior

No crash.

Actual Behavior

Crash when enhanced with ASan.

Steps to reproduce

  1. Build libcoap with ASan
CC=clang CFLAGS="-g -fsanitize=address" ./autogen.sh
CC=clang CFLAGS="-g -fsanitize=address" ./configure --disable-doxygen --disable-manpages --enable-tests --disable-documentation --enable-examples --enable-shared
CC=clang CFLAGS="-g -fsanitize=address" make -j
  1. Compile overflow.c (as shown follows)
clang overflow.c -I/root/libcoap/include -I/root/libcoap /root/libcoap/.libs/libcoap-3-gnutls.a  /usr/local/lib/libgnutls.so -g -fsanitize=address -o overflow
  1. Run overflow and detect ASan error
==869262==ERROR: AddressSanitizer: global-buffer-overflow on address 0x5567c1231cea at pc 0x5567c1079006 bp 0x7ffcdaa591c0 sp 0x7ffcdaa58970
READ of size 12 at 0x5567c1231cea thread T0
    #0 0x5567c1079005 in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long) (/root/libcoap/overflow+0x57005) (BuildId: 54eb8810f12f7eb05271c5e5354411ec106ffe25)
    #1 0x5567c10794f9 in memcmp (/root/libcoap/overflow+0x574f9) (BuildId: 54eb8810f12f7eb05271c5e5354411ec106ffe25)
    #2 0x5567c1128e03 in coap_parse_oscore_conf_mem /root/libcoap/src/coap_oscore.c:1849:11
    #3 0x5567c112849d in coap_new_oscore_conf /root/libcoap/src/coap_oscore.c:2020:37
    #4 0x5567c111ca1f in main /root/libcoap/overflow.c:24:17
    #5 0x7fb67e995d09 in __libc_start_main csu/../csu/libc-start.c:308:16
    #6 0x5567c105da29 in _start (/root/libcoap/overflow+0x3ba29) (BuildId: 54eb8810f12f7eb05271c5e5354411ec106ffe25)

0x5567c1231cea is located 54 bytes to the left of global variable '.str.74' defined in '/root/libcoap/src/coap_oscore.c:1790' (0x5567c1231d20) of size 14
  '.str.74' is ascii string 'replay_window'
0x5567c1231cea is located 22 bytes to the left of global variable '.str.73' defined in '/root/libcoap/src/coap_oscore.c:1788' (0x5567c1231d00) of size 11
  '.str.73' is ascii string 'id_context'
0x5567c1231cea is located 0 bytes to the right of global variable '.str.72' defined in '/root/libcoap/src/coap_oscore.c:1787' (0x5567c1231ce0) of size 10
  '.str.72' is ascii string 'sender_id'
SUMMARY: AddressSanitizer: global-buffer-overflow (/root/libcoap/overflow+0x57005) (BuildId: 54eb8810f12f7eb05271c5e5354411ec106ffe25) in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long)
Shadow bytes around the buggy address:
  0x0aad7823e340: 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 04 f9 f9 f9
  0x0aad7823e350: f9 f9 f9 f9 00 00 00 00 00 00 03 f9 f9 f9 f9 f9
  0x0aad7823e360: 05 f9 f9 f9 06 f9 f9 f9 00 00 00 00 00 00 06 f9
  0x0aad7823e370: f9 f9 f9 f9 06 f9 f9 f9 04 f9 f9 f9 00 f9 f9 f9
  0x0aad7823e380: 05 f9 f9 f9 05 f9 f9 f9 00 04 f9 f9 00 00 07 f9
=>0x0aad7823e390: f9 f9 f9 f9 00 06 f9 f9 00 04 f9 f9 00[02]f9 f9
  0x0aad7823e3a0: 00 03 f9 f9 00 06 f9 f9 00 01 f9 f9 00 01 f9 f9
  0x0aad7823e3b0: 00 01 f9 f9 00 06 f9 f9 00 04 f9 f9 00 00 01 f9
  0x0aad7823e3c0: f9 f9 f9 f9 00 00 04 f9 f9 f9 f9 f9 00 00 02 f9
  0x0aad7823e3d0: f9 f9 f9 f9 00 00 02 f9 f9 f9 f9 f9 00 00 04 f9
  0x0aad7823e3e0: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==869262==ABORTING

Code to reproduce this issue

// overflow.c
#include "coap3/coap_internal.h"
#include "oscore/oscore.h"
#include "oscore/oscore_context.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
 static const char conf_data[] =
    "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
    "master_salt,hex,\"9e7ca92223786340\"\n"
    "sender_id,hex,\"\"\n"
    "recipient_id,hex,\"01\"\n";
  const coap_str_const_t conf = { sizeof(conf_data)-1,
                                  (const uint8_t *)conf_data };
  coap_context_t ctx[1];
  coap_oscore_conf_t *oscore_conf;
  cose_encrypt0_t cose[1];
  uint8_t nonce_buffer[13];
  coap_bin_const_t nonce = { 13, nonce_buffer };

  memset(&ctx, 0, sizeof(ctx));
  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);

  oscore_free_contexts(ctx);
  return 0;
}

Debug Logs

(gdb) b coap_oscore.c:1849
Breakpoint 1 at 0x106d39: file src/coap_oscore.c, line 1849.
(gdb) r
Starting program: /root/libcoap/overflow 
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, coap_parse_oscore_conf_mem (conf_mem=...) at src/coap_oscore.c:1849
1849          if (memcmp(oscore_config[i].keyword, keyword.s, keyword.length) == 0 &&
(gdb) display oscore_config[i]
1: oscore_config[i] = {keyword = 0x562f6227aca0 <str> "master_secret", encoding = 3, offset = 0, text_mapping = 0x0}
(gdb) display keyword
2: keyword = {length = 13, 
  s = 0x562f62279660 <main.conf_data> "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\nmaster_salt,hex,\"9e7ca92223786340\"\nsender_id,hex,\"\"\nrecipient_id,hex,\"01\"\n"}
(gdb) c
Continuing.

Breakpoint 1, coap_parse_oscore_conf_mem (conf_mem=...) at src/coap_oscore.c:1849
1849          if (memcmp(oscore_config[i].keyword, keyword.s, keyword.length) == 0 &&
1: oscore_config[i] = {keyword = 0x562f6227aca0 <str> "master_secret", encoding = 3, offset = 0, text_mapping = 0x0}
2: keyword = {length = 11, s = 0x562f62279695 <main.conf_data+53> "master_salt,hex,\"9e7ca92223786340\"\nsender_id,hex,\"\"\nrecipient_id,hex,\"01\"\n"}
(gdb) c
Continuing.

Breakpoint 1, coap_parse_oscore_conf_mem (conf_mem=...) at src/coap_oscore.c:1849
1849          if (memcmp(oscore_config[i].keyword, keyword.s, keyword.length) == 0 &&
1: oscore_config[i] = {keyword = 0x562f6227acc0 <str> "master_salt", encoding = 3, offset = 8, text_mapping = 0x0}
2: keyword = {length = 11, s = 0x562f62279695 <main.conf_data+53> "master_salt,hex,\"9e7ca92223786340\"\nsender_id,hex,\"\"\nrecipient_id,hex,\"01\"\n"}
(gdb) c
Continuing.

Breakpoint 1, coap_parse_oscore_conf_mem (conf_mem=...) at src/coap_oscore.c:1849
1849          if (memcmp(oscore_config[i].keyword, keyword.s, keyword.length) == 0 &&
1: oscore_config[i] = {keyword = 0x562f6227aca0 <str> "master_secret", encoding = 3, offset = 0, text_mapping = 0x0}
2: keyword = {length = 9, s = 0x562f622796b8 <main.conf_data+88> "sender_id,hex,\"\"\nrecipient_id,hex,\"01\"\n"}
(gdb) c
Continuing.

Breakpoint 1, coap_parse_oscore_conf_mem (conf_mem=...) at src/coap_oscore.c:1849
1849          if (memcmp(oscore_config[i].keyword, keyword.s, keyword.length) == 0 &&
1: oscore_config[i] = {keyword = 0x562f6227acc0 <str> "master_salt", encoding = 3, offset = 8, text_mapping = 0x0}
2: keyword = {length = 9, s = 0x562f622796b8 <main.conf_data+88> "sender_id,hex,\"\"\nrecipient_id,hex,\"01\"\n"}
(gdb) c
Continuing.

Breakpoint 1, coap_parse_oscore_conf_mem (conf_mem=...) at src/coap_oscore.c:1849
1849          if (memcmp(oscore_config[i].keyword, keyword.s, keyword.length) == 0 &&
1: oscore_config[i] = {keyword = 0x562f6227ace0 <str> "sender_id", encoding = 3, offset = 16, text_mapping = 0x0}
2: keyword = {length = 9, s = 0x562f622796b8 <main.conf_data+88> "sender_id,hex,\"\"\nrecipient_id,hex,\"01\"\n"}
(gdb) c
Continuing.

Breakpoint 1, coap_parse_oscore_conf_mem (conf_mem=...) at src/coap_oscore.c:1849
1849          if (memcmp(oscore_config[i].keyword, keyword.s, keyword.length) == 0 &&
1: oscore_config[i] = {keyword = 0x562f6227aca0 <str> "master_secret", encoding = 3, offset = 0, text_mapping = 0x0}
2: keyword = {length = 12, s = 0x562f622796c9 <main.conf_data+105> "recipient_id,hex,\"01\"\n"}
(gdb) c
Continuing.

Breakpoint 1, coap_parse_oscore_conf_mem (conf_mem=...) at src/coap_oscore.c:1849
1849          if (memcmp(oscore_config[i].keyword, keyword.s, keyword.length) == 0 &&
1: oscore_config[i] = {keyword = 0x562f6227acc0 <str> "master_salt", encoding = 3, offset = 8, text_mapping = 0x0}
2: keyword = {length = 12, s = 0x562f622796c9 <main.conf_data+105> "recipient_id,hex,\"01\"\n"}
(gdb) c
Continuing.

Breakpoint 1, coap_parse_oscore_conf_mem (conf_mem=...) at src/coap_oscore.c:1849
1849          if (memcmp(oscore_config[i].keyword, keyword.s, keyword.length) == 0 &&
1: oscore_config[i] = {keyword = 0x562f6227ace0 <str> "sender_id", encoding = 3, offset = 16, text_mapping = 0x0}
2: keyword = {length = 12, s = 0x562f622796c9 <main.conf_data+105> "recipient_id,hex,\"01\"\n"}
(gdb) c
Continuing.

[Then crashes]
@mrdeep1
Copy link
Collaborator

mrdeep1 commented May 22, 2023

It is appreciated that you are checking the libcoap code for potential issues and giving detail to be able to reproduce the issue. This has been fixed in #1118 which is ready for further testing.

Note that you need to add coap_context_oscore_server(ctx, oscore_conf); before oscore_free_contexts(ctx); to your overflow.c file to prevent memory leak errors being reported.

@risicle
Copy link

risicle commented Aug 19, 2023

CVE-2023-35862 claims this makes 4.3.1 vulnerable, but I think I'm right in saying oscore code wasn't even present in 4.3.1?

@mrdeep1
Copy link
Collaborator

mrdeep1 commented Aug 19, 2023

@risicle You are correct. The OSCORE code was added in sometime after 4.3.1 was released, and this issue is fixed in #1118 which is included in 4.3.2rc1 and later..

daniel-lang added a commit to daniel-lang/buildroot that referenced this issue Sep 6, 2023
According to a collaborator [0] the affected code isn't in 4.3.1

[0]: obgm/libcoap#1117

Signed-off-by: Daniel Lang <dalang@gmx.at>
arnout pushed a commit to buildroot/buildroot that referenced this issue Sep 22, 2023
According to a collaborator [0] the affected code isn't in 4.3.1

[0]: obgm/libcoap#1117

Signed-off-by: Daniel Lang <dalang@gmx.at>
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>
arnout pushed a commit to buildroot/buildroot that referenced this issue Sep 26, 2023
According to a collaborator [0] the affected code isn't in 4.3.1

[0]: obgm/libcoap#1117

Signed-off-by: Daniel Lang <dalang@gmx.at>
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>
(cherry picked from commit 20c023a)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
arnout pushed a commit to buildroot/buildroot that referenced this issue Sep 26, 2023
According to a collaborator [0] the affected code isn't in 4.3.1

[0]: obgm/libcoap#1117

Signed-off-by: Daniel Lang <dalang@gmx.at>
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>
(cherry picked from commit 20c023a)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
arnout pushed a commit to buildroot/buildroot that referenced this issue Sep 26, 2023
According to a collaborator [0] the affected code isn't in 4.3.1

[0]: obgm/libcoap#1117

Signed-off-by: Daniel Lang <dalang@gmx.at>
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>
(cherry picked from commit 20c023a)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants