2010-12-23 4 views
45

누군가가 리눅스 커널 소스에 사용 된 __user 매크로의 뉘앙스를 설명 할 수 있기를 바랍니다. 모든linux __user 매크로의 의미는 무엇입니까?

첫째, 매크로 :

이제
# define __user   __attribute__((noderef, address_space(1))) 

, 나는이 매크로가 하나가 사용자 주소 공간에 속하는 것으로 포인터를 지정할 수 있습니다, 그것은 역 참조되어서는 안된다는 것을 읽을 일부 인터넷 검색 후.

몇 가지 명백한 사실이 누락되었지만 누군가 이러한 매크로의 의미를 설명 할 수 있습니까? 예를 들어,이 매크로를 사용할 수있는 좋은 예는 무엇입니까? 다시 한 번, 뭔가 분명하지 않은 것이 있으면 용서해주십시오.

어떤 맥락에서이 글을 쓰려면 USB 코드 (linux/usbdevice_fs.h)를 검사하면서 매크로를 보았습니다. 나는 커널 내에서 사용되는이 매크로 (또는 비슷한 커널)에 대한 전반적인 이해만을 찾고있다.

감사합니다.

+2

좋은 예를 보려면 do_execve() 소스를 참조하십시오. count()에서 argv가 어떻게 사용되는지보십시오. (* argv [0])을 참조 해제하기 만하면 스파 스 (1)가 경고를 표시합니다. address_space는 모든 포인터가 동일하지 않으며 다른 (참조 해제) 규칙을 필요로하므로 혼합해서는 안됩니다. – adobriyan

답변

33

sparse과 같은 도구는 커널 개발자에게 신뢰할 수없는 포인터 (또는 현재의 가상 주소 매핑에서 유효하지 않은 포인터)를 잘못 사용하고 있다고 알릴 수 있습니다.

+0

그래서'__attribute __()'는 임의의 텍스트를 "속성"으로 사용할 수 있습니까? GCC 자체에 의미가있는 고정 세트에만 국한되지 않습니까? –

+0

@AlexD [GCC 속성 구문 매뉴얼] (https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html)에서 :'속성 지정자는 __attribute__ ((attribute-list)) 형식입니다. 속성 목록은 쉼표로 구분 된 속성 순서 일 수 있습니다. 각 속성은 다음 중 하나입니다. 1. 비어 있음. 빈 속성은 무시됩니다. ** 2. 속성 명 (사용되지 않는 식별자, 또는 const 등의 예약어 일 가능성이있다). ** (...)'. 그것은 당신이 원하는 식별자 (식별자 명명 규칙을 사용하여)가 될 수있는 것 같습니다. –

27

저는 __user가 사용자 공간 포인터를 표시하고 개발자/시스템에이를 신뢰하지 않는다고 말합니다. 사용자가 "유효하지 않은"포인터를 주면 커널은 그것을 참조하려고합니다 (커널이 어디에서나 참조 할 수 있음에 유의하십시오). 그러면 자신의 공간이 손상 될 수 있습니다.

예를 들어 "read"(usbdevice_fs.h에서)는 결과를 기록 할 (__user) 버퍼를 제공해야합니다. 그래서 당신은 copy_to_user를 사용해야 만합니다. 그러나 memcopy, strcpy 또는 이것과 비슷한 것은 아닙니다.

참고 : 이것은 공식적인 정의/설명이 아니지만 내가 아는 유일한 부분입니다.

+2

댓글을 기다리는 중, 왜 내 대답은 downvoted입니다. –

+2

롤 ... 사람들은 여기에 downnvoting 사랑 – Junaid

+0

그래, 그 copy_to_user 의미가 보자 – David

2

__user 매크로는 compiler.h 헤더 파일에 __force/__kernel 등의 다른 매크로로 정의됩니다. GCC/ICC 등을 포함한 전통적인 컴파일러에는 실제로 사용되지 않습니다. 그러나 스파 스 (더 자세한 정보는 스파 스 - Linux Kernel Newbies)와 같은 커널 정적 분석 도구에 유용합니다. __user/__kernel/__force 등의 매크로를 언급하면 ​​스파 스에 대해 특별한 의미를 지닙니다. 리눅스 커널 메일 링리스트에서 Linus Torvalds는 이것을 다음과 같이 설명합니다 :

gcc의 경우 스파 스 주석은 의미가 없습니다. 그들은 단지 프로그래머에게 "이봐, 그 포인터는 보통 포인터가 아니야"라고 꽤 쉽게 읽을 수 있다고 말하기에 유용 할 수 있습니다. 그러나 결국에는 스파 스를 사용하지 않으면 실제로는 않습니다. 무엇이든.

. 을 수행 할 때 구문 분석을 사용하면 완전히 다른 문제입니다. "__iomem"는 의미를 많이 가지고, "스파 스"가 들어 :

# define __iomem __attribute__((noderef, address_space(2))) 

즉 "iomem는"두 개의 가지를 의미합니다 : 그것은 포인터가 어느 역 참조하면 드문 드문는

불평한다는 것을 의미 (그것의는 " noderef "포인터)를 가지고 있고, 그것은 정상 주소 공간 (0)과 반대되는"주소 공간 2 "에 있습니다.이제

, 즉 같은 포인터 적 (일반 포인터를 원하는 함수에 전달되는 경우 스파 스 불평 것을 의미한다 "는 하지 정상적인 포인터, 당신은 분명 같은 일을 안하기 때문에 strcmp() "등), sparse는 다른 주소 공간의 다른 포인터로 캐스팅하려고하면 불평 할 것입니다.