You are on page 1of 15

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI

VIỆN CÔNG NGHỆ THÔNH TIN VÀ TRUYỀN THÔNG


TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN CÔNG NGHỆ THÔNH TIN VÀ TRUYỀN THÔNG

BÁO CÁO THÍ NGHIỆM


ĐIỆN
BÀI TẬP TỬMÔN
LỚN SỐ HỌC
HỆ ĐIỀU HÀNH

Đề tài: Tìm hiểu lỗ hổng trong quản lý bộ nhớ trong hệ điều hành và nêu rõ
nguyên nhân.

Sinh viên thực hiện: Sinh viên thực hiện:


Nguyễn
Phạm Văn Tùng - 20083036 - Kĩ thuật máy tính XuânK53Tiến
Tạ Thị Quỳnh - 20082714 - Kỹ thuật máyMSSV:tính20082662
K53
Kĩ thuật
Tô Đông Hoàng - 20081075 - Truyền thông mạng K53máy tính K53
Giáo
Đỗ Duy Thành - 20082368 - Truyền viên mạng
thông hướng dẫn: K53
GV:thông
Tô Xuân Hoàng - 20081074 - Truyền Trần mạng
Thị ThúyK53
Giáo viên hướng dẫn:
GV: Đỗ Quốc Huy

HÀ NỘI - 2011

HÀ NỘI - 2011

1
Mục lục
A.Lời nói đầu……………………………………………………………………...2
B.Nội dung………………………………………………………………………...2
I. Nhiệm vụ của quản lý bộ nhớ……………………………………………….2
II. Các cấu trúc của chương trình……………………………………………...5
III. Các kỹ thuật cấp phát bộ nhớ……………………………………………...6
IV. Kỹ thuật bộ bộ nhớ ảo……………………………………….....................8
V. Các lỗ hổng trong quản lý bộ nhớ…………………………………………..9
C.Kết luận…………………………………………………………………………13
Tài liệu tham khảo………………………………………………………………...14

2
A. LỜI NÓI ĐẦU
Bộ nhớ trong là thiết bị lưu trữ mà CPU có thể truy xuất 1 cách trực tiếp.Khi tổ
chức một chương trình,sau biên dịch chương trình được chuyển sang ngôn ngữ
máy tính,khi đó nó có các đỉa chỉ tương đối.Khi thực hiện,chương trình được nạp
vào bộ nhớ,các địa chỉ tương đối sẽ được chuyển đổi thành các địa chỉ vật lý xác
định để CPU có thể truy xuất được trong quá trình xử lý đó,đó là quá trình sinh địa
chỉ. Sau khi chương trình hoạt động xong,hệ thống cần phải giải phóng các địa chỉ
vật lý đã cấp phát(giải phóng bộ nhớ).Để tăng hiệu suất xử lý của hệ thống,tại cùng
một thời điểm hệ thống có thể cho phép nhiều chương trình cùng tồn tại trong bộ
nhớ.Hệ điều hành chịu trách nhiệm cấp phát không gian nhớ cho các tiến trình khi
có yêu cầu.Các phương pháp tổ chức bộ nhớ khác nhau sẽ gây ra các lỗ
hổng,những lỗ hổng này hoàn toàn có thể khắc phục bằng các cơ chế được cụ thể
hóa trong hệ điều hành
Tuy nhiên,khi các chương trình được lập trình mà không quan tâm đến bảo vệ
bộ nhớ được cấp phát,giải phóng(ví dụ các hàm cấp phát và giải phóng bộ nhớ
trong C như malloc,free…hoặc trong C++ như new,delete…) sẽ gây ra các lỗi
trong quản lý bộ nhớ trong hệ điều hành,các lỗi này nếu đã xảy ra là không thể
chống lại,các kể có ý đồ xấu có thể lợi dụng các lỗ hổng này để phá vỡ an ninh hệ
thống,truy nhập thao túng các chương trình.
B. NỘI DUNG
I. Nhiệm vụ của quản lý bộ nhớ
Trong các hệ thống đơn chương trình (uniprogramming), trên bộ nhớ
chính ngoài hệ điều hành, chỉ có một chương trình đang thực hiện. Trong các hệ
thống đa chương (multiprogramming) trên bộ nhớ chính ngoài hệ điều hành, có thể
có nhiều tiến trình đang hoạt động. Do đó nhiệm vụ quản lý bộ nhớ của hệ điều
hành trong hệ thống đa chương trình sẽ phức tạp hơn nhiều so với trong hệ thống
đơn chương trình. Trong hệ thống đa chương bộ phận quản lý bộ nhớ phải có
nhiệm vụ đưa bất kỳ một tiến trình nào đó vào bộ nhớ khi nó có yêu cầu, kể cả khi
trên bộ nhớ không còn không gian trống, ngoài ra nó phải bảo vệ chính hệ điều
hành và các tiến trình trên bộ nhớ tránh các trường hợp truy xuất bất hợp lệ xảy ra.
Như vậy việc quản lý bộ nhớ trong các hệ thống đa chương là quan trọng và cần
thiết. Bộ phận quản lý bộ nhớ phải thực hiện các nhiệm vụ sau đây:
 Sự tái định vị (Relocation):
