未定义的清理无法检测到简单的堆栈越界错误

时间:2019-05-06 09:56:51

标签: c++ indexoutofboundsexception sanitization

from django.db import models
from datetime import datetime

class Posts(models.Model):
      title = models.CharField(max_length=200)
      body = models.TextField()
      created_at = models.DateTimeField(default=datetime.now, blank=True)
      images = models.ImageField(default='')
      author = models.CharField(max_length = 200, default='')

def __str__(self):
      return self.title


class Meta:
   verbose_name_plural = "Posts"

此代码产生了超出界限的情况,其中堆栈值#include <iostream> void fill(int *); int main() { int a[1]; int b[1]; a[0] = 1; b[0] = 2; fill(a); std::cout << *a << " " << *b << std::endl; } void fill (int * x) { x[1] = 3; } b[0]覆盖。

代码已使用

进行编译
fill(a)

但是消毒剂无法检测到错误。

我想念什么吗?

1 个答案:

答案 0 :(得分:6)

  

我想念什么吗?

是的。堆栈溢出是由地址分隔符而不是UB分隔符检测的。使用-fsanitize=address编译您的代码段即可

=17847==ERROR: AddressSanitizer: stack-buffer-overflow on address ... at pc ...

#0 0x10f7f5d44 in fill(int*) (a.out:x86_64+0x100000d44)
#1 0x10f7f5b81 in main (a.out:x86_64+0x100000b81)
#2 0x7fff5f490014 in start (libdyld.dylib:x86_64+0x1014)

...

从技术上讲,堆栈上的越界访问确实会导致未定义的行为。但是,将导致UB的所有内容都放入UB消毒器中,可能会使关注点分离得太少。来自clang address sanitizer docs

  

AddressSanitizer是一种快速内存错误检测器。它由一个编译器检测模块和一个运行时库组成。该工具可以检测以下类型的错误:

     
      
  • 对堆,堆栈和全局变量的越界访问
  •   
  • ...
  •   

同时可以here找到UB消毒器实现的检查列表(再次,是clang文档)。