【问题标题】:How to access data written in a socket without reading it如何在不读取套接字的情况下访问写入的数据
【发布时间】:2019-06-11 13:47:36
【问题描述】:

我正在开发具有 Linux 的嵌入式系统。 客户端线程正在套接字中写入一些数据,但另一端正在读取的服务器线程与写入的不同。这导致线程(和父进程)崩溃。

我是网络和 Linux 的新手。 我已经转储了正在写入的每条数据,一切都很好。

gdb 中的函数跟踪显示以下信息。

(gdb) 
#0  0x00007f62be8e8670 in getenv () from /lib/libc.so.6
#1  0x00007f62be92057a in __libc_message () from /lib/libc.so.6
#2  0x00007f62be99f927 in __fortify_fail () from /lib/libc.so.6
#3  0x00007f62be99f8f0 in __stack_chk_fail () from /lib/libc.so.6
#4  0x0000000000406471 in reading (sockFd=15) at __line_number_in_the_program__
#5  0x793bcf318b18bb01 in ?? ()
#6  0x117d0300942ff567 in ?? ()
#7  0x0000000100000000 in ?? ()
..
..
..

直到 #785 带有一些 [随机] 地址。

reading() 是在服务器线程中处理读取数据的函数。

我怀疑套接字内部出了点问题。 有什么方法可以查看套接字(客户端/服务器)缓冲区中的数据而不读取它? 或者有什么其他方法可以用 gdb 进一步调试?

已经有一些检查可以正确处理读取的数据,但这些也无济于事。

【问题讨论】:

  • 不行,socket发送/接收缓冲区是由内核管理的,不能暴露给用户空间,否则会出现linux内核的安全问题
  • 如果这些是 AF_INET or AF_INET6 套接字(TCP 或 UDP),那么像 WiresharkFiddler 这样的工具对于调试此类问题非常有用。 Wireshark 可让您查看数据包中发生的情况。如果您的协议基于 HTTP,Fiddler 非常有用,并且即使对于加密的 HTTPS 连接也可以显示请求/响应的完整历史记录。
  • 套接字内部几乎可以肯定没有任何问题。虽然从技术上讲,您可能在 Linux 内核中发现了一个错误,但请记住,Linux 在数亿台机器上使用,其中大多数依赖于网络。因此,极不可能找到会更改套接字内数据的错误。您很有可能在自己的代码中出错。
  • 谢谢@PhilipCouling。使用 Wireshark 是个好主意。如果有帮助,我会检查一下。由于通信是在 localhost 中进行的,因此将使用带有环回地址的 Wireshark。我也承认你的第二条评论。
  • 是的,有。查找recv(2)MSG_PEEK 标志。这对于调试程序是否有用是完全不同的问题——这是非常值得怀疑的。您的“服务器”应该能够处理格式错误的数据,而不是像表面上那样进行递归旅行或炸毁堆栈。

标签: linux networking linux-kernel c


【解决方案1】:

您遇到了堆栈缓冲区溢出问题。如果您从未听说过 GCC 堆栈保护器,那么现在是时候查找它了。虽然 Wireshark 是查看动态数据的明显工具,但这不是您的问题所在。您的服务器应该能够抵御从网络读取的任何和所有恶意数据。这是基本的良好服务器设计和实现实践。 您遇到了堆栈缓冲区溢出问题。

【讨论】:

  • 这当然是需要解决的问题,但一定是问题的答案。 OP 认为崩溃是由于接收到的数据不正确造成的。接收程序在接收和解析不良数据时绝对应该避免堆栈溢出错误(是的),但如果发送方发送不良数据,防止这种情况并不能解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 2019-04-05
  • 2011-12-13
  • 2017-09-11
  • 1970-01-01
相关资源
最近更新 更多