Trong các hệ thống đa chương, không gian bộ nhớ chính thường được chia sẻ
cho nhiều tiến trình khác nhau và yêu cầu bộ nhớ của các tiến trình luôn lớn hơn
không gian bộ nhớ vật lý mà hệ thống có được. Do dó, một chương trình đang hoạt
3
động trên bộ nhớ cũng có thể bị đưa ra đĩa (swap-out) và nó sẽ được đưa vào lại
(swap-in) bộ nhớ tại một thời điểm thích hợp nào đó sau này. Vấn đề đặt ra là khi
đưa một chương trình vào lại bộ nhớ thì hệ điều hành phải định vị nó vào đúng vị
trí mà nó đã được nạp trước đó. Để thực hiện được điều này hệ điều hành phải có
các cơ chế để ghi lại tất cả các thông tin liên quan đến một chương trình bị swap-
out, các thông tin này là cơ sở để hệ điều hành swap-in chương trình vào lại bộ nhớ
chính và cho nó tiếp tục hoạt động. Hệ điều hành buộc phải swap-out một chương
trình vì nó còn không gian bộ nhớ chính để nạp tiến trình khác, do dó sau khi
swap-out một chương trình hệ điều hành phải tổ chức lại bộ nhớ để chuẩn bị nạp
tiến trình vừa có yêu cầu. Các nhiệm vụ trên do bộ phần quản lý bộ nhớ của hệ
điều hành thực hiện. Ngoài ra trong nhiệm vụ này hệ điều hành phải có khả năng
chuyển đổi các địa chỉ bộ nhớ được ghi trong code của chương trình thành các địa
chỉ vật lý thực tế trên bộ nhớ chính khi chương trình thực hiện các thao tác truy
xuất trên bộ nhớ, bởi vì người lập trình không hề biết trước hiện trạng của bộ nhớ
chính và vị trí mà chương trình được nạp khi chương trình của họ hoạt động. Trong
một số trường hợp khác các chương trình bị swap-out có thể được swap-in vào lại
bộ nhớ tại vị trí khác với vị trí mà nó được nạp trước đó.
 Bảo vệ bộ nhớ (Protection):
Mỗi tiến trình phải được bảo vệ để chống lại sự truy xuất bất hợp lệ vô tình hay
có chủ ý của các tiến trình khác. Vì thế các tiến trình trong các chương trình khác
không thể tham chiếu đến các vùng nhớ đã dành cho một tiến trình khác để thực
hiện các thao tác đọc/ghi mà không được phép (permission), mà nó chỉ có thể truy
xuất đến không gian địa chỉ bộ nhớ mà hệ điều hành đã cấp cho tiến trình đó. Để
thực hiện điều này hệ thống quản lý bộ nhớ phải biết được không gian địa chỉ của
các tiến trình khác trên bộ nhớ và phải kiểm tra tất cả các yêu cầu truy xuất bộ nhớ
của mỗi tiến trình khi tiến trình đưa ra địa chỉ truy xuất. Điều này khó thực hiện vì
không thể xác định địa chỉ của các chương trình trong bộ nhớ chính trong quá trình
biên dịch mà phải thực hiện việc tính toán địa chỉ tại thời điểm chạy chương trình.
Hệ điều hành có nhiều chiến lược khác nhau để thực hiện điều này.
Điều quan trọng nhất mà hệ thống quản lý bộ nhớ phải thực hiện là không
cho phép các tiến trình của người sử dụng truy cập đến bất kỳ một vị trí nào của
chính hệ điều hành, ngoại trừ vùng dữ liệu và các rountine mà hệ điều hành cung
cấp cho chương trình người sử dụng.
 Chia sẻ bộ nhớ (Sharing):
Bất kỳ một chiến lược nào được cài đặt đều phải có tính mềm dẻo để cho phép
nhiều tiến trình có thể truy cập đến cùng một địa chỉ trên bộ nhớ chính Hệ thống
quản lý bộ nhớ phải điều khiển việc truy cập đến không gian bộ nhớ được chia sẻ
mà không vi phạm đến các yêu cầu bảo vệ bộ nhớ. Ngoài ra, trong môi trường hệ
điều hành đa nhiệm hệ điều hành phải chia sẻ không gian nhớ cho các tiến trình để
4
hệ điều hành có thể nạp được nhiều tiến trình vào bộ nhớ để các tiến trình này có
thể hoạt động đồng thời với nhau.
 Tổ chức bộ nhớ logic (Logical organization):
