1. Trang chủ
  2. » Công Nghệ Thông Tin

Cơ chế bảo mật mã thực thi trên linux

66 165 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 66
Dung lượng 1,16 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Code Signing đã được cài đặt trên nhiều nền tảng khác nhau như trên hệ thống định dạng file thực thi của Microsoft Windows, .NET Framework, các ứng dụng Java, extension của Fir

Trang 1

BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI

-

TRIỆU MINH TUÂN

CƠ CHẾ BẢO MẬT MÃ THỰC THI TRÊN LINUX

LUẬN VĂN THẠC SĨ KỸ THUẬT

KỸ THUẬT MÁY TÍNH VÀ TRUYỀN THÔNG

Trang 2

1

LỜI CAM ĐOAN

Tôi xin cam đoan đề tài nghiên cứu của tôi hoàn toàn do tôi tự làm dưới sự hướng dẫn của cô giáo Tiến sỹ Trương Thị Diệu Linh Các số liệu, kết quả trình bày trong luận văn là hoàn toàn trung thực và chưa từng được công bố trong bất cứ công trình nghiên cứu nào

Các tài liệu tham khảo sử dụng trong luận văn đều được dẫn nguồn (có bảng thống kê các tài liệu tham khảo) hoặc được sự đồng ý trực tiếp của tác giả

Nếu xảy ra bất cứ điều không đúng như những lời cam đoan trên, tôi xin chịu hoàn toàn trách nhiệm trước Viện và Nhà trường

Hà Nội, ngày 10 tháng 3 năm 2014 Tác giả

Triệu Minh Tuân

Trang 3

và nghiên cứu tại đây Với vốn kiến thức được tiếp thu trong quá trình học tập và nghiên cứu không chỉ là nền tảng cho quá trình nghiên cứu khóa luận mà còn là hành trang quí báu để tôi bước vào đời một cách vững chắc và tự tin

Tôi cũng xin được gửi lời cảm ơn sự ủng hộ giúp đỡ nhiệt tình của những anh chị em trong lớp cùng những người đồng nghiệp, gia đình và bạn bè – những người thân yêu của tôi, những người luôn là chỗ dựa vững chắc cho tôi, để tôi có nỗ lực quyết tâm hoàn thành nghiên cứu này

Cuối cùng, tôi xin kính chúc Quý Thầy cô, Đồng nghiệp, Gia đình dồi dào sức khỏe và thành công trong con đường sự nghiệp cao quý

Tôi xin trân trọng cảm ơn!

Học viên

Triệu Minh Tuân

Trang 4

3

MỤC LỤC

LỜI CAM ĐOAN 1

LỜI CẢM ƠN 2

MỤC LỤC 3

DANH MỤC HÌNH VẼ 5

PHẦN MỞ ĐẦU 7

CHƯƠNG 1 - NHÂN LINUX VÀ CƠ CHẾ THỰC THI ỨNG DỤNG 9

1.1 TỔNG QUAN VỀ NHÂN LINUX 9

1.1.1 Định nghĩa nhân linux 9

1.1.2 Thiết kế và thành phần Linux Kernel 10

1.1.3 Sự phát triển của Linux Kernel 13

1.1.4 Mã nguồn linux kernel 17

1.2 TIẾN TRÌNH VÀ FILE THỰC THI TRONG LINUX 22

1.2.1 Tiến trình 22

1.2.2 Lời gọi hệ thống (System call) 23

1.2.3 Mã thực thi (Excutable code) 24

1.2.4 File thực thi (Executable File) 25

1.2.5 Thư viện hỗ trợ (Shared libraries) 25

1.2.6 Định dạng file thực thi 26

1.2.7 Quá trình thực thi một file 28

CHƯƠNG 2 - CODE SIGNING VÀ ĐỊNH HƯỚNG TÍCH HỢP 34

2.1 CODE SIGNING VÀ CÁC NGHIÊN CỨU LIÊN QUAN 34

2.1.1 Định nghĩa code signing 34

2.1.2 Các nghiên cứu code signing 40

2.2 PHÂN TÍCH VÀ ĐỊNH HƯỚNG GIẢI PHÁP 46

CHƯƠNG 3 - TÍCH HỢP CODE SIGNING VÀO NHÂN LINUX 50

3.1 MÔ TẢ GIẢI PHÁP TÍCH HỢP 50

3.2 ĐÁNH GIÁ GIẢI PHÁP 59

3.3 ĐỊNH HƯỚNG PHÁT TRIỂN 61

Trang 5

4

KẾT LUẬN 63 TÀI LIỆU THAM KHẢO 64

Trang 6

5

DANH MỤC HÌNH VẼ

Hình 1 User space & Kernel space 10

Hình 2 Tầng trung gian giữa user & filesystem 12

Hình 3 Kernel Subsystem 13

Hình 4 Timeline of Linux kernel version 16

