mbedtls DTLS 服务器在 64 位桌面上运行,但不在嵌入式系统上

Posted

技术标签:

【中文标题】mbedtls DTLS 服务器在 64 位桌面上运行,但不在嵌入式系统上【英文标题】:mbedtls DTLS server running on 64-bit desktop but not on embedded system 【发布时间】:2022-01-07 15:39:09 【问题描述】:

我正在尝试用我的应用程序上的 DTLS 服务器替换 UDP 通信。

我有一个使用 mbedtls 在我的计算机 (linux mint) 上运行的 DTLS 服务器。应用程序正在读/写而不会崩溃。 (虽然关闭连接尚未正确实施)。 当我在嵌入式系统(32 位 geode)上运行我的应用程序时,应用程序崩溃了。

从 gdb 输出中可以看出,当 read 函数尝试访问部分 mbedtls_ssl_ctx(已被覆盖)时会发生分段错误。

mbedtls_ssl_readmbedtls_ssl_write 从不同的线程调用并同时读取/写入。为了使其线程安全,我启用了MBEDTLS_THREADING_CMBEDTS_THREADING_PTHREAD。 (这样对吗?)

DTLS 服务器的设置实现here。它是在新的“节点”(客户端)连接时设置的。

谁能告诉我一般 DTLS 服务器的设置是否有错误? 或者什么可能导致这个错误?

gdb 输出:

Thread 3 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 3421.3485]
0x08912351 in mbedtls_debug_print_ret (ssl=0xa76d5c3c, level=2, 
    file=0x8ad259c "/home/github/mt_feature_security/implementation/dune/dune/vendor/libraries/mbedtls/library/ssl_msg.c", line=1853, text=0x8ad2bb9 "ssl->f_recv(_timeout)", ret=55)
    at /home/github/mt_feature_security/implementation/dune/dune/vendor/libraries/mbedtls/library/debug.c:115
115         NULL == ssl->conf->f_dbg ||
(gdb) bt
#0  0x08912351 in mbedtls_debug_print_ret (ssl=0xa76d5c3c, level=2, 
    file=0x8ad259c "/home/github/mt_feature_security/implementation/dune/dune/vendor/libraries/mbedtls/library/ssl_msg.c", line=1853, text=0x8ad2bb9 "ssl->f_recv(_timeout)", ret=55)
    at /home/github/mt_feature_security/implementation/dune/dune/vendor/libraries/mbedtls/library/debug.c:115
#1  0x08925319 in mbedtls_ssl_fetch_input (ssl=0xa76d5c3c, nb_want=13)
    at /home/github/mt_feature_security/implementation/dune/dune/vendor/libraries/mbedtls/library/ssl_msg.c:1853
#2  0x0892939b in ssl_get_next_record (ssl=0xa76d5c3c)
    at /home/github/mt_feature_security/implementation/dune/dune/vendor/libraries/mbedtls/library/ssl_msg.c:4379
#3  0x08928364 in mbedtls_ssl_read_record (ssl=0xa76d5c3c, update_hs_digest=1)
    at /home/github/mt_feature_security/implementation/dune/dune/vendor/libraries/mbedtls/library/ssl_msg.c:3727
#4  0x0892a76c in mbedtls_ssl_read (ssl=0xa76d5c3c, 
    buf=0x8d01ea0 <Security::DtlsServer::m_bfr> "", len=16383)
    at /home/github/mt_feature_security/implementation/dune/dune/vendor/libraries/mbedtls/library/ssl_msg.c:5265
#5  0x08701f5f in Security::DtlsServer::Node::read (this=0xa76d53d0)
    at /home/github/mt_feature_security/implementation/dune/dune/src/Security/DtlsServer/Node.cpp:548
#6  0x08702ec0 in Security::DtlsServer::Listener::run (this=0x8ddde40)
    at /home/github/mt_feature_security/implementation/dune/dune/src/Security/DtlsServer/Listener.cpp:94