Bộ nhớ chính của hệ thống máy tính được tổ chức như là một dòng hoặc một
mảng, không gian địa chỉ bao gồm một dãy có thứ tự các byte hoặc các word. Bộ
nhớ phụ cũng được tổ chức tương tự. Mặc dù việc tổ chức này có sự kết hợp chặt
chẽ với phần cứng thực tế của máy nhưng nó không phù hợp với các chương trình.
Đa số các chương trình đều được chia thành các modun, một vài trong số đó là
không thể thay đổi (read only, execute only) và một vài trong số đó chứa dữ liệu là
có thể thay đổi. Nếu hệ điều hành và phần cứng máy tính có thể giao dịch một cách
hiệu quả với các chương trình của người sử dụng và dữ liệu trong các modun thì
một số thuận lợi có thể thấy rõ sau đây:
 Các modun có thể được viết và biên dịch độc lập, với tất cả các tham chiếu
từ một modun đến modun khác được giải quyết bởi hệ thống tại thời điểm
chạy.
 Các mức độ khác nhau của sự bảo vệ, read-only, execute-only, có thể cho ra
các modun khác nhau.
 Nó có thể đưa ra các cơ chế để các modun có thể được chia sẻ giữa các tiến
trình.
• Tổ chức bộ nhớ vật lý (Physical organization):
Như chúng ta đã biết bộ nhớ máy tính được tổ chức theo 2 cấp: bộ nhớ chính và
bộ nhớ phụ. Bộ nhớ chính cung cấp một tốc độ truy cập dữ liệu cao, nhưng dữ liệu
trên nó phải được làm tươi thường xuyên và không thể tồn tại lâu dài trên nó. Bộ
nhớ phụ có tốc độ truy xuất chậm và rẻ tiền hơn so với bộ nhớ chính nhưng nó
không cần làm tươi thường xuyên. Vì thế bộ nhớ phụ có khả năng lưu trữ lớn và
cho phép lưu trữ dữ liệu và chương trình trong một khoảng thời gian dài, trong khi
đó bộ nhớ chính chỉ để giữ (hold) một khối lượng nhỏ các chương trình và dữ liệu
đang được sử dụng tại thời điểm hiện tại.
Trong giản đồ 2 cấp này, việc tổ chức luồng thông tin giữa bộ nhớ chính và
bộ nhớ phụ là một nhiệm vụ quan trọng của hệ thống. Sự chịu trách nhiệm cho
luồng này có thể được gán cho từng người lập trình riêng, nhưng điều này là không
hợp lý và có thể gây rắc rối, là do hai nguyên nhân:
• Không gian bộ nhớ chính dành cho các chương trình cùng với dữ liệu của
nó thường là không đủ, trong trường hợp này, người lập trình phải tiến hành
một thao tác được hiểu như là Overlaying, theo đó chương trình và dữ liệu
được tổ chức thành các modun khác nhau có thể được gán trong cùng một
vùng của bộ nhớ, trong đó có một chương trình chính chịu trách nhiệm
chuyển các modun vào và ra khi cần.
5
• Trong môi trường đa chương trình, người lập trình không thể biết tại một
thời điểm xác định có bao nhiêu không gian nhớ còn trống hoặc khi nào thì
không gian nhớ sẽ trống.
Như vậy nhiệm vụ di chuyển thông tin giữa 2 cấp bộ nhớ phải do hệ thống
thực hiện. Đây là nhiệm vụ cơ bản mà thành phần quản lý bộ nhớ phải thực hiện.
II. Các cấu trúc cơ bản của chương trình
Có nhiều phương pháp tổ chức chương trình ở bộ nhớ trong để thực hiện.
Các phương pháp này khác nhau ở kiểu định vị chương trình trong bộ nhớ và thời
điểm thực hiện phép ánh xạ địa chỉ tương đối thành địa chỉ tuyệt đối.
Cấu trúc một chương trình thể hiện cách quản lý bộ nhớ logic và cho ta thấy hình
ảnh của chương trình ở bộ nhớ vật lý khi thực hiện.Mỗi chương trình có thể có các
dạng cấu trúc sau:
1. Cấu trúc tuyến tính
Là cấu trúc sau khi biên dịch,các modul được tập hợp thành một chương trình
hoàn thiện,chứa đầy đủ mọi thông tin để có thể thực hiện;mọi biến ngoài đều được
gán địa chỉ cụ thể. Khi thực hiện chỉ cần định vị chương trình một lần vào bộ nhớ.
2. Cấu trúc động
Trong cấu trúc động,các modul chương trình được biên tập một cách riêng biệt.
Khi thực hiện,chương trình chỉ cần định vị modul gốc.trong quá trình thực hiện,cần
tới modul nào thì hệ thống cấp phát không gian nhớ và nạp modul đó vào bộ nhớ.
Khi hoạt động xong thì giải phóng modul khỏi bộ nhớ,thu hồi không gian nhớ
3. Cấu trúc Overlay
Trong cấu trúc overlay,các modul chương trình sau khi biên dịch được chia
thành các mức
Mức 0: chứa các modul gốc dùng để nạp chương trình.
Mức 1:chứa các modul gọi bởi mức 0.
Mức 2: chứa các modul gọi bới mức 1.
….
Bộ nhớ chương trình cũng được chia thành các mức tương ứng với các mức
chương trình.
Để tạo thành chương trình cấu trúc Overlay,người sử dụng cần cung cấp các
thông tin về các mức cho trình biên dịch thông qua sơ đồ Overlay(file
.OVL),modul gốc được lưu trữ trong một file chương trình riêng.Khi thực hiện
chương trình,modul gốc được định vị vào bộ nhớ như chương trình có cấu trúc
tuyến tính. Cần tới modul nào thì hệ thống sẽ tìm kiếm trong sơ đồ Overlay và nạp
vào bộ nhớ tương ứng.
4. Cấu trúc phân đoạn
Chương trình của người sử dụng được biên dịch thành từng modul độc lập.
Thông tin về các modul được chứa trong một bảng điều khiển gọi là bảng quản lý

