2009-11-08 8 views
9

나는 어떤 종류의 문자 장치를 구현했으며 copy_ from_user 함수에 대한 도움이 필요하다. 나는 사용자 공간에서 초기화와 '쓰기'기능을 사용하여 내 문자 장치에 my_struct하는 포인터를 전달리눅스 커널 : copy_from_user - 포인터로 구조체

struct my_struct{ 

int a; 

int *b; 
}; 

:

나는 구조를했습니다. 커널의 공간 문자 장치 '쓰기'기능에서 나는이 문자를 * char로부터 이런 종류의 구조로 캐스팅합니다. 내가 kmalloc을 사용하여 구조체에 대한 일부 메모리를 할당하고 그것에 copy_from_user 마십시오.

단순한 'int a'는 괜찮지 만 b가 가리키는 값이 아닌 b 값의 포인터 (주소) 만 복사하므로 커널 공간에 있고 포인터를 가리키는 포인터로 작업하고 있습니다. 사용자 공간 메모리. 이 잘못된이며 사용자 공간 포인터를 직접 액세스해야합니다 및 내 구조체에있는 모든 단일 포인터 copy_from_user 다음 "read"함수 copy_to_user 함수를 사용하여 모든 포인터를 다시 복사해야합니까?

답변

6

당신의 추측에 정확합니다. *b 값에 액세스해야하는 경우 사용자 프로세스에서 다시 업데이트하려면 copy_from_user (및 copy_to_user)을 사용해야합니다.

+2

또한 포인터가있는 구조체를 사용하는 syscalls 또는 ioctls를 생각할 수 없다는 것을 지적합니다. 문자열이있는 경우에도 구조체에 char 배열이 대신 있습니다. 모든 포인터 멤버에 대해이 작업을 수행하는 코드를 작성하는 것이 매우 귀찮습니다. :-) – asveikau

+0

@asveikau :'readv()'와'writev()'? – caf

13

포인터를 가져온 방법에 관계없이 커널 공간에서 사용자 공간 메모리에 액세스하려면 항상 copy_from_user 및 그와 비슷한 것을 사용해야합니다. b은 사용자 공간 메모리에 대한 포인터이기 때문에 액세스하려면 copy_from_user을 사용해야합니다. 그들은 사용자 공간에 있는지 포인터 점을과 공간을 커널하지

  1. :

    이 기능은 두 가지 중요한 추가 작업을한다. 이 검사가 없으면 사용자 공간 프로그램이 정상적인 보안을 우회하여 커널 메모리를 읽거나 쓸 수 있습니다.

  2. 페이지 폴트를 올바르게 처리합니다. 일반적으로 커널 모드의 페이지 오류로 인해 OOPS 또는 패닉이 발생합니다. copy_*_user 패밀리의 함수 패밀리는 PF 처리기에 모두 정상이며 오류를 정상적으로 처리해야한다고 알려주는 특수 대체 기능을가집니다. IO가 오류를 만족할 수없는 경우 (즉, 보통 SIGSEGV 또는 SIGBUS) 오류 코드를 반환하여 -EFAULT으로 사용자 공간으로 돌아 가기 전에 호출자가 필요한 정리 작업을 수행 할 수 있도록합니다.