2013-03-19 35 views
15

Gcc có phân bổ bộ nhớ thông minh để ngăn chặn tấn công tràn bộ đệm không?vấn đề cấp phát bộ nhớ gcc - tấn công tràn bộ đệm

int function(char *str) { 
    int a = 0;     // See the 
    char b[16] = "abcd";  // changes here 

    if(!strcmp(b, str)) 
     a = 1; 

    return a; 
} 

int function(char *str) { 
    char b[16] = "abcd";  // See the 
    int a = 0;     // changes here 

    if(!strcmp(b, str)) 
     a = 1; 

    return a; 
} 

Khi tôi gỡ lỗi nó với gdb, nó luôn luôn phân bổ bộ nhớ đầu tiên để nguyên biến và sau đó mảng nhân vật; bất kể thứ tự khai báo biến là gì. Ví dụ: Trong cả hai trường hợp, trình biên dịch cấp phát bộ nhớ trước tiên cho a và sau đó đến b.

(higher address) 
    Memory 
|  | 
|  | 
+--------+ 
|  | 
|  | 
|  | 
|  | 
+--------+ <----- b (16 bytes) 
|  | 
+--------+ <----- a (4 bytes) 
|  | 
(lower address) 

Vì vậy, ngay cả khi chúng tôi cung cấp hơn 16 ký tự trong str, nó có thể không ảnh hưởng đến giá trị của a. Ai có thể giúp tôi ở đây không?

Cảm ơn bạn.

+1

_ Tiêu chuẩn_ cho phép sắp xếp lại như vậy cho bất kỳ mục đích nào, trình biên dịch muốn thực hiện. Phổ biến nhất - tối ưu hóa. Nó vẫn là "trí thông minh", nhưng không phải để ngăn chặn "tấn công tràn bộ đệm". Và nó vẫn là một hành vi _undefined_ (tràn bộ đệm) –

Trả lời

11

Có, nếu chạy với cờ -fstack-protector.

Khi chạy cờ, GCC bổ sung thêm canaries, sắp xếp biến mảng thành phần cao nhất của khung ngăn xếp để làm cho chúng khó tràn và hỏng các biến khác, đồng thời sao chép các đối số hàm được lưu trữ những người dân địa phương khác.

Xem Wikipedia page on Buffer overflow protectionProPolice trang chủ để biết thêm thông tin

+0

@Ravi: Một số bản phân phối cho phép theo mặc định. Thử biên dịch bằng '-fno-stack-protector' và xem nó có tạo sự khác biệt hay không. – Hasturkun

+0

@MM .: Đã thêm. Phần lớn bị bỏ quên. – Hasturkun

+1

Bạn nói đúng. GCC kích hoạt nó theo mặc định. Nếu chúng ta biên dịch với '-fno-stack-protector', nó cấp phát bộ nhớ tuần tự theo thứ tự khai báo chứ không phải biến _array tới phần cao nhất của khung stack_. Cảm ơn bạn – Ravi

-1

Gcc có phân bổ bộ nhớ thông minh để ngăn chặn tấn công tràn bộ đệm không?

Không, không. Bạn không thể ngăn chặn một cuộc tấn công hoặc tràn bộ đệm mà không kiểm tra giới hạn, điều này không phải lúc nào cũng có thể. Bạn chỉ có thể đôi khi phát hiện một tràn sau khi thực tế. Ở mức tốt nhất, trình biên dịch có thể bao gồm thông tin bổ sung (được gọi là canary value) gần địa chỉ trả về trên ngăn xếp và trước khi trở về từ chức năng kiểm tra xem nó có còn nguyên vẹn và không bị ghi đè do tràn bộ đệm hay không.

+2

Điều này là sai, GCC có thể và không sắp xếp lại các biến để ngăn chặn các tác động của tràn bộ đệm – Hasturkun

+0

@Hasturkun Bạn không thể ngăn chặn tràn mà không kiểm tra giới hạn. Bạn chỉ có thể phát hiện một lần. –

+0

Đó là sự thật. Nhưng bạn có thể giảm thiểu chúng, như được thực hiện bởi ProPolice, v.v. – Hasturkun

2

Thậm chí nếu GCC có như vậy một tính năng để bảo vệ chống lại tràn bộ đệm, có nhiều mối quan tâm khác ở đây có thể gây ra một trật tự khai cố định biến. Trường hợp khai báo được thực hiện không thực sự quan trọng, trình biên dịch sẽ quyết định phân bổ dựa trên thời gian và cách biến được sử dụng trong thời gian chạy.

Quan trọng nhất, trình biên dịch hy vọng sẽ phân bổ các biến trong khung ngăn xếp với sự liên kết tốt nhất có thể trong đầu. Điều này có thể được thực hiện theo những cách hoàn toàn khác nhau tùy thuộc vào CPU và tối ưu hóa cài đặt. Tối ưu hóa cho tốc độ có thể phân bổ hoàn toàn khác nhau, so với tối ưu hóa cho mức tiêu thụ bộ nhớ. Và rất có thể, nó sẽ đặt một số biến trong sổ đăng ký CPU, loại bỏ toàn bộ nhu cầu phân bổ RAM.

Vì vậy, để trả lời câu hỏi của bạn: GCC phân bổ các biến theo nhiều cách khác nhau, tùy thuộc vào cổng trình biên dịch. Làm thế nào nó làm như vậy, không phải là một cái gì đó lập trình viên cần phải quá lo lắng về bản thân. Có thể có các tùy chọn để sắp xếp lại ngăn xếp để bảo vệ chống lại các tấn công tràn bộ đệm, nhưng điều đó chỉ có ý nghĩa trong một số loại ứng dụng. Có thể thậm chí không có bất kỳ đầu vào nào cho một hệ thống cụ thể, cho tất cả chúng ta biết. Vì vậy, nó không có ý nghĩa cho một trình biên dịch để có tính năng bảo mật này được kích hoạt theo mặc định.

Các vấn đề liên quan