6
đoạn(Segment Control Block-SCB).Khi thực hiện chương trình,hệ thống sẽ dựa
vào bảng quản lý đoạn để nạp các modul cần thiết vào bộ nhớ cho đến khi hết khả
năng.Khi cần nạp các modul mới nhưng thiếu bộ nhớ thì hệ thống sẽ đưa bớt các
modul có khả năng không sử dụng nữa.
5. Cấu trúc phân trang
Chương trình được biên dịch,sau đó phân chia thành các phần bằng nhau gọi là
trang. Thông tin về các trang chứa trong bảng quản lý trang(Page Control Block-
PCB). Mỗi phần tử trong bảng quản lý trang tương ứng với một trang trong chương
trình của người sử dụng.Khi thực hiện,hệ thống sẽ dựa vào bảng quản lý trang để
nạp các trang cần thiết vào bộ nhớ.
III. Các kỹ thuật cấp phát bộ nhớ(nạp chương trình vào bộ nhớ)
1. Kỹ thuật phân vùng cố định
Bộ nhớ được chia thành n phần, không nhất thiết phải bằng nhau và mỗi
phần được sử dụng như một bộ nhớ độc lập gọi là một phân vùng. Mỗi phân
vùng có thể nạp được một chương trình và tổ chức thực hiện một cách đồng
thời. như vậy, trên lý thuyết nếu có n phân vùng thì sẽ có thể nạp được n
chương trình và thực hiện một cách đồng thời(n được gọi là hệ số song song
của hệ thống).
Vì mỗi phân vùng được coi như một bộ nhớ độc lập, nên mỗi chương
trình sẽ có danh sách quản lý không gian nhớ tự do riêng. Chương trình được
nạp vào phân vùng nào thì sẽ ở đó cho đến kết thúc.
Mỗi phân vùng sẽ được gắn với một số lớp phục vụ, chương trình khi
định vị vào bộ nhớ cũng được phân lớp theo khai báo của người sử dụng. mỗi
phân vùng chỉ phục vụ các chương trình thuộc lớp mình quản lý. Như vậy
chúng ta có thể tránh được các trượng hợp định vị chương trình nhỏ vào vùng
nhớ lớn, tránh lãng phí bộ nhớ.
Để sửa đổi cấu trúc các phân vùng cần phải nạp lại hệ điều hành nhưng
để tránh mất thông tin chúng ta phải chờ cho tới khi các chương trình kết thúc.
Cũng có một số công cụ cho phép kết hợp một số phân vùng liền kề thành một
phân vùng có cấu trúc lớn hơn mà thông tin ở các phân vùng khác nhau vẫn
được bảo toàn.
2. Kỹ thuật phân vùng động
Để khắc phục một vài hạn chế của kỹ thuật phân vùng cố định, kỹ thuật phân
vùng động ra đời. Kỹ thuật này thường được sử dụng trong các hệ điều hành gần
đây như hệ điều hành mainframe của IBM, hệ điều hành OS/MVT,...
Trong sơ đồ này, bộ nhớ có bảng quản lý không gian nhớ tự do thống nhất.
khi thực hiện chương trình, hệ thống dựa vào kích thước chương trình để phân bổ
không gian nhớ thích hợp, tạo thành một vùng nhớ độc lập và tạo bảng quản lý
riêng. Khi chương trình kết thúc bộ nhớ dành cho nó sẽ bị thu hồi.
3. Kỹ thuật phân trang
7
Trong kỹ thuật này không gian địa chỉ bộ nhớ vật lý được chia thành các phần
có kích thước cố định bằng nhau, được đánh số địa chỉ bắt đầu từ 0 và được gọi là
các khung trang (page frame). Không gian địa chỉ của các tiến trình cũng được chia
thành các phần có kích thước bằng nhau và bằng kích thước của một khung trang,
được gọi là các trang (page) của tiến trình.
Khi một tiến trình được nạp vào bộ nhớ thì các trang của tiến trình được nạp
vào các khung trang còn trống bất kỳ, có thể không liên tiếp nhau, của bộ nhớ. Khi
hệ điều hành cần nạp một tiến trình có n trang vào bộ nhớ thì nó phải tìm đủ n
khung trang trống để nạp tiến trình này. Nếu kích thước của tiến trình không phải
là bội số của kích thước một khung trang thì sẽ xảy ra hiện tượng phân mảnh trong
ở khung trang chứa trang cuối cùng của tiến trình. Ở đây không xảy ra hiện tượng
phân mảnh ngoài. Trên bộ nhớ có thể tồn tại các trang của nhiều tiến trình khác
nhau. Khi một tiến trình bị swap-out(hoán chuyển ra bộ nhớ ngoài) thì các khung
trang mà tiến trình này chiếm giữ sẽ được giải phóng để hệ điều hành có thể nạp
các trang tiến trình khác.
Trong kỹ thuật này hệ điều hành phải đưa ra các cơ chế thích hợp để theo dõi
trạng thái của các khung trang (còn trống hay đã cấp phát) trên bộ nhớ và các
khung trang đang chứa các trang của một tiến trình của các tiến trình khác nhau
trên bộ nhớ. Hệ điều hành sử dụng một danh sách để ghi số hiệu của các khung
trang còn trống trên bộ nhớ, hệ điều hành dựa vào danh sách này để tìm các khung
trang trống trước khi quyết định nạp một tiến trình vào bộ nhớ, danh sách này được
cập nhật ngay sau khi hệ điều hành nạp một tiến trình vào bộ nhớ, được kết thúc
hoặc bị swap out ra bên ngoài.
Hệ điều hành sử dụng các bảng trang (PCT: page control table) để theo dõi vị
trí các trang tiến trình trên bộ nhớ, mỗi tiến trình có một bảng trang riêng
 Kỹ thuật phân trang loại bỏ được hiện tượng phân mảnh ngoài, nhưng vẫn
