Tôi cho rằng có một lịch sử với nó, nhưng tại sao ngăn xếp lại phát triển xuống?
Đối với tôi, dường như tràn bộ đệm sẽ khó khai thác hơn rất nhiều nếu ngăn xếp tăng dần lên ...
Tôi cho rằng có một lịch sử với nó, nhưng tại sao ngăn xếp lại phát triển xuống?
Đối với tôi, dường như tràn bộ đệm sẽ khó khai thác hơn rất nhiều nếu ngăn xếp tăng dần lên ...
Câu trả lời:
Tôi tin rằng nó xuất phát từ những ngày đầu của máy tính, khi bộ nhớ rất hạn chế và việc phân bổ trước một khối lớn bộ nhớ để sử dụng riêng cho ngăn xếp. Vì vậy, bằng cách phân bổ bộ nhớ heap từ địa chỉ 0 trở lên và ngăn xếp bộ nhớ từ cuối bộ nhớ trở xuống, bạn có thể có cả heap và stack chia sẻ cùng một vùng nhớ.
Nếu bạn cần thêm một chút nữa, bạn có thể cẩn thận với việc sử dụng ngăn xếp của mình; nếu bạn cần thêm stack, bạn có thể cố gắng giải phóng bộ nhớ heap. Tất nhiên, kết quả là, hầu hết, các sự cố ngoạn mục, vì ngăn xếp đôi khi sẽ ghi đè lên đống và ngược lại.
Quay lại những ngày đó không có sự đan xen, vì vậy không có vấn đề khai thác tràn bộ đệm. (Hoặc ít nhất là trong phạm vi mà interwebz tồn tại, tất cả đều nằm trong các cơ sở bảo mật cao của bộ quốc phòng thống nhất, vì vậy khả năng dữ liệu độc hại không cần phải suy nghĩ nhiều.)
Sau đó, với hầu hết các kiến trúc, tất cả chỉ là vấn đề duy trì khả năng tương thích với các phiên bản trước đó của cùng một kiến trúc. Đó là lý do tại sao các ngăn xếp lộn ngược vẫn còn với chúng ta ngày hôm nay.
bộ nhớ chương trình được thiết lập theo truyền thống là
code
constants
heap (growing up)
...
stack (growing down)
đống và ngăn xếp có thể được trao đổi
nhưng tràn bộ đệm vẫn có thể được khai thác nếu ngăn xếp đi theo cách khác
lấy kinh điển strcpy
làm ví dụ
foo(char* in){
char[100] buff;
strcpy(buff,in);
}
với bộ nhớ ngăn xếp như
ret foo
arg in
buff array
ret strcpy
buf pointer
in
điều này có nghĩa là khi sao chép xong, địa chỉ trả về strcpy
nằm sau bộ đệm (thay vì foo
địa chỉ trả về) và có thể được ghi đè bằng bất cứ thứ gì có trongin
Một số phần cứng có heap bắt đầu từ bộ nhớ cao, phát triển xuống, trong khi ngăn xếp bắt đầu ở bộ nhớ thấp tăng lên.
Phần cứng PA-RISC của HP, trong số những người khác, thực hiện việc này: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php
Hệ điều hành Multics đáng kính chạy trên phần cứng có (một trong số rất nhiều) ngăn xếp đang phát triển: xem http://www.acsac.org/2002/ con / classic-multics.pdf, cuối phần 2.3.2:
Thứ ba, các ngăn xếp trên bộ xử lý Multics phát triển theo hướng tích cực, thay vì theo hướng tiêu cực. Điều này có nghĩa là nếu bạn thực sự hoàn thành tràn bộ đệm, bạn sẽ ghi đè lên các khung ngăn xếp không sử dụng, thay vì con trỏ trở lại của riêng bạn, khiến việc khai thác trở nên khó khăn hơn nhiều.
Đó là một tuyên bố khá thú vị. Có phải lỗi tràn bộ đệm đã trở thành một vấn đề lớn như vậy chỉ vì sự sắp xếp thủ tục "cuộc gọi-ngăn xếp-khung" thông thường? Ngoài ra, bao nhiêu danh tiếng của Multics như Totally Invulnerable chỉ là một phần nhỏ của thiết kế phần cứng?