커널 실행에서 지원되는 시스템 호출


9

현재 실행중인 Linux Kernel에서 지원하는 시스템 호출 수 또는 목록을 얻는 방법이 있습니까? 따라서 실행중인 커널의 syscall 테이블을 '읽는'방법을 찾고 싶습니다.

답변:


15

이 파일 /proc/kallsyms은 실행중인 커널의 모든 기호를 나열합니다. 관례 적으로 시스템 호출의 이름은로 시작합니다 sys_. 64 비트 시스템에서 32 비트 프로그램에 대한 시스템 호출의 이름은로 시작합니다 sys32_. 엄밀히 말하면, 이것은 시스템 호출이 아닌 내부 커널 함수를 나열하지만, ​​통신이 작동한다고 생각합니다 (모든 시스템 호출은 작업을 수행하기 위해 내부 커널 함수를 호출하며 이름은 항상 sys_앞에 붙은 시스템 호출의 이름이라고 생각합니다 ).

</proc/kallsyms sed -n 's/.* sys_//p'

시스템 호출은 매우 느리게 변경되므로 일반적으로 유용한 정보는 아닙니다. 선택적 구성 요소 (와 같은 장치로 일반적인 기능을 사용하여, 기존의 시스템 콜의 측면에서 기능을 제공 IOCTLread 하고 write당신에게 기능에 대해 아무것도 말하지 않을 것이다 지원 시스템 콜의 목록을 결정, 파일 시스템, 소켓 등을 잘라하지 않습니다) 시스템이 지원하는 다른 내부 함수 이름은 매우 빠르게 변경되기 때문에 도움이되지 않습니다. 한 커널 버전에서 일부 기능을 구현하는 함수 이름은 다음 버전에서 변경 될 수 있습니다.


+1. "내가 당신보다 더 많은 경험을 가진 사람에게 대답하도록하겠습니다" 라고 말했을 때의 의미 입니다. 또한 /proc/kallsyms다른 파일과 같이 조작 할 수 있으므로 프로그램에서 사용하기가 훨씬 쉬워집니다.
John WH Smith

2
@JohnWHSmith“다른 파일처럼 조작 할 수 있습니다”… 커널 ASLR 시스템에서는이 파일을 루트 만 읽을 수 있다는주의 사항이 있습니다.
Gilles 'SO- 악마 그만해

7

TL; DR

나는이 답변을 쓸 때 새로운 대안을 계속 찾았으므로 각 질문에 대해 약간의 세부 사항을 작성하고 통계를 작성했습니다. 기본적으로 다음 중 하나를 수행 할 수 있습니다.

  • 깨끗하고 빠른 방법을 제공하는 Gilles의 답변을 읽으십시오 (에 의존 /proc).
  • 설명서 리소스를 사용하십시오.
  • 시스템의 C 헤더 파일을 사용하십시오.
  • 커널 소스 코드 자체를 사용하십시오.
  • /sys디렉토리를 사용하십시오 .

수학을 한 후에 /sys파일 시스템을 사용하는 것이 좋습니다 . 시스템 호출 수 측면에서 최상의 결과를 제공하는 것 같습니다. 다른 트릭에 대해 읽고 싶지 않다면 해당 섹션으로 바로 이동할 수 있습니다.

설명서 리소스 사용

그 중 일부를 놓칠 수도 있지만 apropos섹션 2 (시스템 호출)에 속하는 모든 맨 페이지를 나열 하는 데 사용할 수 있습니다 .

$ apropos -s2 . | awk '{print $1}' | column

column멋진 열 출력을 원하지 않으면 제거하십시오 .

방금 찾았지만 시스템 호출에 대한 Linux 매뉴얼 페이지가 있으며 대부분의 시스템 호출을 찾을 수 있습니다.

$ man syscalls

나는 또한 흥미로운 두 웹 사이트를 발견했다.

헤더 파일 사용

편집 : 사용 가능한 시스템 호출을 결정하는 프로그래밍 방식으로 (또는 적어도 문서화 된 기능에 의존하지 않고) 커널이 시스템 호출 테이블을 최소한의 형태로 유지하지 않을까 걱정됩니다. 문자열 목록 (아마도 문자열을 조작 할 것으로 예상 됨). 이 수준에서는 함수 이름이 아닌 함수 주소와 포인터에 대해 더 많이 이야기하고 있습니다.

방금 내 /usr/include디렉토리를 탐색 grep하고 몇 가지 사항을 탐색했습니다 . 다음 디렉토리가 흥미로울 수 있습니다. 아키텍처와 배포판에 따라 일부 컴퓨터에서 다를 수 있지만 조정할 수있을 것입니다.

  • / usr / include / linux
  • / usr / include / x86_64-linux-gnu
  • / usr / include / sys
  • / usr / include / asm-generic

이 파일에서 함수 정의를 찾아 보면 시스템 정의가 완전히 정의되지 않았더라도 많은 시스템 호출을 보게됩니다. grep이 디렉토리에서 몇 가지를 실행했으며 일부 시스템 호출에 대한 언급을 찾을 수있었습니다. 예를 들면 다음과 같습니다.