có thể xảy ra hiện tượng phân mảnh trong khi kích thước của tiến trình
không đúng bằng bội số kích thược của một trang, khi đó khung trang cuối
cùng sẽ không được sử dụng hết.
4. Kỹ thuật phân đoạn
Trong kỹ thuật này không gian địa chỉ bộ nhớ vật lý được chia thành các phần
cố định có kích thước không bằng nhau, được đánh số bắt đầu từ 0, được gọi là các
phân đoạn (segment). Mỗi phân đoạn bao gồm số hiệu phân đoạn và kích thước
của nó. Không gian địa chỉ của các tiến trình kể cả các dữ liệu liên quan cũng được
chia thành các đoạn khác nhau và không nhất thiết phải có kích thước bằng nhau,
thông thường mỗi thành phần của một chương trình/tiến trình như: code, data,
stack, subprogram, ..., là một đoạn.

8
Để theo dõi các đoạn của các tiến trình khác nhau trên bộ nhớ, hệ điều hành sử
dụng các bảng phân đoạn (SCT: Segment control Table) tiến trình, thông thường
một tiến trình có một bảng phân đoạn riêng.
 Vì các segment có kích thước không bằng nhau nên sự phân đoạn tương tự
như sự phân vùng động. Sự khác nhau là với sự phân đoạn một chương trình
có thể chiếm giữ hơn một phân vùng, và các phân vùnh này có thể không
liền kề với nhau. Sự phân vùng loại trừ được sự phân mảnh nội vi, nhưng
như sự phân vùng động nó vẫn xuất hiện hiện tượng phân mảnh ngoại vi.
5. Kết hợp phân trang với phân đoạn
Kỹ thuật phân trang đảm bảo hiệu quả bộ nhớ dử dụng không phụ
thuộc vào cấu trúc chương trình của người sử dụng, điều khiển trang thuận
tiện đơn giản. Tuy nhiên, khi chương trình có kích thước lớn thì kích thước
bảng quản lý trang cũng lơn theo, dẫn đến lãng phí bộ nhớ. Mặt khác, nếu
kích thước trang quá nhỏ thì kích thước bảng quản lý trang sẽ lớn và khả
năng phải thường xuyên nạp lại tràn càng cao. Ngược lại, nếu kích thước
trang lớn thì số trang được nạp để xử lý sẽ giảm gây tác động đáng kể đến
hiệu quả sử dụng bộ nhớ.
Kỹ thuật phân đoạn linh hoạt hơn về độ dài của các đoạn nhưng cũng
chính vì đọ dài của các đoạn khác nhau nên phức tạp trong thực hiện và cấp
phát bộ nhớ.
Để phát huy được ưu điểm và hạn chế nhược điểm của các sơ đồ trên
người ta thường dùng sơ đồ kết hợp phân trang và phân đoạn.
IV. Kỹ thuật bộ nhớ ảo
Bộ nhớ ảo (Virtual Memory): là một kỹ thuật cho phép xử lý một tiến trình
không được nạp toàn bộ vào bộ nhớ vật lý.Bộ nhớ ảo mô hình hóa bộ nhớ như
một bảng lưu trữ rất lớn và đồng nhất, tách biệt hẳn khái niệm không gian địa
chỉ ảo (virtual address space) và không gian vật lý (physical space).Một điểm
lợi quan trọng của cơ chế này là các chương trình được chạy có thể lớn hợn bộ
nhớ vật lý.Ngoài ra, bộ nhớ ảo phóng đại bộ nhớ chính thành bộ nhớ luận lý cực
lớn khi được hiển thị bởi người dùng.Kỹ thuật này giải phóng người lập
trình từ việc quan tâm đến giới hạn kích thước bộ nhớ.Bộ nhớ ảo cũng cho
phép các quá trình dễ dàng chia sẽ tập tin và không gian địa chỉ, cung cấp cơ
chế hữu hiện cho quá trình

