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_read
和 mbedtls_ssl_write
从不同的线程调用并同时读取/写入。为了使其线程安全,我启用了MBEDTLS_THREADING_C
和MBEDTS_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 位桌面上运行,但不在嵌入式系统上的主要内容,如果未能解决你的问题,请参考以下文章
Windows2008 Server r2 64位显示桌面图标的方法
Oracle 11g win7 64位桌面类 && 服务器类安装过程