--Type <RET> for more, q to quit, c to continue without paging--
#7  0x085d57d7 in dune_concurrency_thread_entry_point (data=0x8ddde40)
    at /home/github/mt_feature_security/implementation/dune/dune/src/DUNE/Concurrency/Thread.cpp:90
#8  0xa7fba12e in ?? () from target:/lib/libpthread.so.0
#9  0xa7ce67be in clone () from target:/lib/libc.so.6
(gdb) p *ssl
$1 = conf = 0x66737365, state = 2037148789, renego_status = 1869772576, 
  renego_records_seen = 857761140, major_ver = 1646276913, minor_ver = 1936028793, 
  badmac_seen = 10, f_vrfy = 0x0, p_vrfy = 0x0, f_send = 0x0, f_recv = 0x0, f_recv_timeout = 0x0, 
  p_bio = 0x0, session_in = 0x0, session_out = 0x0, session = 0x0, session_negotiate = 0x0, 
  handshake = 0x0, transform_in = 0x0, transform_out = 0x0, transform = 0x0, 
  transform_negotiate = 0x0, p_timer = 0x0, f_set_timer = 0x0, f_get_timer = 0x0, in_buf = 0x0, 
  in_ctr = 0x0, in_hdr = 0x0, in_len = 0x0, in_iv = 0x0, in_msg = 0x0, in_offt = 0x0, 
  in_msgtype = 0, in_msglen = 0, in_left = 0, in_epoch = 0, next_record_offset = 0, 
  in_window_top = 0, in_window = 0, in_hslen = 0, nb_zero = 0, keep_current_message = 0, 
  disable_datagram_packing = 0 '\000', out_buf = 0x0, out_ctr = 0x0, out_hdr = 0x0, out_len = 0x0, 
  out_iv = 0x0, out_msg = 0x0, out_msgtype = 0, out_msglen = 0, out_left = 0, 
  cur_out_ctr = "\000\000\000\000\000\000\000", mtu = 0, client_auth = 0, hostname = 0x0, 
  alpn_chosen = 0x0, cli_id = 0x0, cli_id_len = 0, secure_renegotiation = 0, verify_data_len = 0, 
  own_verify_data = '\000' <repeats 11 times>, peer_verify_data = '\000' <repeats 11 times>, 
  f_export_keys = 0x0, p_export_keys = 0x0
(gdb) 

【问题讨论】:

【参考方案1】:

根据Mbed TLS knowledge base:

一个线程只能同时使用或访问一个上下文,除非:

访问共享上下文的函数的文档明确声明该函数是线程安全的,或者 您自己执行显式锁定(可能在包装函数中)。

本文继续描述了一些线程安全的情况。 SSL 上下文不是其中之一。不允许在多个线程中使用相同的 SSL 上下文,除非您自己进行锁定。

跨线程分配负载的典型方法是让不同的线程负责不同的连接,但每个连接一次只能由一个线程处理。这适用于 Mbed TLS,前提是您启用了 MBEDTLS_THREADING_C:它将处理握手期间使用的共享资源(签名密钥、会话票证、会话缓存)的并发性。您不能让一个线程写入而另一个线程读取同一连接。

【讨论】:

吉尔斯您好,感谢您的回答。我尝试使用互斥锁来保护所有访问 ssl 上下文(读取、写入、调试)的函数,但我得到了完全相同的结果。据我了解,这应该可以解决问题。任何猜测为什么仍然会发生? @KAMBLY 如果您将程序限制为单个线程,它是否可以工作?如果是这样,您可能仍然在某处缺少互斥锁。不幸的是,这种错误很难调试。

以上是关于mbedtls DTLS 服务器在 64 位桌面上运行,但不在嵌入式系统上的主要内容,如果未能解决你的问题,请参考以下文章

具有不同端口的同一服务器上的 2 个连接 mbedtls

Windows2008 Server r2 64位显示桌面图标的方法

Oracle 11g win7 64位桌面类 && 服务器类安装过程

无法使用 mbedtls 示例客户端连接到 https 服务器

win10如何看笔记本是32位还是64位系统

win7 64位操作系统 电脑桌面出现this computer is being attacked的窗口