9
Minh họa bộ nhớ ảo lớn hơn bộ nhớ vật lý
V. Các lỗ hổng trong quản lý bộ nhớ
1. Lỗ hổng trong kỹ thuật cấp phát bộ nhớ
• Phân mảnh ngoài
Phân mảnh ngoài là hiện tượng khi tổng bộ nhớ trống đủ lớn để đáp ứng một
yêu cầu nào đó nhưng các khoảng trống không liên tục mà rải rác trên toàn bộ bộ
nhớ
• Nguyên nhân
Là do khi nhiều tiến trình được tải vào,sau đó giải phóng bộ
nhớ,không gian bộ nhớ trống bị phân thành nhiều mảnh nhỏ
• Phân mảnh trong
Phân mảnh trong là hiện tượng kích thước vùng nhớ hệ điều hành có thể cấp
phát hơi lớn hơn so với kích thước vùng nhớ mà tiến trình yêu cầu,theo đó chi phí
quản lý khoảng nhớ thừa đó lớn hơn rất nhiều so với chính giá trị của khoảng nhớ
đó.
Phân mảnh trong xảy ra trong kỹ thuật phân vùng cố định và kỹ thuật phân
trang.do các vung nhớ được chia thành các vùng nhớ cố định
• Page Fault
Page faults xảy ra khi một chương trình truy cập đến một được ánh xạ trong
không gian địa chỉ ảo nhưng chưa được lưu vào bộ nhớ vật lý.
• Nguyên nhân:
Một lỗi trang xảy ra khi bộ xử lý truy cập tới một địa chỉ mà các trang
tương ứng với địa chỉ đó không được đánh dấu trong cácMMU (đơn vị

10
quản lý bộ nhớ) khi được nạp trong bộ nhớ. Các lỗi phần cứng hoặc lỗi
phát sinh trong trường hợp này phụ thuộc vào kiến trúc tập lệnh của bộ
xử lý. Với một số tập lệnh kiến trúc, các lỗi phần cứng trong câu hỏi có
thể được tạo ra bởi các điều kiện khác hơn là một truy cập vào một địa
chỉ trong một trang không được tải vào bộ nhớ, điều này có nghĩa là bộ
xử lý cho rằng lỗi phần cứng sẽ phải tìm xem nó có tương ứng với một trang lỗi
hay không.
2. Lỗ hổng do chương trình
• Memory leak
Rò rỉ bộ nhớ xảy ra khi một chương trình sử dụng bộ nhớ nhưng lại không có
khả năng trả lại cho hệ điều hành.
• Nguyên nhân:
Nguyên nhân sâu xa của rò rỉ bộ nhớ là do xảy ra trục trặc của một hay nhiều
chương trinh.về cơ bản,chươn trình lỗi giải phóng bộ nhớ,bộ nhớ không còn được
tái sử dụng thành vùng bộ nhớ trống.kết quả là vùng nhớ đã được sử dụng không
được xóa đi để sử dụng cho chương trình khác và vì vậy,làm giảm khả năng điều
hành của máy tính
Bất cứ chương trình nào cũng có thể là nguồn cho rò rỉ bộ nhớ.trong một vài
trường hợp,đó có thể là một chương trình ứng dụng,như một cơ sở dữ liệu trên ổ
cứng.ngoài ra,nguyên nhân của rò rỉ bộ nhớ có thể là do một trong những file
chương trình thiết yếu điều khiển hệ điều hành
• Dangling Pointer
Trong nhiều chương trình,bộ nhớ được cấp phát thành những đối tượng chứa dữ
liệu,sau khi sử dụng những đối tượng đó, ,để tiết kiện nguồn tài nguyên hệ
thống,ứng dụng cuối cùng sẽ thu hồi lại đối tượng đó.khi thực hiện, ứng dụng đó sẽ
sử dụng một con trỏ để trỏ đến đối tượng đã thực sự được cấp phát đó.tuy
nhiên,trong nhiều trường hợp, chương trình sẽ thực thi mà con trỏ lại trỏ đến một
vùng nhớ mà không chứa các đối tượng chứa dữ liệu,hoặc trỏ đến vùng nhớ mà đối
tượng đã bị thu hồi(vùng nhớ được giải phóng),dẫn đến chương trình bị đổ vỡ hoặc
tiềm ẩn nhiều lỗ hổng.
• Nguyên nhân:
Có 2 nguyên nhân cơ bản dẫn đến một Dangling Pointer:
• Chương trình sử dụng đối tượng(như C++ )sau khi vùng nhớ đó đã được
giải phóng,được giải phóng,và do đó sẽ truy nhập vào vùng nhớ không có
giá trị.
• Khi một con trỏ trỏ tới một vùng nhớ chưa được cấp phát(còn gọi là wild
pointer).