Hình 5 The linux kernel archives website (www.kernel.org) 17

Hình 6 Cấu trúc thư mục con chứa mã nguồn linux kernel 18

Hình 7 Cấu trúc thư mục linux kernel phiên bản v3.x 19

Hình 8 Mã nguồn linux kernel 20

Hình 9 Giao tiếp Application với Hardware qua lời gọi hệ thống 23

Hình 10 Mô tả lời gọi hệ thống 24

Hình 11 Định dạng ELF 27

Hình 12 Cơ chế fork-and-exec 30

Hình 13 Tạo tiến trình dưới góc độ hệ thống 31

Hình 14 Luồng khởi tạo cấu hình thực thi mới 32

Hình 15 Mô hình ký dữ liệu 36

Hình 16 Mô hình xác minh chữ ký 37

Hình 17 Cảnh báo của Morilla khi cài đặt phần mềm 39

Hình 18 Xcode code signing 39

Hình 19 Mô hình sign-and-verify 48

Hình 20 Vị trí các node có thể thực hiện xác minh chữ ký trong lộ trình thực thi file 49

Trang 7

6

Hình 21 Xác minh chữ ký xử lý tại do_execve_common 51Hình 22 Xác minh chữ ký tại do_mmap_pgoff 52Hình 23 Đặc tả cấu trúc chữ ký 53

Trang 8

7

PHẦN MỞ ĐẦU

Hiện nay, sau khi một chương trình ứng dụng được đưa ra và lưu hành trên mạng, rất khó tránh khỏi nguy cơ bị các hacker/cracker tấn công, chỉnh sửa, thay đổi nội dung nhằm lợi dụng cho các mục đích xấu như phát tán virus, cài đặt phần mềm theo dõi, botnet, đánh cắp dữ liệu cá nhân… Các tình huống này thường xuyên gặp phải với các người dùng hệ điều hành Microsoft Windows và đã gây thiệt hại nặng nề cho cả người dùng và doanh nghiệp trong và ngoài nước Đặc biệt phải kể đến sự kiện đầu năm

2012, một nhóm hacker có tên là Sinh Tử Lệnh đã đính kèm mã độc vào bộ cài đặt phần mềm gõ tiếng việt unikey, một phần mềm khá phổ biến với cộng đồng người dùng Windows trong và ngoài nước, từ đó, lợi dụng những máy tính này đi tấn công từ chối dịch vụ các website, diễn đàn doanh nghiệp trong nước, phải kể đến đó là vụ tấn công vào website báo điện tử Vietnamnet và website công ty an ninh mạng Bkav, chỉ trong vòng chưa đầy 12 tiếng, cả hai website đã hoàn toàn tê liệt

Rất nhiều nghiên cứu được đưa ra nhằm khắc phục tình trạng trên, trong đó có giải pháp code signing Code Signing là phương pháp “ký điện tử” vào các mã thực thi để đảm bảo rằng các mã thực thi này chưa bị chỉnh sửa, thay đổi nội dung tính từ thời điểm được ký

Code Signing đã được cài đặt trên nhiều nền tảng khác nhau như trên hệ thống định dạng file thực thi của Microsoft Windows, NET Framework, các ứng dụng Java, extension của Firefox, trên các phiên bản nhân linux cũ (2.6.x trở về trước)… nhưng với các cập nhật nhân mới gần đây 3.x thì vẫn chưa có lời giải hợp lý nào cho bài toán Code signing trên hệ thống hệ điều hành này Đây cũng có thể là một lỗ hổng để các hacker lợi dụng và khai thác trên hệ thống các hệ điều hành sử dụng phiên bản nhân mới này

Trang 9

8

Đây cũng chính là lý do, tác giả lựa chọn đề tài “Cơ chế bảo mật mã thực thi trên Linux” nhằm mục đích nghiên cứu, bổ sung cơ chế code signing lên các phiên bản nhân linux mới này từ đó hỗ trợ kiểm tra tính toàn vẹn các nội dung thực thi

Trong thời gian sáu tháng nghiên cứu và tìm hiểu về mã nguồn linux kernel và các vấn đề có liên quan đến tiến trình và file thực thi trên hệ điều hành linux, luận văn đã đưa

ra được định hướng tích hợp thành công cơ chế code signing lên phiên bản linux kernel 3.10.10 trong đó, có xử lý kiểm tra các thư viện phụ thuộc có liên quan trực tiếp trong linux kernel

Trang 10

9

CHƯƠNG 1 - NHÂN LINUX VÀ CƠ CHẾ THỰC THI

ỨNG DỤNG

1.1 Tổng quan về nhân linux

1.1.1 Định nghĩa nhân linux

