學習軟體安全考試并遇到此問題但找不到漏洞。如果您輸入姓名“John Doe”和薪水 4000,那么程式將寫入字串“John Doe: $4000”。據我所知,程式占\0,沒有格式字串錯誤,沒有緩沖區溢位。不知道我錯過了什么。
編輯:忘記添加“名稱”引數可以假定為有效的以空字符結尾的字串。
/* Calculates the number of letters (i.e. digits) that are needed to represent a decimal number as an ASCII string */
size_t count_digits(unsigned int number)
{
unsigned int left = number;
size_t n= 0;
while(left != 0) {
left = left / 10;
n ;
}
return n;
}
void add_record(const char* name, unsigned int salary)
{
char buffer[256];
size_t len = strlen(name);
size_t num_digits = count_digits(salary);
/* 5 extra bytes required for colon and space after name dollar sign, endline and NULL-terminator */
if(len > SIZE_MAX - 5 || len 5 > SIZE_MAX - num_digits) {
printf("integer overflow");
exit(1);
}
len = len num_digits 5;
if (len > sizeof(buffer)) {
printf("Too long string");
exit(1);
}
/* Output formatted string to buffer (in the format string, %s denotes a string, and %u denotes an unsigned int that is printed as a decimal number) */
sprintf(buffer, "%s: $%u\n", name, salary);
// Write buffer to file
fputs(buffer, global_file_handle);
}
uj5u.com熱心網友回復:
count_digits錯誤地為零回傳零。正確的結果是一。工資為零的 251 個字符的名稱將需要 257 個字符(名稱為 251,工資為 1,顏色、空格、美元符號、換行符和 null 為 5),但len將錯誤地計算為 256,并且len > sizeof(buffer)將不會被觸發,所以代碼會溢位buffer。
(另一個問題是當不是空終止strlen時具有未定義的行為,但問題陳述中的背景關系并不清楚。)namename
uj5u.com熱心網友回復:
這不是一個答案,而是一個示例代碼可能應該避免 Erik Postpischil 描述的緩沖區溢位。
該count_digits函式是錯誤的(在 的情況下0),但也是不必要的。可以將輸出限制為buffer使用snprintf:
void add_record(const char* name, unsigned int salary)
{
char buffer[256];
int len;
len = snprintf(buffer, sizeof buffer, "%s: $%u\n", name, salary);
if (len >= sizeof(buffer)) {
printf("Too long string");
exit(1);
}
fputs(buffer, global_file_handle);
}
請注意,如果len完全等于sizeof buffer,這將意味著生成的字串已經被截斷。實際上,應該是防止截斷len 1的大小。buffer
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/410330.html
標籤:
下一篇:如何將此代碼翻譯為字符而不是整數
