2016-03-25 27 views
0

我有一個函數,它接受包含敏感數據(在char數組中)作爲參數(排序的小型庫)的struct *指針。 兩個struct型號如下:防止結構中的字符指針溢出

struct struct1 { 
    char str[1024]; /* maybe even 4096 or 10KB+ */ 
    size_t str_length; 
} 

struct struct2 { 
    char *str; 
    size_t str_length; 
} 

的測試功能是:

/* Read str_length bytes from the char array. */ 
void foo(struct struct1/struct2 *s) { 
    int i; 
    for (i = 0; i < s->str_length; i++) { 
     printf("%c\n", s->str[i]); 
    } 
} 

我擔心的是,由於str_length參數爲任意值,我們可以故意把它設置爲導致緩衝區溢出(實際上有人愚蠢到有意在自己的程序中創建安全漏洞,但我覺得我必須考慮這些情況)。通過使用struct1模型,但是,我可以簡單地通過只使用檢查一個可能的緩衝區溢出:

if (s->str_length > sizeof(s->str)) { 
    /* ERROR */ 
} 

的問題是,長度數組實際上未知是在編譯時。所以我不知道是否使用char *指針(struct2風格,所以沒有溢出檢查)或定義一個非常大的數組(struct1),這將限制最大長度(我想避免的東西)和大部分時間都會分配不必要的空間(這在嵌入式系統中可能存在問題,我猜想)。我知道我必須作出妥協,我個人使用struct2模型,但我不確定這是否是一個安全明智的選擇。

+1

如果你想有一個填充階段教練與全功能的範圍檢查,你應該明確不使用C.如果用戶改變了實例的指針? – Olaf

+0

習慣於此在結構的最後定義一個絕對巨大的數組以供您的lib使用,並讓用戶管理它的實際分配並傳遞一個指針和「實際」大小。您保持靈活性,不會浪費實際空間。當然,你不能直接拷貝結構體! –

+1

安全?這是C - 你已經沒有安全:) –

回答

0

你的庫的用戶從哪裏得到struct2實例傳遞給函數?不認爲他自己創建它,然後將它的地址傳遞給你的函數,這將是一個奇怪的方法來傳遞參數,它很可能是從庫中的另一個函數返回的,在這種情況下,你可以使struct2成爲一個不透明的數據類型用戶不能(在哈克的方式或只),直接修改:

/* in the header file */ 
typedef struct2_s struct2; 

/* in the implementation file, where allocation is handled as well 
* so you know str_length is set to the proper value. 
*/ 
struct struct2_s { 
    char *str; 
    size_t str_length; 
}; 
+0

其實我正在考慮傳遞結構地址,但是你的解決方案讓我重新考慮了這個選項,但是這樣,圖書館也應該照顧整個數據採集。我想要的只是傳遞char數組以便被函數處理。我希望我解釋得很好...... – lorenzownd

0

把大陣在結束..

struct struct1 { 
    anyType thisVar; 
    someType anotherVar 
    size_t str_length; 
    char str[10240000];/
} 

讓它到任何「真實」的大小,他們希望用戶的malloc。如果他們設置'str_length'是錯誤的,那麼無論你做什麼都沒什麼可做的:無論你做什麼:(

+0

然而,在這種情況下,用戶仍然完全能夠通過傳遞錯誤的* str_length *值來溢出緩衝區。我認爲你是對的,這不是一個簡單的解決方案:( – lorenzownd