Trong lĩnh vực khoa học máy tính, đặc biệt là trong các nghiên cứu liên quan đến hệ thống, hệ điều hành, thuật ngữ nhân (kernel) dùng để chỉ phần “lõi” của bất cứ hệ thống máy tính nào hay nói theo cách khác là phần mềm hỗ trợ người dùng chia sẻ tài nguyên máy tính.Thuật ngữ kernel cũng có thể được biết đến như là phần quan trọng nhất của hệ điều hành

Nhân linux (linux kernel) là phần nhân hệ thống hệ điều hành Unix, được sử dụng trên rất nhiều các bản phân phối linux (Linux distribution) (các hệ điều hành phát triển từ nhân linux) Không như hệ thống hệ điều hành Windows của Microsoft, nhân linux là một ví dụ nổi bật của phần mềm tự do mã nguồn mở (open source software)

Phiên bản nhân linux đầu tiên được phát triển vào năm 1991 bởi cậu sinh viên người Phần Lan đang học chuyên ngành khoa học máy tính trường Linus Tovards Trong ba năm sau đó, ông tiếp tục nghiên cứu và cho ra đời phiên bản Linux 1.0 vào năm 1994 Phiên bản này được tung ra thị trường dưới bản quyền của GNU General Public License, do đó, mã nguồn của Linux là hoàn toàn mở, bất cứ ai cũng có thể tải và xem

Khởi đầu, Linux kernel được phát triển bởi những con người nhiệt huyết đam mê nghiên cứu Tuy nhiên với những đóng góp từ cộng đồng và người dùng, Linux kernel đang ngày một phát triển và hiện nay đang thu hút sự hỗ trợ đầu tư của các công ty

Trang 11

10

điện toán hàng đầu trên thế giới như IBM, HP (Hewlette-Packard) đồng thời là một thách thức cạnh tranh với các hệ điều hành thương mại như Windows của Microsoft mặc dù số lượng phần cứng được hỗ trợ bởi Linux vẫn còn rất giới hạn so với các hệ điều hành này nhưng với sự ủng hộ nhiệt tình từ cộng đồng, trong một tương lai không

xa, nhược điểm này hoàn toàn có thể được khắc phục

1.1.2 Thiết kế và thành phần Linux Kernel

Các hệ điều hành hiện đại thường tách biệt không gian bộ nhớ ảo thành hai phần kernel space và user space nhằm mục đích bảo vệ các vùng nhớ khỏi các truy cập trái phép, lỗi hệ thống… Kernel space là phần không gian bộ nhớ cho phép linux kernel, module phần mở rộng và các module driver thiết bị thực thi Ngược lại, user space là phần

Trang 12

11

không gian để chạy các phần mềm ứng dụng, thư viện và drivers được sử dụng để tương tác với kernel Khác với các ứng dụng trên User space, được nạp trong những không gian địa chỉ ảo, linux kernel được nạp vào kernel space trong một không gian địa chỉ riêng

Linux kernel có thể được chia thành ba cấp Cấp cao nhất là giao diện các lời gọi hệ thống (System call interface), thực hiện các chức năng cơ bản như đọc ghi Cấp thấp hơn là Kernel code, chứa các mã kernel không phụ thuộc vào kiến trúc (the architecture-independent kernel code) là phần chung với tất cả các kiến trúc vi xử lý hỗ trợ bởi Linux Cấp thấp nhất là phần mã phụ thuộc vào kiến trúc (Architecture-dependent kernel code), là phần mã được viết riêng cho các kiến trúc phần cứng tương ứng

Các thành phần chính của nhân linux bao gồm:

 Giao diện lời gọi hệ thống (System Call Interface): cung cấp giao diện thực thi các lời gọi chức năng từ User space xuống kernel space Thành phần này có thể phục thuộc vào kiến trúc phần cứng, ngay cả khi sử dụng cùng họ vi xử lý

 Quản lý tiến trình (Process Management): thành phần tập trung vào việc thực thi các tiến trình Trong kernel, đây được gọi là các luồng thực thi và thể hiện cơ chế ảo hóa đặc biệt của vi xử lý (mã thực thi, dữ liệu, stack và các thanh ghi CPU) Qua giao diện lời gọi hệ thống SCI, kernel cung cấp các API hỗ trợ việc tạo, giao tiếp, đồng bộ và dừng các tiến trình này Thành phần này được sử dụng

để chia sẻ CPU giữa các luồng đang hoạt động

Trang 13

12

 Quản lý bộ nhớ (Memory Management): qua module mà phần cứng hỗ trợ để quản lý bộ nhớ, bộ nhớ được quản lý trong các trang (thường có kích thước 4KB), bao gồm các phương tiện quản lý bộ nhớ cũng như các cơ chế phần cứng

để ánh xạ giữa bộ nhớ vật lý và bộ nhớ ảo

 Virtual File System (VFS): cung cấp giao diện chung để tương tác với các loại file systems VFS cung cấp một lớp trung gian giữa SCI và các loại File System được Linux hỗ trợ

Hình 2 Tầng trung gian giữa user & filesystem

