【问题标题】:LeetCode: Address Sanitizer ViolationsLeetCode:解决消毒剂违规问题
【发布时间】:2020-09-15 21:04:15
【问题描述】:

我正在研究一些示例,但不断收到这些 Address Sanitizer heap-buffer-overflow 错误。我一生都无法弄清楚潜在的溢出在哪里:

bool detectCapitalUse(char * word){
    
    int CapitalLet = 0;
    int WordLen = sizeof(word)/sizeof(char);
    bool result = 0;
    
    for (int i = 0; i < WordLen; i++)
    {
        if (word[i] >= 'A' && word[i] <= 'Z' )
        {
            CapitalLet++;
        }
    }
    
    if( CapitalLet == WordLen )
    {
        result = 1;
    }
    else if ((CapitalLet == 1) && (word[0] >= 'A' && word[0] <= 'Z'))
    {
        result = 1;
    }
    else if (CapitalLet == 0 )
    {
        result = 1;
    }
    else
    {
        result = 0;
    }    
    
    return result;
}

编辑:这是完整的错误消息。

=================================================================
==31==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000017 at pc 0x000000401850 bp 0x7ffcd5e90680 sp 0x7ffcd5e90670
READ of size 1 at 0x602000000017 thread T0
    #2 0x7f2bb38ea82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
0x602000000017 is located 0 bytes to the right of 7-byte region [0x602000000010,0x602000000017)
allocated by thread T0 here:
    #0 0x7f2bb4905f88 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10bf88)
    #4 0x7f2bb38ea82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa[07]fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==31==ABORTING

【问题讨论】:

  • 问题(至少部分)在这里:int WordLen = sizeof(word)/sizeof(char);。参数word (char * word) 在作为参数传递时衰减为指针,因此sizeof(word) 将真正返回sizeof 指针,而不是sizeof 您可能传递的数组。顺便说一句,sizeof(char) 按照定义始终是1。
  • 使用strlen 获取长度。 sizeof 是指针的大小,可能是 8,而不是它指向的分配内存的长度。
  • 所示代码不太可能导致堆溢出。请澄清观察到的不当行为是什么。我能看到的唯一问题(除了没有做它应该做的事情)是单词比指针短。
  • 我很好奇 - 你能发布这个确切代码的确切错误吗?它似乎没有导致堆溢出的语法。

标签: c


【解决方案1】:

因为你的代码中没有使用heap memory,所以没有什么可能导致堆溢出,但是可以解决的问题就在这里:

int WordLen = sizeof(word)/sizeof(char);. 

在论据中

(char * word)   

word 在作为参数传递时衰减为指针,所以

sizeof(word) 

真的会返回一个指针的大小(32 位寻址的 4 个字节),而不是您可能传递的数组的大小。顺便说一句,sizeof(char) 按照定义始终是1。

将表达式改为:

int WordLen = strlen(word);

更改这一行可以让您的代码按我认为的那样工作。我使用以下调用方法对其进行了测试:

int main(void) 
{
    char word[] = {"this is A string"};
    bool res = detectCapitalUse(word);
    return 0;
}

一个警告:
如果您确实在调用函数中使用了动态分配的内存,或者在本文未包含的其他地方,并且尝试访问该块内存不正确,可能会导致 堆缓冲区溢出。

【讨论】:

  • 你是对的。但是您是否认为这会导致 OP 观察到的不当行为(即堆溢出)?我觉得这个问题要么太不清楚,要么无法回答。即使允许对“堆溢出”进行一些创造性的解释:
  • @Yunnosch - 我正在编辑,但是我同意。至少对问题的性质存在一些误解。
  • @ryyker - 你是对的,这就是问题所在。尽管奇怪的是这导致了 LeetCode 认为的“堆溢出”。我在原始文件中发布了运行时错误消息的完整文本(在更改为 strlen 之前)。
  • @nobby - 是的,我看到了错误消息。奇怪的解释:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-28
  • 2021-03-06
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
相关资源
最近更新 更多