我在 Mac OS X 中进行了一些干预(主要是拦截 C 调用),我注意到 ping 应用程序尝试调用 addrlen 值为 16 的 sendto 函数。在 sys/socket.h 中,我可以清楚地看到 sa_data 数组只有最多可容纳 14 个字节:
/*
* [XSI] Structure used by kernel to store most addresses.
*/
struct sockaddr {
__uint8_t sa_len; /* total length */
sa_family_t sa_family; /* [XSI] address family */
char sa_data[14]; /* [XSI] addr value (actually larger) */
};
评论说“实际上更大”让我感到害怕,但我对此无能为力。
无论如何,手册页显示 sendto 函数的签名如下所示:
ssize_t
sendto(int socket,
const void *buffer,
size_t length,
int flags,
const struct sockaddr *dest_addr,
socklen_t dest_len);
然后手册页特别指出如果长度值太长而无法以原子方式传递消息时该怎么办。它忽略了 dest_len 大于 dest_addr.sa_data 可以容纳的情况。
如果我尝试将 16 个字节的数据从调用者复制到另一个 dest_addr.sa_data 中,它会失败并且应用程序会崩溃,这是应该的。我是否误解了该字段的使用方式?为什么标题中的注释说“实际上更大”但随后为数组分配了固定大小?