2010-07-27 20 views
6

Tôi muốn cấp phát bộ nhớ có quyền thực thi. Vì vậy, tôi sử dụng mprotect để thay đổi quyền .. Để có được một bộ nhớ liên kết trang tôi sử dụng một chức năng valloc.Làm thế nào để cấp phát bộ nhớ với quyền thực thi?

void * temp = (void *) valloc(x); 

và sau đó

if(mprotect(temp, BLOCK_SIZE, (PROT_READ | PROT_WRITE |PROT_EXEC))) { 
    exit(-1); 
} 

Bây giờ tôi muốn thêm bộ nhớ hơn để khối phân bổ này. Do đó tôi sử dụng hàm realloc.

void * new_temp = (void *) realloc(temp, 1024); 

Tính năng này có thể tự động thay đổi quyền của bộ nhớ được cấp cho những bộ nhớ tôi đã đặt trước đó không ?? Trong trường hợp realloc di chuyển toàn bộ khối đến một vị trí khác, quyền của bộ nhớ được phân bổ trước đó và bộ nhớ được cấp phát mới là gì?

Nên sử dụng lại mprotect để nhận bộ nhớ quyền thực thi. Và có API đến realloc trên ranh giới kích thước trang như valloc. ?

+2

Bạn nên gắn thẻ thẻ này với hệ điều hành thích hợp vì đây là hệ điều hành nhiều hơn so với câu hỏi ngôn ngữ. –

+0

valloc() là một hàm BSD cũ được loại bỏ trong SUSv3. Giả sử một số hệ điều hành POSIX như Linux hoặc BSD. – Dummy00001

+0

@ David: Không thực sự, công cụ này được hỗ trợ bởi cả Windoze và Linux (hệ điều hành khác không tồn tại), và API chỉ khác nhau ở nơi POSIX không được tiêu chuẩn hóa. –

Trả lời

4

Hãy thử phân bổ một khu vực mới với valloc và sao chép nội dung cũ khác. Tốt hơn, hãy ngừng sử dụng số điện thoại không được chấp nhận valloc và thay thế bằng các cuộc gọi posix_memalign hoặc trực tiếp mmap để phân bổ rất lớn. Sử dụng mremap bạn có thể hiệu quả realloc các vùng bộ nhớ được liên kết trang.

1

Nên sử dụng lại chế độ bảo vệ để nhận bộ nhớ quyền thực thi.

Bộ nhớ ảo được sắp xếp trong các trang. mprotect() thay đổi cờ trên tất cả các trang trong khối bộ nhớ ảo đã cho. Nó độc lập với việc cấp phát bộ nhớ thực. IOW, bạn phải gọi mprotect() một lần nữa sau khi realloc để áp dụng lại các điều khoản. Và bạn phải gọi lại cho toàn bộ khu vực, vì realloc() có thể thay vì mở rộng con trỏ trả về khối hiện tại thành một điểm mới.

Nghĩ về nó ngay bây giờ, tôi nghĩ người ta có thể cần gọi mprotect() trước realloc() để xóa quyền thực thi khỏi vùng bộ nhớ cũ. malloc()/realloc() là các hàm libc để quản lý bộ nhớ bên trong bộ nhớ ảo của ứng dụng, trong khi mprotect() là một syscall hoạt động độc lập trên chính bộ nhớ ảo của ứng dụng.

Và có API để phân bổ lại trên ranh giới kích thước trang như valloc hay không. ?

Rất nghi ngờ điều đó.

Trong ứng dụng chuyên sâu cấp phát bộ nhớ, realloc() hiếm khi có khả năng mở rộng khối hiện có và thường kết thúc phân bổ khối mới + memcpy() + khối cũ miễn phí. Nếu hiệu suất realloc() được chấp nhận trước đó, so với phiên bản được mã hóa bằng tay (liên kết chặt chẽ hơn vào tài khoản) cũng sẽ ổn.

BTW, POSIXv6 có chức năng mới được gọi là posix_memalign(). valloc's man page là một điều thú vị, chủ yếu là tại sao người ta không nên sử dụng valloc() ngay từ đầu.

P.S. Ngoài ra, bạn luôn có thể sử dụng chức năng POSIX tiêu chuẩn để tìm kích thước trang sysconf(_SC_PAGESIZE); và sắp xếp bộ nhớ đệm cho chính bạn. Rõ ràng bạn phải phân bổ new_size+(sysconf(_SC_PAGESIZE)-1) byte để có đủ bộ nhớ để căn chỉnh lại con trỏ.

+0

Bạn chắc chắn không muốn loại bỏ quyền EXEC cho một trang chỉ vì * một * bộ đệm trong trang đó không còn cần đến nó nữa. Trừ khi bạn chỉ có một bộ đệm thực thi được cấp phát động, vì vậy bạn biết rằng không có bộ đệm thực thi nào khác trong cùng một trang. –

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