Phần trên của VFS cung cấp một giao diện các API chung bao gồm các chức năng mở, đóng, đọc ghi Phần dưới của VFS là sự trừu tượng các File System hay định nghĩa cách mà các chức năng ở lớp trên thực thi Bên cạnh đó, buffer cache cung cấp một tập các chức năng cho tầng hệ thống nhằm tối ưu truy cập tới các thiết bị vật lý bằng cách thực hiện cache dữ liệu

Trang 14

13

 Network Stack: dựa theo một kiến trúc phân lớp theo chuẩn của các giao thức TCP/IP Trong đó, lớp TCP giao tiếp với SCI thong qua các socket, các sockets cung cấp một tập các API cho các networking subsystem phục vụ việc quản lý các kết nối, định hướng dữ liệu tới đích (endpoints)

 Device Drivers: là thành phần chủ yếu trong mã nguồn linux kernel, đặc tả các tích hợp các thiết bị hỗ trợ như BlueTooth, I2C, Serial …

 Architecture-dependent code: đặc tả các thành phần phụ thuộc vào hạ tầng phần cứng

Trang 15

 1994: Trong tháng ba, Torvards tuyên bố tất cả các thành phần của nhân đã hoàn thiện: ông cho ra đời phiên bản Linux 1.0, phiên bản này chỉ hỗ trợ các hệ máy tính vi xử lý đơn i386 Cũng trong năm này, các công ty Red Hat và SUSE cũng xuất bản bản phân phối Linux 1.0 của họ

 1995: Linux được port sang hai nền tảng DEC Alpha và Sun SPARC Nhiều năm sau đó, Linux được port sang rất nhiều các nền tảng khác

 1996 : Phiên bản Linux kernel 2.0 được xuất bản, hỗ trợ xử lý nhiều vi xử lý đồng thời

 1998 : Rất nhiều các công ty lớn như IBM, Compaq và Oracle tuyên bố hỗ trợ Linux, giao diện KDE cũng bắt đầu được phát triển

 2003 : Phiên bản Linux Kernel 2.6 được xuất bản được tích hợp rất nhiều cấc tính năng mới như hỗ trợ PAE, hỗ SELinux, User-mode Linux vào nhánh chính của mã nguồn kernel …

 2011 : Phiên bản nhân linux 3.0 được xuất bản với hơn 14 triệu dòng code (14647033) và gần 40000 files trong project mã nguồn

Trang 16

15

 2014 : Tính đến tháng 3/2014, với đội ngũ hỗ trợ khổng lồ, cộng đồng phát triển linux kernel đã xuất bản phiên bản 3.14 và đang dần hoàn thiện phiên bản linux kernel 3.2

Cách đánh số phiên bản linux kernel :

Trong quá trình phát triển, nhân linux có ba cách đánh số khác nhau :

 Cách thứ nhất được sử dụng theo định dạng « 1.0 » Phiên bản đầu tiên của kernel là 0.01, tiếp đó là 0.02, 0.03, 0.10, 0.11, 0.12 (GPL version), 0.95, 0.96, 0.97, 0.98, 0.99 và sau đó là 1.0

 Từ phiên bản 1.0 đến 2.6, cách đánh version theo kiểu « A.B.C », trong đó A là phiên bản kernel, B là số phiên bản chỉnh sửa lớn của kernel (major version), C là số phiên bản chỉnh sửa nhỏ của kernel (minor version) Số phiên bản chỉ được thay đổi khi kernel có sự thay đổi, điều chỉnh lớn Đã có 3 lần thay đổi số version là 1994 (version 1.0), 1996 (version 2.0) và 2011 (version 3) Major revision được đánh số theo hệ thống quy luật even-odd system version numbering system (số lẻ tương ứng với phiên bản chưa thử nghiệm, số chẵn tương ứng với phiên bản ổn định) Minor revision được cập nhật lại mỗi khi có bản cập nhật, fix bugs, thêm tính năng mới vào kernel

Trang 17

16

Hình 4 Timeline of Linux kernel version

Trang 18

17

1.1.4 Mã nguồn linux kernel

Đa số các bản phân phối của linux đều đính kèm mã nguồn nhân linux trong các bộ cài đặt của chúng Tuy nhiên đây thường chỉ là các bản kernel tại thời điểm phiên bản phân phối này được nghiên cứu, chưa phải là phiên bản mới nhất của linux kernel

các phiên bản mã nguồn linux kernel , cung cấp môi trường cho các nhà phát triển nhân, bảo trì các bản phân phối của linux cũng là server cung cấp những phiên bản linux kernel mới nhất cho cộng đồng người dùng linux

Hình 5 The linux kernel archives website (www.kernel.org)

Kernel.org hỗ trợ nhiều giao thức khác nhau để người dùng có thể kết nối và cập nhật

