LD_PRELOAD 설명
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
DevOps
대상자
- 시스템 관리자 및 개발자에게 유용
- 중간 난이도: Unix/Linux 환경 이해와 동적 링커(Dynamic Linker) 개념 필요
핵심 요약
LD_PRELOAD
는 동적으로 링크된 프로그램 실행 시 사전 로딩되는 공유 라이브러리를 지정하여 기존 함수를 오버라이딩하거나 커스텀 코드를 주입할 수 있는 환경 변수이다.- 정적 링크된 이진 파일은
LD_PRELOAD
기능을 완전히 무시한다. - 보안 위험이 있으며, 시스템 호출(
open
,execve
)을 조작해 악성 행위를 숨길 수 있다.
섹션별 세부 요약
1. 동적 링커(Dynamic Linker) 개요
- 동적 링커는 프로그램 실행 시 공유 라이브러리 로딩과 실행 시작을 담당한다.
- Linux의 경우
/lib64/ld-linux-x86-64.so.2
, FreeBSD의 경우/libexec/ld-elf.so.1
등으로 구현된다. - 동적 링커 실행 실패 시 전체 프로그램 실행이 중단된다.
2. `LD_PRELOAD` 작동 방식
- 동적 링커가 프로그램 이미지 로딩 후, 공유 객체 의존성 로딩 전에 지정된 라이브러리를 로딩한다.
- 함수 오버라이딩은
dlsym(RTLD_NEXT, "함수명")
을 사용해 원본 함수를 찾고, 오버라이딩된 함수로 대체한다.
3. 예제: `malloc` 오버라이딩
malloc
함수를 오버라이딩해 할당 횟수를 카운팅하는 예제에서dlsym
을 통해 실제malloc
함수를 호출하고, 카운터를 증가시킨다.- 재귀 호출 주의:
malloc
내부에서malloc
을 직접 호출할 경우 스택 오버플로우가 발생할 수 있다.
4. 예제: `read`/`write` 함수에 지연 추가
read
/write
함수를 오버라이딩해 200ms 지연을 추가하는 예제에서__attribute__((constructor))
를 통해 라이브러리 로딩 시 초기화 함수를 실행한다.- 실제
read
/write
함수는dlsym
을 통해 로딩되며, 한 번만 초기화된다.
5. `LD_PRELOAD` 사용 방법
- 환경 변수 설정:
LD_PRELOAD=./my_library.so
로 설정하여 실행 시 적용. - 명령행 옵션:
--preload
플래그를 사용해 동적 링커 직접 실행 시 적용. - 시스템 설정 파일:
/etc/ld.so.preload
에 등록하면 모든 프로세스에 자동 적용됨.
6. 보안 고려사항
LD_PRELOAD
는 시스템 호출 오버라이딩이 가능해 보안 취약점이 될 수 있다.- Linux는 보안 실행 모드(set-user-ID 프로그램)에서
LD_PRELOAD
사용을 제한하며, 경로에 슬래시 포함 시 무시한다. - FreeBSD는 set-user-ID 프로그램에서
LD_PRELOAD
을 완전히 무시한다.
결론
LD_PRELOAD
는 디버깅, 성능 모니터링, 핫픽스 적용 등에 유용하지만, 보안 위험이 있으므로 신중하게 사용해야 한다.- 예제를 통해
malloc
/read
함수 오버라이딩을 구현할 수 있으며, 공유 라이브러리 생성(gcc -shared)과 환경 변수 설정을 통해 즉시 적용 가능하다.