$ grep 'sys_exit' /usr/include -R
asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)

그래서, 나는 그들 중 일부를 찾는 다른 방법을 추측하고 있습니다 :

$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')'

커널의 소스 코드와 syscall 테이블 사용

또 다른 해결책은 커널 소스 코드 자체 (헤더뿐만 아니라)를 사용하고 효율적으로 검색하는 방법을 찾는 것입니다. 커널 커밋 303395ac3bf3e2cb488435537d416bc840438fcb이므로 이전보다 조금 더 쉽습니다. 다음은 3.13 (내 커널)의 예입니다.

$ wget https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/plain/arch/x86/syscalls/syscall_64.tbl?id=refs/tags/v3.13 -O syscall_64.tbl

이제 실제 syscalls 테이블을 얻었으므로 찾아보십시오.

$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl

당신은 사용 방법을 찾을 수 unamearch다운로드하기 tbl에서 파일 바로 git.kernel.org 실행중인 커널 버전 및 아키텍처에 기반을.

/sys파일 시스템 사용

Gilles의 대답은 나에게 약간의 영감을 주었고, 당신은 그 시스템 호출을 내부에서 찾을 수 있습니다 /sys/kernel/debug/tracing/events/syscalls. 이 디렉토리는 시스템에서 각 시스템 호출의 사용을 모니터하는 데 사용됩니다. 각 syscall에는 두 개의 디렉토리가 있습니다.

  • sys_enter_ [syscall]
  • sys_exit_ [syscall]

따라서, 사용 ls, grepcut...

$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3

통계

내 시스템에서 :

  • 매뉴얼 페이지를 사용하여 440 개의 시스템 호출이 나타났습니다.
  • grep대한 -ing __SYSCALL헤더 파일의 212 시스템 호출을 밝혔다.
  • 커널 소스에서 syscalls 테이블을 읽으면 346 개의 시스템 호출이 나타났습니다.
  • /sys공개 된 290 시스템 호출을 사용 합니다.

이제 모든 것을한데 모으면 ...

$ apropos -s2 . | awk '{print $1}' > system_calls.txt
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')' >> system_calls.txt
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl >> system_calls.txt
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3 >> system_calls.txt

$ sort < system_calls.txt | uniq | wc -l
707

707 개의 시스템 호출이 있습니다! 물론이 숫자는 3.13은 274 개의 시스템 호출 만 제공하기 때문에 "시스템 호출"의 매우 유연한 정의를 반영합니다 (읽기 /sys는 가장 가까운 솔루션 인 것 같습니다).


매뉴얼 페이지에 어떤 시스템 호출이 문서화되어 있는지를 찾는 것이 아니라 어떤 방식으로 시스템 호출 테이블을 '읽는'관점에서 더 많은 방법을 찾고 있습니다.
Swair

커널이 적어도 문자열 목록이 아닌 syscall 목록을 유지한다고 생각하지 않습니다. 내 답변을 편집했습니다. 이 작업을 수행 할 수있는 실제적인 방법이 경우에, 나는 내가 당신을 대답보다 더 많은 경험을 가진 사람을 드리겠습니다)
존 WH 스미스

그래서 커널에 시스템 호출을 추가하고 사용하려고했을 때 "기능이 구현되지 않았습니다"라는 문제가 있었으며 현재 커널에 대한 syscall 테이블을 얻는 방법이 있는지 궁금했습니다. '#make install'을 수행 할 때 grub을 업데이트하고 새 커널을 시작하면 새 커널이 어떤 단계에서 새 시스템 호출이 포함 된 포함 파일을 가져 옵니까?
Swair

1
시스템 호출을 찾을 수 없으면 제대로 구현하지 않은 것입니다. 내 대답은 Linux의 시스템 호출을 찾는 방법을 알려주지 만 직접 디버깅하는 방법은 아닙니다 (원하는 것이 아니기 때문에). 개발에 문제가있는 경우 특별히 질문을 하고 XY 문제를 피해야 합니다 .
John WH Smith

@swair 시스템 호출을 추가하여 기능을 추가하는 것은 매우 드문 일입니다. 우리는 코드를 제공하지 않았기 때문에 무엇이 잘못되었는지 확실하게 알 수 없습니다 (질문에 C 코드가 필요한 경우 여기서는 주제가 맞지 않지만 집에서는 스택 오버플로 ). 시스템 호출을 (정확하게 또는 그렇지 않은) 구현했으며 C 프로그램에서 시스템 호출을 사용하려고 시도했으며 시스템 호출을 수행하는 C 함수 작성 단계가 누락되었다고 생각합니다. 시스템 호출은 일반적인 함수 호출이 아닙니다.
Gilles 'SO- 악한 중지

1

모든 대답은 괜찮습니다.

특정 시스템 호출 이름을 찾고있는 경우 :

$ cat /proc/kallsyms | grep <sys_call_name>

모든 시스템 호출 목록을 찾고있는 경우 :

$ cat /proc/kallsyms
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.