dữ liệu:

 Giao thức HTTP (https://ww.kernel.org/pub/)

 Giao thức truyền tải file FTP(ftp://ftp.kernel.org/pub/)

Trang 19

18

 Giao thức đồng bộ dữ liệu (rsync://rsync.kernel.org/pub/)

Mã nguồn linux kernel được tổ chức trong thư mục con /pub/linux/kernel:

Hình 6 Cấu trúc thư mục con chứa mã nguồn linux kernel

…được sắp xếp theo từng phiên bản, mỗi phiên bản một thư mục (v1.0/, v1.1/, v1.2/, v1.3/, v2.0/…) trong mỗi thư mục là các phiên bản mã nguồn và các bản vá patch tương ứng với phiên bản đó:

Trang 20

19

Hình 7 Cấu trúc thư mục linux kernel phiên bản v3.x

Mã nguồn linux kernel được nén theo định dạng tar, bao gồm một tập hợp rất nhiều file và thư mục:

Trang 21

20

Hình 8 Mã nguồn linux kernel

 Thư mục arch: bao gồm nhiều thư mục con, mỗi thư mục con là một kiến trúc cpu mà linux kernel hỗ trợ

 Thư mục include: bao gồm danh sách các header thư viện được sử dụng để build

mã nguồn kernel, thư mục này cũng bao gồm nhiều thư mục con tương ứng với các kiến trúc cpu khác nhau

 Thư mục init: Thư mục chứa mã nguồn khởi tạo kernel

 Thư mục mm: thư mục mã nguồn module quản lý bộ nhớ, ứng với mỗi kiến trúc CPU khác nhau, mã nguồn module này được đặt trong các thư mục con arch/*/mm (ví dụ: arch/i386/mm/)

 Thư mục drivers: thư mục chứa mã nguồn các drivers thiết bị trong kernel

 Thư mục ipc: thư mục chứa mã nguồn module giao tiếp giữa các tiến trình trong kernel

 Thư mục modules: thư mục chứa các module đã được build (từ mã nguồn)

 Thư mục fs: thư mục chứa mã nguồn các file system mà kernel hỗ trợ, bao gồm nhiều thư mục con, mỗi thư mục con tương ứng với một loại file system mà linux kernel hỗ trợ

Trang 22

21

 Thư mục kernel: thư mục chứa mã nguồn chính của kernel, ứng với mỗi kiến trúc cpu khác nhau, mã nguồn module này được đặt trong thư mục con arch/*/kernel

 Thư mục net: thư mục chứa mã nguồn các module network trong kernel

 Thư mục lib: thư mục chứa các thư việc của linux kernel, tương tự, ứng với mỗi kiến trúc CPU khác nhau, mã nguồn module này được đặt trong các thư mục con trong thư mục arch: arch/*/lib/

 Thư mục scripts/: thư mục chứa các scripts được sử dụng khi kernel được cấu hình

 Thư mục Documentation/: thư mục chứa rất nhiều tài liệu thông tin mô tả, cấu hình kernel và các module

 Thư mục crypto: thư mục chứa mã nguồn các cryptographic API được sử dụng bởi kernel

 Thư mục security/: thư mục chứa mã nguồn của các module bảo mật trong linux bao gồm SE Linux (Security-Enhanced Linux), các module network hooking

 Thư mục sound/: thư mục chứa mã nguồn driver âm thanh và các thiết bị tương tự

 Thư mục usr/: thư mục chứa mã nguồn để build định dạng cpio (định dạng lưu

trữ file trong các hệ điều hành Unix) các chứa ảnh filesystem gốc sẽ được sử

dụng trên userspace

Trang 23

22

1.2 Tiến trình và file thực thi trong linux

Tiến trình là thành phần chỉnh trong bất cứ hệ điều hành đa nhiệm nào, tiến trình thực thi các tác vụ trong hệ thống để giải quyết các bài toán do người dùng yêu cầu Do đó,

để nghiên cứu bảo mật mã thực thi, trước hết chúng ta phải nắm được tổ chức tiến trình

và các file thực thi trong linux kernel

1.2.1 Tiến trình

Theo lý thuyết hệ điều hành trong khoa học máy tính: tiến trình được định nghĩa như sau:

“A process is an instance of a program in execution”

“Tiến trình là một instance của một chương trình đang được thực thi”

Hiểu một cách đơn giản hơn, tiến trình là ánh xạ của một chương trình thực thi (dữ liệu trên ổ cứng) lên bộ nhớ Sâu hơn nữa, có thể hiểu tiến trình là một thực thể tiêu tốn các tài nguyên hệ thống như CPU, bộ nhớ …

Tiến trình cũng có quan hệ cha-con: một tiến trình có cha là tiến trình thực hiện lời gọi tạo ra nó, khi đó, tiến trình này là tiến trình con của tiến trình kia và ngược lại Khi một tiến trình được tạo, tiến trình này đồng nhất với tiến trình cha của nó Nó nhận một bản sao logic không gian địa chỉ nhớ từ tiến trình cha và thực thi cùng

một mã thực thi như tiến trình cha nhưng bắt đầu từ các thực thi sau lời gọi hệ

thống tạo tiến trình (system call) Mặc dù tiến trình cha và tiến trình con có thể

sử dụng chung một trang nhớ để chứa mã thực thi của chương trình (program code) nhưng mỗi tiến trình đều sử dụng các bản sao dữ liệu (bộ nhớ stack và heap) riêng nên thay đổi từ tiến trình con không ảnh hưởng tới tiến trình cha và ngược lại

Trang 24

23

Trong mã nguồn của linux kernel, tiến trình thường được định nghĩa như các tasks hoặc các threads

1.2.2 Lời gọi hệ thống (System call)

Hệ điều hành thường cung cấp cho các tiến trình chạy trong User Mode một tập các interface để tương tác với các thiết bị phần cứng như CPU, ổ cứng, máy in … bằng bổ sung vào giữa tầng ứng dụng và phần cứng thêm một lớp trung gian:

Hình 9 Giao tiếp Application với Hardware qua lời gọi hệ thống

Các lời gọi hệ thống (system calls) được đặt giữa ứng dụng và kernel, là thành phần

“chuyển mạch” từ Usermode  Kernelmode để xử lý các tương tácvới tài nguyên

phần cứng

Nhờ đó, các chương trình ứng dụng có tính chất portable hơn, dễ dàng biên dịch và thực thi trên nhiều kernel khác nhau có cùng chung interfaces

Trang 25

24

Khi một tiến trình từ User mode thực hiện lời gọi hệ thống, CPU được chuyển quyền cho Kernel Mode và bắt đầu thực thi các hàm chức năng tương ứng trong nhân:

Hình 10 Mô tả lời gọi hệ thống

Trong đó, system call handler là thành phần thực hiện lưu lại các thông tin dữ liệu từ usermode (các thanh ghi) vào stack của kernel, sau đó kích hoạt chức năng xử lý tương ứng (System call service routine), sau khi thành phần này thực hiện xong, các cấu hình

dữ liệu nêu trên được khôi phục từ Kernel Stack và CPU được chuyển trở lại User mode

1.2.3 Mã thực thi (Excutable code)

Mã thực thi có thể được hiểu là một dạng phần mềm có thể “chạy” được trong máy tính hay nói các khác đó là các chuỗi dữ liệu được máy tính hiểu và biên dịch thành các tác

vụ tính toán, thường thì chúng ta hiểu đây là các mã máy (machine language)

Trong một hệ điều hành các mã thực thi thường là các chuỗi nhị phân nằm trong các file thực thi (executable file) và thư viện hỗ trợ (shared library) Khi có một thao tác

Trang 26

25

kích hoạt như người dùng tương tác trên giao diện quản lý, ra lệnh qua các chương trình shell, các mã thực thi này được nạp vào bộ nhớ và được dịch thành mã máy qua con trỏ lệnh

1.2.4 File thực thi (Executable File)

File thực thi là chương trình nằm trên ổ cứng, chứa đầy đủ thông tin các object code của các hàm chức năng và dữ liệu để thực thi chương trình Rất nhiều các hàm trong file thực thi được cung cấp dưới các file thư viện (được link tĩnh hoặc nạp đồng khi chương trình chạy)

Giả sử người dùng muốn thực thi một chương trình từ shell, thông qua dòng lệnh được nhập vào, command shell khởi tạo một tiến trình mới, trong đó kích hoạt lời gọi hệ thống execve() với đầu vào là đường dẫn đầy đủ của chương trình Từ kernel, hàm xử

lý chức năng tương ứng sys_execve được kích hoạt, thực hiện tìm file tương ứng, kiểm tra định dạng file thực thi và cập nhật lại cấu hình thực thi theo cấu hình được mô tả trong file thực thi Khi lời gọi hệ thống thực thi xong, tiến trình thực thi các mã thực thi được mô tả trong file thực thi và thực hiện các chức năng tương ứng

1.2.5 Thư viện hỗ trợ (Shared libraries)

Như đã trình bày ở trên, các tiến trình thực thi trên User mode có thể sử dụng các thư viện để thực hiện các lời gọi hệ thống xuống kernel Do đó, ngoài những mã thực thi được biên dịch trực tiếp từ mã nguồn của chương trình, chương trình còn có thể sử dụng các mã thực thi từ các thư viện mà chương trình sử dụng

Có hai kiểu thư viện:

Trang 27

26

 Thư viện tĩnh (static libraries): trong quá trình biên dịch chương trình (có sử dụng thư viện tĩnh), chương trình liên kết (linker) thực hiện liên kết cả các mã thực thi của thư viện vào chương trình, điều này giúp cho chương trình có tính chất đóng gói, chỉ cần một file chương trình duy nhất có thể thực thi được, tuy nhiên sử dụng thư viện tĩnh cũng có nhược điểm là tiêu tốn không gian lưu trữ của ổ cứng khi nhiều chương trình cùng sử dụng một thư viện tĩnh)

 Thư viện động (shared libraries): trong quá trình biên dịch chương trình, chương trình linker không thực hiện liên kết các mã thực thi của thư viện vào chương trình mà chỉ đặt một tham chiếu tới tên thư viện, khi chương trình được thực thi, thư viện sẽ được nạp lên vùng nhớ của tiến trình Ưu điểm của dạng kiểu thư viện này là cung cấp cơ chế ánh xạ bộ nhớ - file (file memory mapping) Khi chương trình liên kết động thực hiện liên kết thư viện động vào tiến trình, các

mã thực thi của thư viện không bị copy vào chương trình mà chỉ thực hiện ánh

xạ bộ nhớ phần thư viện tương ứng sang không gian bộ nhớ của tiến trình Nhờ vậy, sử dụng kiểu thư viện này ít tốn không gian ổ cứng hơn so với thư viện tĩnh Tuy nhiên, nhược điểm của kiểu thư viện này là thời gian nạp của chương trình thường chậm hơn so với các chương trình sử dụng thư viện tĩnh, do chương trình phải thực hiện thêm các thao tác nạp thư viện lên vùng nhớ

1.2.6 Định dạng file thực thi

Một chương trình được lưu trên ổ cứng dưới dạng một file thực thi (executable file), file này bao gồm cả object code của các hàm chức năng để thực thi và dữ liệu tương ứng của các hàm chức năng này Các hàm trong thư viện có thể là được sử dụng trong các chương trình khác thông qua việc các chương trình khác “liên kết” tới các thư viện này (link tĩnh/link động) File thực thi cũng là một file có cấu trúc riêng, thông qua việc

Trang 28

Hình 11 Định dạng ELF

Mỗi ELF file bao gồm một ELF header và phần data tương ứng ngay sau đó:

Trang 29

28

 ELF header: nằm ở đầu file (từ offset đầu tiên trong file) mô tả cấu trúc sắp xếp của cả file, bắt đầu với một giá trị kiểu DWORD (magic number) tương ứng với 0x7F ‘E’ ‘L’ ‘F’ dùng để nhận dạng file định dạng ELF

 Program header table: chứa thông tin mô tả cấu hình để loader tiến hành khởi tạo tiến trình

 Section header table: chứa thông tin mô tả các sections, bảng này bao gồm nhiều section entry, mỗi section entry chứa thông tin tên section, kích thước và vị trí section trên file và trên bộ nhớ

Định dạng ELF đã được sử dụng để thay thế cho rất nhiều các định dạng thực thi cũ trong rất nhiều môi trường khác nhau, trong đó, nó thay thế cho định dạng a.out và COFF trong nhiều hệ điều hành như: Linux, Solaris, IRIX, FreeBSD, NetBSD, OpenBSD, DragonFly BSD, Syllable, HP-UX, QNX Neutrino, MINIX Ngoài ra, định dạng này cũng được chấp nhận trên nhiều hệ thống hệ điều hành khác như: OpenVMS bản Itanium, BeOS từ phiên bản 4 trở đi, Haiku, RISC OS … Bên cạnh đó, một vài hệ máy game consoles như PlayStation Portable, PlayStation 2, PlayStation 3, GP2X, Dreamcast, GameCube, Wii … và hệ điều hành cho các thiết bị di động như (Symbian

OS v9, Sony Erricsson, Siemens, Motorola, Bada, Nokia, Android …) cũng sử dụng định dạng này cho một số loại trên nền tảng tương ứng

1.2.7 Quá trình thực thi một file

Hầu hết các hệ điều hành sử dụng cơ chế spawn để tạo một tiến trình mới với không gian địa chỉ mới, cập nhật cấu hình từ file thực thi và chạy những mã thực thi tương ứng Tuy nhiên, Unix sử dụng một định hướng khác hẳn: khi một tiến trình mới được

Trang 30

29

tạo khi một tiến trình đã tồn tại tạo bản sao của chính nó Ngoại trừ process ID, tiến trình con này có cùng môi trường với tiến trình cha Quá trình này được gọi là forking (phân nhánh)

Sau khi tiến trình được forking, không gian địa chỉ của tiến trình con bị ghi đè với dữ liệu tiến trình mới thông qua lời gọi hệ thống tới hàm exec

Cơ chế fork-and-exec thực hiện chuyển những câu lệnh cũ sang những câu lệnh mới tuy nhiên môi trường tiến trình được thực thi vẫn giữ nguyên, bao gồm cấu hình của các thiết bị đầu vào đầu ra, thông tin biến môi trường… đây là cơ chế được sử dụng để

tạo tiến trình trong hệ điều hành Linux Tiến trình đầu tiên init (process ID 1) cũng

tuân theo cơ chế này, tiến trình này được tạo (forking) trong quá trình khởi động

Trang 31

30

Hình 12 Cơ chế fork-and-exec

Trong nhiều trường hợp, tiến trình init trở thành tiến trình cha của nhiều process, trong khi không phải tiến trình init thực hiện khởi tạo tiến trình này Đó là trường hợp tiến trình được gọi chạy ngầm (running in background) Khi đó, ngay cả khi tiến trình cha kết thúc hoặc bị buộc phải kết thúc, tiến trình con vẫn tiếp tục thực thi

Xét dưới góc độ của lập trình viên:

Quá trình tạo một process trong Linux chia làm hai bước, sử dụng hai hàm API fork()

và exec():

Trang 32

31

 Đầu tiên fork() được gọi để tạo một tiến trình con, là bản sao của task đang làm việc (tiến trình cha) với giá trị PID (process ID) mới, giá trị PID của process gốc (gọi hàm fork()) được cập nhật vào trường PPID của process mới

 Sau đó exec() được gọi để nạp thông tin thực thi vào không gian địa chỉ mới và tiến hành chạy các mã thực thi tương ứng

Xét dưới góc độ hệ thống:

Hình 13 Tạo tiến trình dưới góc độ hệ thống

Trong đó exec()/fork() đại diện chung cho các hàm chức năng tương tự trên usermode

Từ góc độ một lập trình viên, ta thấy một tiến trình đơn giản được tạo thông qua các lời gọi tới các hàm API được cung cấp bởi linux kernel, thông qua các lời gọi hệ thống các tham số cấu hình tương ứng được truyền tới các hàm xử lý trong linux kernel Cụ thể,

ta thấy hàm fork() sẽ thực hiện truyền tham số từ usermode  kernelmode thông qua:

fork()  sys_fork()  do_fork(), do_fork() sẽ xử lý các chức năng tương ứng trong kernel để tiến hành khởi tạo môi trường cho tiến trình mới Tương tự, với exec(), các

Trang 33

32

tham số cấu hình sẽ được truyền từ usermode  kernelmode thông qua luồng làm việc sau:

exec()  sys_execve()  do_execve()  do_execve_common()

Trong đó, do_execve_common sẽ tiến hành nạp các cấu hình thực thi mới của tiến

trình từ filesystem lên bộ nhớ với luồng làm việc như sau:

Hình 14 Luồng khởi tạo cấu hình thực thi mới

Linux kernel định nghĩa một cấu trúc linux_binfmt để quản lý chung các module thực thi được hỗ trợ (kernel module, file thực thi, thư viện, coredump) Mỗi khi một module thực thi muốn được nạp lên bộ nhớ sẽ phải thông qua cấu trúc này để ánh xạ các cấu hình thực thi từ filesystem lên bộ nhớ:

 load_elf_binary: được sử dụng để ánh xạ các cấu hình thực thi của file thực thi lên bộ nhớ

Ngày đăng: 25/07/2017, 21:34

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
5. Greg Kroah (2004), “Signed Kernel Modules”, Linux Journal 7130 Sách, tạp chí
Tiêu đề: Signed Kernel Modules
Tác giả: Greg Kroah
Năm: 2004
12. M. Tim Jones (2007), “Anatomy of the Linux kernel”, IBM developerWorks Sách, tạp chí
Tiêu đề: M. Tim Jones (2007), “Anatomy of the Linux kernel
Tác giả: M. Tim Jones
Năm: 2007
1. Code Signing, http://en.wikipedia.org/wiki/Code_signing Link
2. Constantine Shulyupin (2010), Linux Kernel Map, http://www.makelinux.net/kernel_map/ Link
8. Joseph A.Fox(2011), signelf – Digitally signing ELF binaries, http://blog.codenoise.com Link
17. The linux kernel source code, http://www.linux.org/threads/the-linux-kernel-the-source-code.4204/ Link
18. The linux kernel archives, https://www.kernel.org/ Link
3. Daniel P. Bovet, Marco Cesati (2005), Understanding the linux kernel, O’Reilly Media Inc Khác
4. Dsafford, Kds_etu, mzohar, reinersailer, serge_hallyn (2014), Integrity Measurement Architecture Khác
6. Sven Vermeulen (2014), Integrity Measurement Architecture, Gentoo Wiki Khác
7. Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman (2005), Linux Device Drivers, O’reilly Inc Khác
9. Kernel module signing facility, Linux kernel documentation Khác
10. LAKSHMANAN GANAPATHY (2013), How to compile linux kernel from source to Build Custom Kernel, The geek stuff Khác
11. Mac Developer Library (2012), Code Signing Guide, Apple Inc Khác
13. Roberto Arcomano (2003), Kernel Analysis-How to, www.bertolinux.com Khác
14. Robert Love (2010), Linux kernel development, Pearson Education Khác

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w