2009-11-08 10 views
9

Tôi đã triển khai một số loại thiết bị ký tự và tôi cần trợ giúp với hàm copy_ from_user.Nhân Linux: copy_from_user - struct với con trỏ

Tôi đã một cấu trúc:

struct my_struct{ 

int a; 

int *b; 
}; 

tôi khởi tạo nó trong không gian người dùng và vượt qua con trỏ đến my_struct vào thiết bị char của tôi sử dụng chức năng 'ghi'. Trong chức năng 'write' của thiết bị nhân vật Space của Kernel, tôi cast nó từ một char * cho loại cấu trúc này. Tôi phân bổ một số bộ nhớ cho một cấu trúc bằng cách sử dụng kmalloc và làm copy_from_user vào nó.

Nó là tốt cho đơn giản 'int a', nhưng nó chỉ sao chép con trỏ (địa chỉ) của giá trị b, không phải giá trị được chỉ bởi b, vì vậy tôi bây giờ trong Kernel Space và tôi đang làm việc với một con trỏ trỏ đến bộ nhớ không gian người dùng. Đây có phải là không chính xác và tôi không nên truy cập trực tiếp vào con trỏ không gian người dùng và tôi phải copy_from_user mỗi con trỏ trong cấu trúc của tôi và sau đó sao chép mọi con trỏ trong hàm "đọc" bằng hàm copy_to_user?

Trả lời

6

Bạn đúng trong phỏng đoán của mình. Nếu bạn cần truy cập vào giá trị *b, bạn sẽ cần phải sử dụng copy_from_user (và copy_to_user để cập nhật lại trong quy trình người dùng).

+2

Tôi cũng chỉ ra rằng tôi không thể nghĩ ra bất kỳ syscalls hoặc ioctls mà có structs với con trỏ trong đó. Ngay cả những người có chuỗi sẽ có một mảng ký tự trong cấu trúc thay thế. Thực tế là nó rất khó chịu để viết mã để làm điều này cho mỗi thành viên con trỏ có thể có một cái gì đó để làm với điều đó. :-) – asveikau

+0

@asveikau: 'readv()' và 'writev()'? – caf

13

Bạn phải luôn sử dụng copy_from_user và tương tự như bộ nhớ không gian người dùng truy cập từ không gian hạt nhân, bất kể bạn có con trỏ như thế nào. Vì b là con trỏ đến bộ nhớ không gian của người dùng, bạn phải sử dụng copy_from_user để truy cập bộ nhớ.

Các chức năng này thực hiện hai nhiệm vụ bổ sung quan trọng:

  1. Họ chắc chắn điểm con trỏ vào không gian sử dụng và không hạt nhân không gian. Nếu không có kiểm tra này, các chương trình không gian người dùng có thể đọc hoặc ghi vào bộ nhớ hạt nhân, bỏ qua bảo mật thông thường.
  2. Chúng xử lý chính xác lỗi trang. Thông thường, lỗi trang trong chế độ hạt nhân sẽ dẫn đến OOPS hoặc hoảng loạn - họ có chức năng ghi đè đặc biệt cho bộ xử lý PF, và lỗi phải được xử lý bình thường; và trong trường hợp lỗi không thể được IO thỏa mãn (tức là, thông thường sẽ gây ra SIGSEGV hoặc SIGBUS), hãy trả về mã lỗi để người gọi có thể thực hiện bất kỳ dọn dẹp cần thiết nào trước khi trở về không gian người dùng với -EFAULT.