11
Dangling
Pointer Pointer Pointer Dangling
pointer(wi Pointer
ld pointer)

Dangling pointer
Vùng nhớ
Delete trỏ tới một vùng
chưa được Objec Objec d
cấp phát
t t nhớ đã bị thu hồi
object

Trong những trường hợp trên, sử dụng một dangling pointer có thể cho
những kết quả không mong muốn.hầu hết các kết quả chung của lỗi này là gây ra
sự cố chương trình hoặc luồng đang chạy. khi xảy ra lỗi dangling pointer,một
người có thể điều khiển dữ liệu mà dangling pointer trỏ tới,nếu điều đó xảy
ra,người đó có thể thay đổi các trạng thái của chương trình,thậm chí là chèn các mã
độc vào trong đó.
• Buffer overflow(Lỗi tràn bộ nhớ đệm)
Lỗi tràn bộ nhớ đệm là một điều kiện bất thường khi một tiến trình lưu dữ liệu
vượt ra ngoài biên của một bộ nhớ đệm có chiều dài cố định, Kết quả là dữ liệu đó
sẽ đè lên các vị trí bộ nhớ liền kề. Dữ liệu bị ghi đè có thể bao gồm các bộ nhớ
đệm khác, các biến và dữ liệu điều khiển luồng chạy của chương trình (program
flow control).
• Nguyên nhân:
Một lỗi tràn bộ nhớ đệm xảy ra khi dữ liệu được viết vào một bộ nhớ đệm, mà
do không kiểm tra biên đầy đủ nên đã ghi đè lên vùng bộ nhớ liền kề và làm hỏng
các giá trị dữ liệu tại các địa chỉ bộ nhớ kề với vùng bộ nhớ đệm đó.
Các lỗi tràn bộ đệm có thể làm cho một tiến trình đổ vỡ hoặc cho ra các kết quả
sai. Các lỗi này có thể được kích hoạt bởi các dữ liệu vào được thiết kế đặc biệt để
thực thi các đoạn mã phá hoại hoặc để làm cho chương trình hoạt động một cách
không như mong đợi. Bằng cách đó, các lỗi tràn bộ đệm gây ra nhiều lỗ hổn bảo
mật (vulnerability) đối với phần mềm và tạo cơ sở cho nhiều thủ thuật khai
thác (exploit). Việc kiểm tra biên (bounds checking) đầy đủ bởi lập trình viên
hoặc trình biên dịch có thể ngăn chặn các lỗi tràn bộ đệm.
• Ví dụ cơ bản:
Mã nguồn C dưới đây thể hiện một lỗi lập trình thường gặp. Sau khi được biên
dịch, chương trình sẽ tạo ra một lỗi tràn bộ đệm nếu nó được gọi với một tham số
dòng lệnh là một xâu ký tự quá dài, vì tham số này được dùng để ghi vào một bộ
nhớ đệm mà không kiểm tra độ dài của nó.

