MengRao / fmtlog

fmtlog is a performant fmtlib-style logging library with latency in nanoseconds.
MIT License
795 stars 121 forks source link

打印字符串可能出现内存越界风险 #75

Closed colderleo closed 1 year ago

colderleo commented 1 year ago

如果以下面的形式打印字符串:

logi("teststr={:.12s}", teststr);

程序运行时会首先拷贝teststr指向的完整字符串,而不是只拷贝12个字符。当teststr并不是以\0结尾的字符串时,就可能导致内存访问越界。

测试程序如下:

  constexpr int pagesize = 4096;

  // mmap得到一个内存上孤立的页,使得访问teststr[4096]会出现内存越界
  char *teststr = (char *)mmap((void*)0x60000000ULL, pagesize, PROT_READ | PROT_WRITE , MAP_SHARED | MAP_ANONYMOUS , -1, 0);
  if(teststr == MAP_FAILED) 
  {
    perror("map failed");
    return -1;
  }
  for(int i=0; i<pagesize; ++i) {
    char *tmp = teststr+i;
    *tmp = 's';
  }

  //teststr[4095] = 0; 加上这句则不会出错

  // fmt::print("teststr={:.12s}\n", teststr);
  logi("teststr={:.12s}", teststr);

实测fmt::print 和 logi都会出现segment fault,所以在使用的时候有什么方法可以避免该问题?

MengRao commented 1 year ago

可以使用string_view,比如logi("teststr={}", std::string_view(test_str, 12);

colderleo commented 1 year ago

感谢!