정현진Jeong Hyeonjin

정현진 — 보안 포트폴리오

Research / 시스템 / sudo 소스 코드 구조 읽기: 디렉터리 구성과 주요 함수

sudo 소스 코드 구조 읽기: 디렉터리 구성과 주요 함수

유형
연구 기록
분류
시스템
발행
2026. 1. 16.
분량
2분
종류
연구 기록

sudo 프로젝트를 시작하면서 소스 디렉터리가 어떻게 나뉘는지, 헤더와 실행 흐름의 주요 함수가 무슨 일을 하는지 정리했습니다.

sudo 취약점을 찾는 팀 프로젝트를 시작하면서, 코드가 어디에 무엇이 있는지부터 정리한 노트입니다.

디렉터리 구성

디렉터리 내용
include 공용 헤더 (구조체, 매크로, 함수 선언)
lib 내부 공통 라이브러리 (문자열, 유틸 등)
plugins 정책(sudoers), 감사, 승인 같은 플러그인
src sudo 핵심 실행 코드 (sudo, sudoedit, exec, pty 처리)
logsrvd 중앙 로그 서버
docs, examples, etc 문서, 예제, 기본 설정 샘플
docker, .github, .circleci, scripts, m4, po 빌드·테스트·CI, 다국어 번역

처음에는 include → src → plugins 순서로 읽었습니다.

헤더

파일 역할
include/sudo_util.h 자주 쓰는 상수·매크로와 유틸 함수 선언을 모은 헤더 (시간 계산 매크로, 비트맵 매크로, base64, 파일 잠금 등)
include/compat/stdbool.h bool이 없는 환경에서 C로 bool을 쓸 수 있게 해 줌
include/sudo_conf.h sudo.conf에서 플러그인·디버그·경로 설정을 읽어 오는 함수 선언
include/hostcheck.h OpenSSL이 있을 때 서버 인증서의 hostname/IP가 맞는지 검증

정리하면서 익힌 것들입니다.

  • #ifndef / #define / #endif: 헤더가 두 번 포함되지 않게 막는 전처리기 조건문
  • TAILQ_HEAD, TAILQ_ENTRY: BSD 계열에서 쓰는 연결 리스트 매크로. 플러그인 목록, 디버그 파일 목록 같은 리스트를 만듭니다.
  • X.509 인증서에는 소유자 이름, 발급자 이름, 유효기간, 공개키가 들어 있습니다.

실행 흐름에서 본 함수

main (src/sudo.c)

큰 흐름은 이렇습니다.

  1. 프로그램 이름 확인, 리소스 제한·파일 디스크립터 정리, 로케일 설정
  2. sudo.conf 읽기, 디버그 등록, setuid 상태 확인, 시그널 초기화
  3. 사용자 정보 수집 (get_user_info)
  4. 명령줄 인자 해석 (parse_args) → 실행 모드 결정
  5. 플러그인 로드 (sudo_load_plugins), 감사·정책 플러그인 열기
  6. 모드에 따라 분기: 버전 출력, 인증 갱신, 목록 출력, 또는 실행·편집
  7. 실행·편집이면 정책 검사(policy_check) → 승인 → I/O 로그 → 감사를 통과해야 run_command 또는 sudo_edit로 실행

정책 검사 단계 중 하나라도 실패하면 access_denied로 빠집니다.

그 밖에 정리한 함수

함수 하는 일
tgetpass() 터미널에서 비밀번호를 입력받아 문자열로 돌려줌. 터미널이 없으면 SUDO_ASKPASS에 설정된 askpass 헬퍼로 입력받음. 입력 중 시그널을 잡아 터미널 설정(에코 끄기)을 원래대로 돌려놓음
sudo_askpass_cred() askpass를 실행할 때 쓸 사용자 자격 정보를 저장하고 꺼내는 저장소 역할
sudo_execute() 상황에 맞게 실행 방식을 고름. 백그라운드면 fork, pty가 필요하면 exec_pty, 바로 실행할 수 있으면 exec_cmnd, 아니면 exec_nopty
add_preserved_fd() 명령을 실행할 때 닫지 않고 넘겨줄 파일 디스크립터를 정렬된 리스트에 추가
apparmor_is_enabled() /sys/module/apparmor/parameters/enabled를 읽어 AppArmor가 켜져 있는지 확인

정리

  • sudo는 실행 전에 정책·승인·로그·감사 단계를 모두 통과해야 명령을 실행하는 구조입니다.
  • 정책 판단은 대부분 plugins(sudoers 플러그인)에 있고, src는 그 결과를 받아 실제 실행을 담당합니다.
  • 이 정리를 바탕으로 이후 팀에서 입력이 들어오는 순서대로 코드를 읽는 방식으로 분석을 이어갔습니다.

0 백링크1 링크3 태그