시스템 호출
100%

Kernel · 레슨 3

시스템 호출

사용자 공간 코드가 리눅스 커널 서비스를 호출하는 방법과 `strace`로 호출을 안전하게 검사하는 방법을 알아봅니다.

시스템 호출은 사용자 공간 코드가 파일 열기, 메모리 매핑, 프로세스 생성 또는 네트워크 데이터 전송 같은 작업을 요청하는 정의된 커널 진입점입니다. 커널은 요청을 수행하기 전에 인수, 자격 증명, 객체 상태 및 보안 정책을 검증합니다.

라이브러리와 시스템 호출 ABI

애플리케이션은 아키텍처별 진입 명령어를 직접 작성하는 대신 일반적으로 C 라이브러리 함수를 호출합니다. 라이브러리 래퍼는 시스템 호출 ABI에 따라 레지스터와 메모리를 준비하고 커널에 진입한 뒤 결과를 해당 언어의 규칙에 맞게 변환합니다.

함수와 시스템 호출이 항상 일대일 관계인 것은 아닙니다.

  • 라이브러리 함수 하나가 여러 시스템 호출을 결합할 수 있음
  • 일부 함수는 완전히 사용자 공간에서 동작
  • 최적화된 vDSO 함수는 전체 모드 전환 없이 커널이 유지하는 일부 데이터를 가져올 수 있음
  • 시스템 호출 하나가 여러 상위 수준 API를 지원할 수 있음

일반적인 libc 시스템 호출 래퍼는 무엇을 합니까?

커널 진입과 반환

래퍼는 아키텍처에서 정의한 위치에 시스템 호출 번호와 인수를 배치한 다음 x86-64의 syscall 또는 AArch64의 svc 같은 진입 명령어를 실행합니다. 프로세서는 설정된 특권 진입점으로 전환하고 커널이 요청을 전달합니다.

작업을 마치면 커널은 값이나 오류 표시를 반환합니다. C 라이브러리 래퍼는 일반적으로 오류 시 -1을 반환하고 스레드 로컬 errno를 설정합니다. 다른 언어와 런타임은 서로 다른 오류 유형으로 노출합니다.

현재 아키텍처의 모든 진입을 “소프트웨어 인터럽트”라고 부르는 것은 정확하지 않습니다. 트랩, 고속 시스템 호출 명령어 및 감독자 호출은 서로 다른 방식으로 관련된 제어 전환을 구현합니다.

시스템 호출의 인수와 권한을 검증하는 것은 누구입니까?

번호와 호환성

시스템 호출 번호와 호출 규칙은 아키텍처별로 다릅니다. 같은 기호 호출도 다른 ABI에서는 번호나 구조 레이아웃이 다를 수 있습니다. 커널 릴리스는 새 시스템 호출을 추가할 수 있지만 안정적인 사용자 공간 ABI는 기존 동작을 보존하려고 합니다.

비특권 프로세스는 실행 중인 커널의 syscall 테이블에 임의의 새 핸들러를 삽입할 수 없습니다. 인터페이스 확장에는 커널 코드와 신중한 ABI 설계가 필요합니다. seccomp 같은 기능은 프로세스가 수행할 수 있는 호출을 필터링하지만 새 커널 구현을 만들지는 않습니다.

애플리케이션이 다른 아키텍처의 syscall 번호를 하드 코딩해서는 안 되는 이유는 무엇입니까?

`strace`로 추적하기

간단한 명령을 추적하고 출력을 별도 파일에 저장합니다.

$ strace -o trace.log -- ls

권한이 있는 경우 -f로 자식 프로세스를 따라가거나 다음과 같은 표현식으로 출력 범위를 좁힙니다.

$ strace -f -e trace=%file -o trace.log -- command

strace에는 경로, 인수, 환경에서 파생된 데이터, 네트워크 주소, 파일 내용 일부 및 인수로 잘못 전달된 자격 증명이 나타날 수 있습니다. 추적 파일을 제한적인 권한으로 저장하고 사고 데이터 정책에 따라 제거하십시오.

strace가 주로 관찰하는 것은 무엇입니까?

추적을 신중하게 해석하기

추적은 타이밍을 바꾸고 상당한 오버헤드를 만들 수 있습니다. 실패한 호출이 예상된 탐색일 수 있고, 최종적으로 보이는 오류는 더 이른 작업이나 애플리케이션 정책에서 비롯될 수 있습니다. 파일 디스크립터를 해석하고 프로세스 관계를 따라가며 애플리케이션 로그와 연결하십시오.

권한과 ptrace 보안 정책은 추적할 수 있는 프로세스를 제한합니다. 승인 없이 다른 사용자나 운영 프로세스에 연결하지 마십시오. 정지와 타이밍 변화가 서비스 동작에 영향을 줄 수 있습니다.

추적에서 시스템 호출 하나가 실패하면 애플리케이션이 반드시 고장 났다는 뜻입니까?

레슨 완료

시스템 호출 완료

이제 라이브러리 API에서 검증된 커널 작업까지 시스템 호출을 추적할 수 있습니다.

  • 상위 수준 함수와 시스템 호출 ABI를 구분합니다.

  • 아키텍처 진입 명령어를 제어된 커널 전달과 연결합니다.

  • syscall 번호와 구조를 아키텍처별 요소로 취급합니다.

  • 민감한 데이터를 보호하면서 필터링된 strace 출력을 사용합니다.

  • 오류와 추적 오버헤드를 애플리케이션 맥락에서 해석합니다.

학습 진행 상황 저장

무료 계정을 만들어 이 레슨을 저장하고 어떤 기기에서든 계속 학습하세요.

무료 계정 만들기
다음 수업
Kernel(으)로 돌아가기