12
/* overflow.c - demonstrates a buffer overflow */

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])


{
char buffer[10];
if (argc < 2)
{
fprintf(stderr, "USAGE: %s string\n", argv[0]);
return 1;
}
strcpy(buffer, argv[1]);
return 0;
}

Các xâu ký tự độ dài không quá 9 sẽ không gây tràn bộ đệm. Các xâu ký tự gồm từ
10 ký tự trở lên sẽ gây tràn bộ đệm
• Có 2 loại lỗi tràn bộ đệm:
1. Tràn bộ nhớ đệm stack(stack buffer overflow)
Tràn bộ nhớ đệm xảy ra khi một chương trình ghi đè lên một địa chỉ bộ nhớ trên
vùng call stack (vùng cấu trúc dữ liệu lưu trữ thông tin về các thủ tục,các chương
trình con)bên ngoài vùng cấu trúc dữ liệu đã định sẵn,thường có độ dài cố định.lỗi
tràn bộ đệm xảy ra khi một chương trình ghi nhiều dữ liệu hơn so với vùng đệm
mà nó được cấp phát.điều này dẫn đến sự sai lệch dữ liệu vùng gần kề đó trên
stack.trong trường hợp tràn gây ra lỗi sai,sẽ làm cho chương trình đổ vỡ hoặc chạy
không còn đúng nữa.
2. Tràn bộ nhớ heap(heap overflow)
Heap overflow là lối tràn bộ nhớ đệm xảy ra trong vùng dữ liệu heap,bộ nhớ
heap được cấp phát động bởi các ứng dụng tại thời điểm thực thi và thường chứa
dữ liệu của chương trình.lỗi này có thể khai thác được dữ liệu bằng cách là cho
ứng dụng ghi đè lên các cấu trúc dữ liệu nội bộ chẳng hạn các con trỏ của danh
sách liên kết.Ví dụ: Lỗ hổng của Microsoft JPEGGDI+.

13
• Segmentation fault

Một segmentation fault xảy ra khi một chương trình cố gắng truy nhập vào
một vùng nhớ không được phép truy nhập,hoặc cố gắng truy nhập vào vùng
nhớ đã bị hạn chế phương thức truy nhập(ví dụ,cố ghi lên vùng nhớ chỉ để
đọc(read-only) hoặc ghi đè lên một phần vùng nhớ dành cho hệ điều hành)

• Nguyên nhân :
Một vài nguyên nhân của một lỗi phân đoạn có thể được tóm tắt như sau:
• Cố gắng thực hiện chương trình khi mà chương trình không được biên
dịch đúng.chú ý rằng hầu hết các trình biên dịch sẽ không xuất ra một
mã máy khi xảy ra lỗi thời gian biên dịch .

• Xảy ra lỗi tràn bộ đệm

• Sử dụng một con trỏ chưa được cấp phát

• Truy cập vào vùng nhớ con trỏ Null

• cố gắng truy cập bộ nhớ chương trình không sở hữu

• cố gắng làm thay đổi bộ nhớ các chương trình không sở hữu.

C. KẾT LUẬN

Quản lý bộ nhớ trong hệ điều hành phải luôn đảm bảo 2 yếu tố quan trọng
nhất đó là tiết kiệm bộ nhớ và bảo vệ bộ nhớ,việc tổ chức cấu trúc chương trình
và cấp phát bộ nhớ tốt sẽ giảm nguy cơ gây lãng phí bộ nhớ.các lỗi lập trình là
nguyên nhân chính dẫn đến các lỗi về bảo vệ bộ nhớ,các lỗi này khi đã xảy ra là
không thể chống đỡ,chính vì vậy mà các kẻ có ý đồ xấu thường lợi dụng vào
các lỗi này để khai thác và tấn công vào hệ thống,các chương trình ứng
dung,tranh quyền,làm tăng các nguy cơ bảo mật….. Việc quan tâm tới bảo vệ
bộ nhớ(,lựa chọn ngôn ngữ,kiểm tra biên,xử lí ngoại lệ…) sẽ làm giảm được
các nguy cơ đó.

14
Tài liệu tham khảo:

1. Giao trình nguyên lý hệ điều hành-Đặng Vũ Tùng,nhà xuất bản Hà Nội

2. Bài giảng nguyên lý Hệ Điều Hành - Khoa CNTT trường ĐH Bách Khoa
Hà Nội

3. Wikipedia.com

15

You might also like