[英]Recommended way to track down array out-of-bound access/write in C program
[英]Is it safe to use an out-of-bound index with an smaller array, which is casted from a large enough array?
在我的日常工作中,我遇到了很多類似以下模式的C代碼。 我擔心這種模式是否安全。
typedef struct
{
unsigned char someField : 4;
unsigned char someOtherField : 4;
unsigned char body[1];
} __attribute__((__packed__, aligned(1))) SomeStruct;
int main()
{
unsigned char pack[16] = {};
SomeStruct* structPack = (SomeStruct*)pack;
structPack->someField = 0xC;
structPack->body[4] = 0x5;
return 0;
}
讓我擔心的是程序使用的是structPack->body[4]
,它仍然是16字節數組的一部分,但是如果我們看一下SomeStruct
的定義SomeStruct
。 所以有兩種方法來看待它:
所以,我的問題是:
請注意,此類代碼主要在微控制器上運行,有時在Linux桌面上作為應用程序運行。
通過不兼容的左值訪問對象是未定義的行為。 對齊可以通過屬性行解決,但使用指針訪問對象仍然違反嚴格別名:
unsigned char pack[16] = {};
SomeStruct* structPack = (SomeStruct*)pack;
6.5。 P7:
對象的存儲值只能由具有以下類型之一的左值表達式訪問:
- 與對象的有效類型兼容的類型,
- 與對象的有效類型兼容的類型的限定版本,
- 對應於對象的有效類型的有符號或無符號類型的類型,
- 對應於對象有效類型的限定版本的有符號或無符號類型,
- 聚合或聯合類型,其成員中包含上述類型之一(包括遞歸地,子聚合或包含聯合的成員),或者
- 角色類型。
有效類型是:
用於訪問其存儲值的對象的有效類型是對象的聲明類型(如果有)。
SomeStruct*
與char數組不兼容。
分配SomeStruct的正確方法是使用內存分配器或alloca(如果需要考慮,將分配堆棧)如果支持該功能。
仍然存在body
構件的問題,該構件是尺寸為一的陣列並且標准將不允許其越過界限(即身體[1])。 c99引入了一個靈活的陣列成員解決方案:
typedef struct
{
unsigned char someField : 4;
unsigned char someOtherField : 4;
unsigned char body[]; //must be last
}...
當您設置大小以分配此結構時,您可以根據body[]
成員需要的大小來添加其他大小。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.