【问题标题】:Coverity - overrun of struct typeCoverity - 结构类型溢出
【发布时间】:2015-09-01 08:56:12
【问题描述】:

我通过覆盖工具收到以下错误 -

overrun-buffer-arg:通过将结构类型 in_addr 传递给使用参数“8UL”在字节偏移量 7 处访问它的函数,溢出 4 个字节的结构类型。

示例代码:

static u_long   addr;
static struct   sockaddr_in remote_server;
addr = inet_addr(remote_servername);
memcpy((char *) &remote_server.sin_addr, (char *)&addr, sizeof(addr));

在最后一行,我得到了上述错误。

有人可以通过一些线索,出了什么问题。

如果您需要更多信息,请告诉我。

【问题讨论】:

  • 正如消息中所说,u_longin_addr 大(显然是 4)。
  • u_long 也是 4 字节大小
  • 我在solaris 10 OS中检查过,显示u_long的大小为4
  • Coverity 认为是 8 个字节。

标签: c sockets


【解决方案1】:

标准警告:不要将指针投射到/来自void *

对于消息:仔细阅读,它很好地说明了问题。只是一个提示:使用正确的类型。您显然正在访问超出其大小的结构。 u_long 究竟有多大?

addr 应正确序列化为 uint8_t[],尊重字节序。当您从第二个参数中获取sizeof() 时,显然第一个参数更短。

为什么你不只是分配,而是使用memcpy()?检查两者是否具有相同的类型。

【讨论】:

  • 感谢您的回复。 addr 应该具有数据类型 uint32_t 对吗?我在库中看到,remote_server.sin_addr.s_addr 的数据类型为 uint32_t。
  • @GajendraBagali:是的。请只使用 memcpy() 复制内存块,例如结构或数组。不要复制标量!只需使用分配。并且:启用并遵循警告;我强烈建议至少为 gcc 启用-Wall -Wextra(对于不同的编译器,请选择类似的东西)!如果没有启用警告,上述问题(“截断警告”)可能不会被报告。 C 在所有方面都不是类型安全的,但现代编译器警告 _many_(!) 问题! (注意:从这个意义上说,VC 不是现代编译器)
  • 其实那是遗留代码。他们使用 memcpy 分配标量!是的,我尝试启用 -Wall -Wextra。
  • @GajendraBagali:我理解你的问题。如果他们这样做了,那不仅仅是“遗产”,而是被设计破坏了。做这件事的人应该是……好吧,实际上你可能比我有更好的想法;-)
【解决方案2】:

inet_addr() 返回一个 in_addr_t,而不是一个 u_long。 struct sockaddr_in 的 sin_addr 是一个 struct in_addr,里面保存了一个 in_addr_t s_addr。

这应该可以解决问题:

static struct   sockaddr_in remote_server;
remote_server.sin_addr.s_addr = inet_addr(remote_servername);

【讨论】:

  • 这真的成功了。虽然我们必须检查 inet_addr(remote_servername) 的返回值作为错误检查的一部分。
  • 如果您有不受信任的输入,最好不要首先使用 inet_addr()。使用 inet_aton() 代替: static struct sockaddr_in remote_server; if (inet_aton(remote_servername, &remote_server.sin_addr)) { /* error */ }
猜你喜欢
  • 1970-01-01
  • 2014-11-26
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 2020-12-30
  • 2021-07-12
  • 1970-01-01
相关资源
最近更新 更多