statfs 尝试大写入导致堆栈溢出

statfs attempting large write causing stack overflow

提问人:AbsoluteBeginner 提问时间:10/24/2023 最后编辑:AbsoluteBeginner 更新时间:10/24/2023 访问量:92

问:

我目前正在用于获取有关路径的一些信息,并且收到运行时堆栈溢出错误:statfs

==33949==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x000103d3d970 at pc 0x00010172b930 bp 0x00016fdfeed0 sp 0x00016fdfe688
WRITE of size 2168 at 0x000103d3d970 thread T0
    #0 0x10172b92c in wrap_statfs+0x2ac (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x2b92c)
    #1 0x107a10ccc in StatFsErr() OtherFile.c:546
    #2 0x1000c3318 in main main.cpp:141
    #3 0x193d43f24  (<unknown module>)

Address 0x000103d3d970 is located in stack of thread T0 at offset 368 in frame
    #0 0x107a10a64 in StatFsErr() OtherFile.c:538

  This frame has 2 object(s):
    [32, 368) 'sb' (line 541)
    [432, 1457) 'path' (line 542) <== Memory access at offset 368 partially underflows this variable

我的代码如下所示:

OtherFile.c:

void StatFsErr()
{
  struct statfs sb;
  char path[PATH_MAX + 1];
  memset(path, 0, sizeof(path));
  path[0] = '/';
  OSStatus    err = statfs(path, &sb);
}

main.cpp

#include "OtherFile.h"
int main(int argc, char **argv)
{
  StatFsErr();
  return 0;
}

奇怪的是,如果我将 StatFsErr() 的主体移动到 main(),我不会得到任何异常,即。

int main(int argc, char **argv)
{
  struct statfs sb;
  char path[PATH_MAX + 1];
  memset(path, 0, sizeof(path));
  path[0] = '/';
  OSStatus    err = statfs(path, &sb);
  return 0;
}

虽然我认为这里存在某种堆栈溢出,但我不明白为什么要尝试如此大的写入。根据我对 Linux 参考的理解,它只是返回有关 in 处的文件的信息,它似乎很舒服地坐在堆栈上。statfsstatfspathsb

如果我这样做,我可以看到这个问题似乎是可以解决的

char sb_buf [2200];
char path[PATH_MAX + 1];
memset(path, 0, sizeof(path));
path[0] = '/';
OSStatus    err = statfs(path, (struct statfs *)sb_buf);

但这并不能帮助我理解为什么似乎写得超出了 .statfssb

谁能启发我正在发生的事情?

谢谢!!

更新:

听从詹姆斯·波尔克会长的建议,我发现这个问题是由于用“-D__DARWIN_64_BIT_INO_T=0”编译了“OtherFile.c”引起的。那么,一个最小的可重复示例将是

main.cpp:

int main(int argc, char **argv)
{
  struct statfs sb;
  char path[PATH_MAX + 1] = "/";
  OSStatus    err = statfs(path, &sb);
  return 0;
}

并使用 编译,这将产生相应的错误消息:main.cpp-D__DARWIN_64_BIT_INO_T=0

=================================================================
==36752==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x000103cb1170 at pc 0x00010169f930 bp 0x00016fdff0b0 sp 0x00016fdfe868
WRITE of size 2168 at 0x000103cb1170 thread T0
    #0 0x10169f92c in wrap_statfs+0x2ac (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x2b92c)
    #1 0x1000bc880 in main main.cpp:11
    #2 0x193d43f24  (<unknown module>)

Address 0x000103cb1170 is located in stack of thread T0 at offset 368 in frame
    #0 0x1000bc604 in main main.cpp:5

  This frame has 2 object(s):
    [32, 368) 'sb' (line 7)
    [432, 1457) 'path' (line 8) <== Memory access at offset 368 partially underflows this variable

我想,由于 APFS 使用 64 位 inode,macOS 内核返回 defined 的 64 位版本,其中 2168 字节大,导致溢出。struct statfsmount.h

有人可以证实是这样吗?

C Linux macOS 堆栈溢出 系统调用

评论

1赞 Weather Vane 10/24/2023
540号线是哪条?代码中一定比显示的十几行要多得多。请发布一个最小可重现示例,这是显示问题的最短完整代码。
0赞 Barmar 10/24/2023
我替换并添加了所需的行,它在我的 Mac 上运行良好。OSStatusint#include
3赞 President James K. Polk 10/24/2023
我猜您正在为 linux 有意义的定义,但实际上在 MacOS 上运行它。这个问题确实需要一个最小的可重复的例子struct statfs
1赞 chux - Reinstate Monica 10/24/2023
@AbsoluteBeginner,旁白:用 or 更简单、更清晰。char path[PATH_MAX + 1]; memset(path, 0, sizeof(path));char path[PATH_MAX + 1] = { 0 };char path[PATH_MAX + 1] = "";
1赞 Ted Lyngmo 10/24/2023
@BenVoigt 这些在 linux 版本中甚至不存在。也许 PresidentJamesK.Polk 在猜测 OP 复制了 linux 标头并在 mac 上使用它时是正确的。struct statfs

答: 暂无答案