rtld audit(7) - wariua/manpages-ko GitHub Wiki

NAME

rtld-audit - 동적 링컀 감사 API

SYNOPSIS

#define _GNU_SOURCE             /* feature_test_macros(7) μ°Έκ³  */
#include <link.h>

DESCRIPTION

GNU 동적 링컀(λŸ°νƒ€μž„ 링컀)μ—μ„œ 감사 APIλ₯Ό μ œκ³΅ν•˜λŠ”λ° 이λ₯Ό 톡해 λ‹€μ–‘ν•œ 동적 링크 이벀트 λ°œμƒ μ‹œμ— μ‘μš©μ—μ„œ μ•Œλ¦Όμ„ 받을 수 μžˆλ‹€. 이 APIλŠ” μ†”λΌλ¦¬μŠ€ λŸ°νƒ€μž„ λ§μ»€μ—μ„œ μ œκ³΅ν•˜λŠ” 감사 μΈν„°νŽ˜μ΄μŠ€μ™€ 맀우 λΉ„μŠ·ν•˜λ‹€. <link.h>λ₯Ό ν¬ν•¨μ‹œμΌœμ„œ ν•„μš”ν•œ μƒμˆ˜ 및 μ›ν˜•λ“€μ„ μ •μ˜ν•œλ‹€.

이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λ €λŠ” ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” ν‘œμ€€ μ΄λ¦„μ˜ ν•¨μˆ˜λ“€μ„ κ΅¬ν˜„ν•œ 곡유 라이브러리λ₯Ό λ§Œλ“€κ²Œ λœλ‹€. λͺ¨λ“  ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν•˜λŠ” 건 μ•„λ‹ˆλ‹€. λŒ€λΆ€λΆ„μ˜ 경우 νŠΉμ • 이벀트 감사 μœ ν˜•μ— λŒ€ν•΄ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ 관심이 μ—†μœΌλ©΄ λŒ€μ‘ν•˜λŠ” 감사 ν•¨μˆ˜ κ΅¬ν˜„μ„ μ œκ³΅ν•  ν•„μš”κ°€ μ—†λ‹€.

감사 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ ν™˜κ²½ λ³€μˆ˜ LD_AUDIT을 콀마둜 κ΅¬λΆ„λœ 곡유 라이브러리 λͺ©λ‘μ„ 담도둝 μ •μ˜ν•΄μ•Ό ν•œλ‹€. κ·Έ λΌμ΄λΈŒλŸ¬λ¦¬λ“€ κ°κ°μ—μ„œ 감사 API(의 일뢀)λ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€. 감사 λŒ€μƒ μ΄λ²€νŠΈκ°€ λ°œμƒν•˜λ©΄ 라이브러리 λ‚˜μ—΄ μˆœμ„œ λŒ€λ‘œ 각 라이브러리의 λŒ€μ‘ ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€.

la_version()

unsigned int la_version(unsigned int version);

감사 λΌμ΄λΈŒλŸ¬λ¦¬μ— κΌ­ μ •μ˜λΌ μžˆμ–΄μ•Ό ν•˜λŠ” μœ μΌν•œ ν•¨μˆ˜μ΄λ©° 동적 링컀와 감사 라이브러리 κ°„μ˜ 첫인사λ₯Ό μˆ˜ν–‰ν•œλ‹€. 동적 링컀가 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ λ§μ»€μ—μ„œ μ§€μ›ν•˜λŠ” κ°€μž₯ 높은 감사 μΈν„°νŽ˜μ΄μŠ€ 버전을 version으둜 μ „λ‹¬ν•œλ‹€. ν•„μš” μ‹œ 감사 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ 자기 μš”κ±΄μ— κ·Έ 버전이 μΆ©λΆ„ν•œμ§€ 확인할 수 μžˆλ‹€.

ν•¨μˆ˜ 결과둜 이 ν•¨μˆ˜λŠ” 이 감사 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ μ‚¬μš©μ„ κΈ°λŒ€ν•˜λŠ” 감사 μΈν„°νŽ˜μ΄μŠ€ 버전을 λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€. (version을 λ°˜ν™˜ν•˜λŠ” 것도 κ°€λŠ₯ν•˜λ‹€.) λ°˜ν™˜ 값이 0μ΄κ±°λ‚˜ 동적 링컀가 μ§€μ›ν•˜λŠ” 것보닀 큰 버전이면 κ·Έ 감사 라이브러리λ₯Ό λ¬΄μ‹œν•œλ‹€.

la_objsearch()

char *la_objsearch(const char *name, uintptr_t *cookie,
                   unsigned int flag);

동적 λ§μ»€μ—μ„œ 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄μ„œ 곡유 였브젝트 탐색을 ν•˜λ € ν•œλ‹€λŠ” κ±Έ 감사 λΌμ΄λΈŒλŸ¬λ¦¬μ—κ²Œ μ•Œλ¦°λ‹€. name μΈμžλŠ” 탐색할 파일λͺ…μ΄λ‚˜ 경둜λͺ…이닀. cookieλŠ” 탐색을 μœ λ°œν•œ 곡유 였브젝트λ₯Ό 식별할 수 있게 ν•΄ μ€€λ‹€. flagλŠ” λ‹€μŒ κ°’λ“€ 쀑 ν•˜λ‚˜λ‘œ 섀정돼 μžˆλ‹€.

LA_SER_ORIG
name이 νƒμƒ‰ν•˜λ €λŠ” μ›λž˜ 이름이닀. 보톡 ELF DT_NEEDED ν•­λͺ©μ—μ„œ 온 μ΄λ¦„μ΄κ±°λ‚˜ [[dlopen(3)]]의 filename μΈμžμ΄λ‹€.
LA_SER_LIBPATH
LD_LIBRARY_PATH에 μ§€μ •λœ 디렉터리λ₯Ό μ΄μš©ν•΄ name을 λ§Œλ“€μ—ˆλ‹€.
LA_SER_RUNPATH
ELF DT_RPATH λ‚΄μ§€ DT_RUNPATH λͺ©λ‘μ— μ§€μ •λœ 디렉터리λ₯Ό μ΄μš©ν•΄ name을 λ§Œλ“€μ—ˆλ‹€.
LA_SER_CONFIG
ldconfig(8) μΊμ‹œ(/etc/ld.so.cache)λ₯Ό 톡해 name을 μ°Ύμ•˜λ‹€.
LA_SER_DEFAULT
κΈ°λ³Έ 디렉터리듀 쀑 ν•˜λ‚˜λ₯Ό νƒμƒ‰ν•΄μ„œ name을 μ°Ύμ•˜λ‹€.
LA_SER_SECURE
name이 λ³΄μ•ˆ 였브젝트둜 ν•œμ •λΌ μžˆλ‹€. (λ¦¬λˆ…μŠ€μ—μ„œλŠ” μ“°μ§€ μ•ŠμŒ.)

ν•¨μˆ˜ 결과둜 la_objsearch()λŠ” 동적 링컀가 이후 μ²˜λ¦¬μ— μ‚¬μš©ν•΄μ•Ό ν•  경둜λͺ…을 λ°˜ν™˜ν•œλ‹€. NULL을 λ°˜ν™˜ν•˜λ©΄ 이 경둜λͺ…을 이후 μ²˜λ¦¬μ—μ„œ λ¬΄μ‹œν•œλ‹€. 감사 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ 탐색 경둜λ₯Ό κ°μ‹œλ§Œ ν•˜λ €λŠ” 거라면 name을 λ°˜ν™˜ν•˜λ©΄ λœλ‹€.

la_activity()

void la_activity(uintptr_t *cookie, unsigned int flag);

동적 링컀가 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄μ„œ 링크 λ§΅ λ™μž‘μ΄ μžˆμ–΄λ‚˜κ³  μžˆλ‹€λŠ” κ±Έ 감사 λΌμ΄λΈŒλŸ¬λ¦¬μ—κ²Œ μ•Œλ¦°λ‹€. cookieλŠ” 링크 맡의 머리에 μžˆλŠ” 였브젝트λ₯Ό 식별할 수 있게 ν•΄ μ€€λ‹€. 동적 링컀가 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ flagλ₯Ό λ‹€μŒ κ°’λ“€ 쀑 ν•˜λ‚˜λ‘œ μ„€μ •ν•œλ‹€.

LA_ACT_ADD
링크 맡에 μƒˆ μ˜€λΈŒμ νŠΈλ“€μ„ μΆ”κ°€ν•˜λ € ν•œλ‹€.
LA_ACT_DELETE
링크 λ§΅μ—μ„œ μ˜€λΈŒμ νŠΈλ“€μ„ μ œκ±°ν•˜λ € ν•œλ‹€.
LA_ACT_CONSISTENT
링크 λ§΅ λ™μž‘μ΄ 끝났닀. 맡이 λ‹€μ‹œ λͺ¨μˆœ μ—†λŠ” μƒνƒœμ΄λ‹€.

la_objopen()

unsigned int la_objopen(struct link_map *map, Lmid_t lmid,
                        uintptr_t *cookie);

μƒˆ 곡유 였브젝트λ₯Ό μ μž¬ν•  λ•Œ 동적 링컀가 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€. map μΈμžλŠ” κ·Έ 였브젝트λ₯Ό κΈ°μˆ ν•˜λŠ” 링크 λ§΅ ꡬ쑰체에 λŒ€ν•œ 포인터이닀. lmid μΈμžλŠ” λ‹€μŒ κ°’λ“€ 쀑 ν•˜λ‚˜μ΄λ‹€.

LM_ID_BASE
링크 맡이 졜초 λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— μ†ν•œλ‹€.
LM_ID_NEWLM
링크 맡이 dlmopen(3)을 톡해 μš”μ²­λœ μƒˆ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— μ†ν•œλ‹€.

cookieλŠ” 이 였브젝트의 μ‹λ³„μžμ— λŒ€ν•œ 포인터이닀. μ΄ν›„μ˜ 감사 라이브러리 ν•¨μˆ˜ ν˜ΈμΆœμ— 이 μ‹λ³„μžκ°€ μ œκ³΅λ˜λ―€λ‘œ 이 였브젝트λ₯Ό 식별할 수 μžˆλ‹€. 이 μ‹λ³„μžλŠ” 였브젝트의 링크 맡을 가리킀도둝 μ΄ˆκΈ°ν™” 돼 μžˆμ§€λ§Œ 감사 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ 였브젝트 식별에 μ“°κΈ° νŽΈν•œ λ‹€λ₯Έ μ–΄λ–€ κ°’μœΌλ‘œ λ°”κΏ€ 수 μžˆλ‹€.

λ°˜ν™˜ κ°’μœΌλ‘œ la_objopen()은 λ‹€μŒ μƒμˆ˜λ“€μ„ 0개 이상 OR ν•΄μ„œ λ§Œλ“  λΉ„νŠΈ 마슀크λ₯Ό λ°˜ν™˜ν•œλ‹€. κ·Έλž˜μ„œ 감사 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ la_symbind*()둜 κ°μ‹œν•  였브젝트λ₯Ό 선택할 수 μžˆλ‹€.

LA_FLG_BINDTO
이 였브젝트둜의 심볼 바인딩을 κ°μ‚¬ν•œλ‹€.
LA_FLG_BINDFROM
이 μ˜€λΈŒμ νŠΈλ‘œλΆ€ν„°μ˜ 심볼 바인딩을 κ°μ‚¬ν•œλ‹€.

la_objopen()의 λ°˜ν™˜ κ°’ 0은 이 μ˜€λΈŒμ νŠΈμ— λŒ€ν•΄ μ–΄λ–€ 심볼 바인딩도 κ°μ‚¬ν•˜μ§€ μ•Šμ„ κ²ƒμž„μ„ λ‚˜νƒ€λ‚Έλ‹€.

la_objclose()

unsinged int la_objclose(uintptr_t *cookie);

μ˜€λΈŒμ νŠΈμ— 마무리 μ½”λ“œκ°€ 있으면 μ‹€ν–‰ν•œ ν›„μ΄λ©΄μ„œ κ·Έ 였브젝트λ₯Ό λ‚΄λ¦¬κΈ°λŠ” 전에 동적 링컀가 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€. cookie μΈμžλŠ” μ•žμ„  la_objopen() ν˜ΈμΆœμ—μ„œ 얻은 μ‹λ³„μžμ΄λ‹€.

ν˜„μž¬ κ΅¬ν˜„μ—μ„œλŠ” la_objclose()κ°€ λ°˜ν™˜ν•˜λŠ” 값을 λ¬΄μ‹œν•œλ‹€.

la_preinit()

void la_preinit(uintptr_t *cookie);

λͺ¨λ“  곡유 μ˜€λΈŒμ νŠΈλ“€μ„ μ μž¬ν•œ ν›„μ΄λ©΄μ„œ μ‘μš©μœΌλ‘œ μ œμ–΄λ₯Ό λ„˜κΈ°κΈ°λŠ” 전에 (즉 main() 호좜 전에) 동적 링컀가 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€. 참고둜 이후 main()μ—μ„œλ„ dlopen(3)으둜 였브젝트λ₯Ό λ™μ μœΌλ‘œ μ μž¬ν•  수 μžˆλ‹€.

la_symbind*()

uintptr_t la_symbind32(Elf32_Sym *sym, unsigned int ndx,
                       uintptr_t *refcook, uintptr_t *defcook,
                       unsigned int *flags, const char *symname);
uintptr_t la_symbind64(Elf64_Sym *sym, unsigned int ndx,
                       uintptr_t *refcook, uintptr_t *defcook,
                       unsigned int *flags, const char *symname);

la_objopen()μ—μ„œ 감사 μ•Œλ¦Όμ„ λ°›κ²Œ ν‘œμ‹œν–ˆλ˜ 두 곡유 였브젝트 간에 심볼 바인딩이 μ΄λ€„μ§ˆ λ•Œ 동적 링컀가 이 ν•¨μˆ˜λ“€ 쀑 ν•˜λ‚˜λ₯Ό ν˜ΈμΆœν•œλ‹€. la_symbind32() ν•¨μˆ˜λŠ” 32λΉ„νŠΈ ν”Œλž«νΌμ—μ„œ μ“°λŠ” 것이고 la_symbind64() ν•¨μˆ˜λŠ” 64λΉ„νŠΈ ν”Œλž«νΌμ—μ„œ μ“°λŠ” 것이닀.

sym μΈμžλŠ” λ°”μΈλ“œ ν•˜λ €λŠ” 심볼에 λŒ€ν•œ 정보λ₯Ό μ œκ³΅ν•˜λŠ” ꡬ쑰체에 λŒ€ν•œ 포인터이닀. ꡬ쑰체 μ •μ˜λŠ” <elf.h>에 μžˆλ‹€. 이 ꡬ쑰체의 ν•„λ“œλ“€ 쀑에 st_value은 심볼이 λ°”μΈλ“œ λ˜λŠ” μ£Όμ†Œλ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

ndx μΈμžλŠ” λ°”μΈλ“œ λŒ€μƒ 곡유 였브젝트의 심볼 ν…Œμ΄λΈ”μ—μ„œ κ·Έ μ‹¬λ³Όμ˜ μΈλ±μŠ€μ΄λ‹€.

refcook μΈμžλŠ” 심볼 μ°Έμ‘°λ₯Ό ν•˜κ³  μžˆλŠ” 곡유 였브젝트λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. LA_FLG_BINDFROM을 λ°˜ν™˜ν•œ la_objopen() ν•¨μˆ˜μ— 제곡된 것과 같은 μ‹λ³„μžμ΄λ‹€. defcook μΈμžλŠ” μ°Έμ‘°λ˜λŠ” 심볼을 μ •μ˜ν•˜κ³  μžˆλŠ” 곡유 였브젝트λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. LA_FLG_BINDTOλ₯Ό λ°˜ν™˜ν•œ la_objopen() ν•¨μˆ˜μ— 제곡된 것과 같은 μ‹λ³„μžμ΄λ‹€.

symname μΈμžλŠ” 심볼 이름은 담은 λ¬Έμžμ—΄μ„ 가리킨닀.

flags μΈμžλŠ” 심볼에 λŒ€ν•œ 정보λ₯Ό μ œκ³΅ν•˜λ©΄μ„œ λ™μ‹œμ— 이 PLT(Procedure Linkage Table) ν•­λͺ©μ˜ 이후 감사 방식을 λ³€κ²½ν•˜λŠ” 데 μ“Έ 수 μžˆλŠ” λΉ„νŠΈ λ§ˆμŠ€ν¬μ΄λ‹€. 동적 링컀가 이 μΈμžμ— λ‹€μŒ λΉ„νŠΈ 값듀을 μ œκ³΅ν•  수 μžˆλ‹€.

LA_SYMB_DLSYM
dlsym(3) 호좜둜 인해 바인딩이 λ°œμƒν–ˆλ‹€.
LA_SYMB_ALTVALUE
μ•žμ„  la_symbind*() 호좜이 이 심볼에 λŒ€ν•΄ λŒ€μ²΄ 값을 λ°˜ν™˜ν–ˆλ‹€.

기본적으둜 감사 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ la_pltenter() 및 la_pltexit() ν•¨μˆ˜(μ•„λž˜ μ°Έκ³ )λ₯Ό κ΅¬ν˜„ν•˜κ³  있으면 la_symbind() 후에 심볼이 참쑰될 λ•Œλ§ˆλ‹€ PLT ν•­λͺ©μ— λŒ€ν•΄ κ·Έ ν•¨μˆ˜λ“€μ΄ ν˜ΈμΆœλœλ‹€. *flags에 λ‹€μŒ ν”Œλž˜κ·Έλ“€μ„ OR ν•΄μ„œ κ·Έ κΈ°λ³Έ λ™μž‘μ„ λ°”κΏ€ 수 μžˆλ‹€.

LA_SYMB_NOPLTENTER
이 심볼에 la_pltenter()λ₯Ό ν˜ΈμΆœν•˜μ§€ 말 것.
LA_SYMB_NOPLTEXIT
이 심볼에 la_pltexit()을 ν˜ΈμΆœν•˜μ§€ 말 것.

la_symbind32() 및 la_symbind64()의 λ°˜ν™˜ 값은 ν•¨μˆ˜ λ°˜ν™˜ ν›„ μ œμ–΄κ°€ λ„˜μ–΄κ°€μ•Ό ν•  μ£Όμ†Œμ΄λ‹€. 감사 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ 심볼 바인딩을 κ°μ‹œλ§Œ ν•˜λ €λŠ” 거라면 sym->st_valueλ₯Ό λ°˜ν™˜ν•˜λ©΄ λœλ‹€. λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ μ œμ–΄λ₯Ό λ‹€λ₯Έ λ°©ν–₯으둜 λ°”κΎΈκ³  μ‹Άλ‹€λ©΄ λ‹€λ₯Έ 값을 λ°˜ν™˜ν•  수 μžˆλ‹€.

la_pltenter()

이 ν•¨μˆ˜μ˜ μ •ν™•ν•œ 이름과 인자 νƒ€μž…μ€ ν•˜λ“œμ›¨μ–΄ ν”Œλž«νΌμ— 따라 λ‹€λ₯΄λ‹€. (<link.h>에 μ ˆμ ν•œ μ •μ˜κ°€ μžˆλ‹€.) λ‹€μŒμ€ x86-32용 μ •μ˜μ΄λ‹€.

Elf32_Addr la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
                 uintptr_t *refcook, uintptr_t *defcook,
                 La_i86_regs *regs, unsigned int *flags,
                 const char *symname, long int *framesizep);

바인딩 μ•Œλ¦Όμ„ λ°›κ²Œ ν‘œμ‹œλœ 두 곡유 였브젝트 κ°„μ—μ„œ PLT ν•­λͺ©μ΄ 호좜되기 λ°”λ‘œ 전에 이 ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€.

sym, ndx, refcook, defcook, symname은 la_symbind*()μ—μ„œμ™€ κ°™λ‹€.

regs μΈμžλŠ” 이 PLT ν•­λͺ© ν˜ΈμΆœμ— μ‚¬μš©λ  λ ˆμ§€μŠ€ν„°λ“€μ˜ 값을 담은 ꡬ쑰체(<link.h>에 μ •μ˜λΌ 있음)λ₯Ό 가리킨닀.

flags μΈμžλŠ” la_symbind*()μ—μ„œμ²˜λŸΌ 이 PLT ν•­λͺ©μ— λŒ€ν•œ 정보λ₯Ό λ‹΄κ³  있고 이후 감사 방식 변경에 μ΄μš©ν•  수 μžˆλŠ” λΉ„νŠΈ 마슀크λ₯Ό 가리킨닀.

framesizep μΈμžλŠ” long int 버퍼λ₯Ό κ°€λ¦¬ν‚€λŠ”λ° 이λ₯Ό μ΄μš©ν•΄ 이 PLT ν•­λͺ© ν˜ΈμΆœμ— μ‚¬μš©ν•˜λŠ” ν”„λ ˆμž„ 크기λ₯Ό λͺ…ν™•νžˆ μ„€μ •ν•  수 μžˆλ‹€. 이 심볼에 λŒ€ν•΄ μ—¬λŸ¬ la_pltenter()μ—μ„œ λ‹€λ₯Έ 값듀을 λ°˜ν™˜ν•˜λ©΄ κ°€μž₯ 큰 λ°˜ν™˜ 값을 μ“΄λ‹€. 이 버퍼가 λͺ…ν™•ν•˜κ²Œ μ μ ˆν•œ κ°’μœΌλ‘œ μ„€μ •λœ κ²½μš°μ—λ§Œ la_pltexit() ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€.

la_pltenter()의 λ°˜ν™˜ 값은 la_symbind*()μ—μ„œμ™€ κ°™λ‹€.

la_pltexit()

이 ν•¨μˆ˜μ˜ μ •ν™•ν•œ 이름과 인자 νƒ€μž…μ€ ν•˜λ“œμ›¨μ–΄ ν”Œλž«νΌμ— 따라 λ‹€λ₯΄λ‹€. (<link.h>에 μ ˆμ ν•œ μ •μ˜κ°€ μžˆλ‹€.) λ‹€μŒμ€ x86-32용 μ •μ˜μ΄λ‹€.

unsigned int la_i86_gnu_pltexit(Elf32_Sym *sym, unsigned int ndx,
                 uintptr_t *refcook, uintptr_t *defcook,
                 const La_i86_regs *inregs, La_i86_retval *outregs,
                 const char *symname);

바인딩 μ•Œλ¦Όμ„ λ°›κ²Œ ν‘œμ‹œλœ 두 곡유 였브젝트 κ°„μ—μ„œ PLT ν•­λͺ©μ΄ λ°˜ν™˜ν•  λ•Œ 이 ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€. PLT ν•­λͺ© ν˜ΈμΆœμžμ—κ²Œ μ œμ–΄κ°€ λŒμ•„κ°€κΈ° λ°”λ‘œ 전에 ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€.

sym, ndx, refcook, defcook, symname은 la_symbind*()μ—μ„œμ™€ κ°™λ‹€.

inregs μΈμžλŠ” 이 PLT ν•­λͺ© ν˜ΈμΆœμ— μ‚¬μš©λœ λ ˆμ§€μŠ€ν„°λ“€μ˜ 값을 담은 ꡬ쑰체(<link.h>에 μ •μ˜λΌ 있음)λ₯Ό 가리킨닀. outregs μΈμžλŠ” 이 PLT ν•­λͺ© 호좜의 λ°˜ν™˜ 값을 담은 ꡬ쑰체(<link.h>에 μ •μ˜λΌ 있음)λ₯Ό 가리킨닀. 이 값듀을 ν˜ΈμΆœμžκ°€ λ³€κ²½ν•  수 있으며 κ·Έ λ³€κ²½ λ‚΄μš©μ΄ PLT ν•­λͺ© ν˜ΈμΆœμžμ—κ²Œ 보이게 λœλ‹€.

ν˜„μž¬ GNU κ΅¬ν˜„μ—μ„œλŠ” la_pltexit()의 λ°˜ν™˜ 값을 λ¬΄μ‹œν•œλ‹€.

CONFORMING TO

이 APIλŠ” λΉ„ν‘œμ€€μ΄λ˜ μ†”λΌλ¦¬μŠ€ Linker and Libraries Guide의 Runtime Linker Auditing Interface μž₯에 기술된 μ†”λΌλ¦¬μŠ€ API와 맀우 λΉ„μŠ·ν•˜λ‹€.

NOTES

μ†”λΌλ¦¬μŠ€ 동적 링컀 감사 APIμ™€μ˜ λ‹€μŒ 차이에 μœ μ˜ν•˜λΌ.

  • μ†”λΌλ¦¬μŠ€μ˜ la_objfilter() μΈν„°νŽ˜μ΄μŠ€λ₯Ό GNU κ΅¬ν˜„μ—μ„œλŠ” μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€.

  • μ†”λΌλ¦¬μŠ€μ˜ la_symbind32() 및 la_pltexit() ν•¨μˆ˜μ—λŠ” symname μΈμžκ°€ μ—†λ‹€.

  • μ†”λΌλ¦¬μŠ€μ˜ la_pltexit() ν•¨μˆ˜μ—λŠ” inregs 및 outregs μΈμžκ°€ μ—†λ‹€. (ν•˜μ§€λ§Œ regval 인자둜 ν•¨μˆ˜ λ°˜ν™˜ 값은 μ œκ³΅ν•œλ‹€.)

BUGS

glibc 버전 2.9κΉŒμ§€μ—μ„œ LD_AUDIT에 감사 라이브러리λ₯Ό μ—¬λŸ¬ 개 μ§€μ •ν•˜λ©΄ λŸ°νƒ€μž„ ν¬λž˜μ‹œκ°€ λ°œμƒν•œλ‹€. glibc 2.10μ—μ„œ κ³ μ³μ‘Œλ‹€κ³  ν•œλ‹€.

EXAMPLE

#include <link.h>
#include <stdio.h>

unsigned int
la_version(unsigned int version)
{
    printf("la_version(): %d\n", version);

    return version;
}

char *
la_objsearch(const char *name, uintptr_t *cookie, unsigned int flag)
{
    printf("la_objsearch(): name = %s; cookie = %p", name, cookie);
    printf("; flag = %s\n",
            (flag == LA_SER_ORIG) ?    "LA_SER_ORIG" :
            (flag == LA_SER_LIBPATH) ? "LA_SER_LIBPATH" :
            (flag == LA_SER_RUNPATH) ? "LA_SER_RUNPATH" :
            (flag == LA_SER_DEFAULT) ? "LA_SER_DEFAULT" :
            (flag == LA_SER_CONFIG) ?  "LA_SER_CONFIG" :
            (flag == LA_SER_SECURE) ?  "LA_SER_SECURE" :
            "???");

    return name;
}

void
la_activity (uintptr_t *cookie, unsigned int flag)
{
    printf("la_activity(): cookie = %p; flag = %s\n", cookie,
            (flag == LA_ACT_CONSISTENT) ? "LA_ACT_CONSISTENT" :
            (flag == LA_ACT_ADD) ?        "LA_ACT_ADD" :
            (flag == LA_ACT_DELETE) ?     "LA_ACT_DELETE" :
            "???");
}

unsigned int
la_objopen(struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
    printf("la_objopen(): loading \"%s\"; lmid = %s; cookie=%p\n",
            map->l_name,
            (lmid == LM_ID_BASE) ?  "LM_ID_BASE" :
            (lmid == LM_ID_NEWLM) ? "LM_ID_NEWLM" :
            "???",
            cookie);

    return LA_FLG_BINDTO | LA_FLG_BINDFROM;
}

unsigned int
la_objclose (uintptr_t *cookie)
{
    printf("la_objclose(): %p\n", cookie);

    return 0;
}

void
la_preinit(uintptr_t *cookie)
{
    printf("la_preinit(): %p\n", cookie);
}

uintptr_t
la_symbind32(Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
        uintptr_t *defcook, unsigned int *flags, const char *symname)
{
    printf("la_symbind32(): symname = %s; sym->st_value = %p\n",
            symname, sym->st_value);
    printf("        ndx = %d; flags = 0x%x", ndx, *flags);
    printf("; refcook = %p; defcook = %p\n", refcook, defcook);

    return sym->st_value;
}

uintptr_t
la_symbind64(Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
        uintptr_t *defcook, unsigned int *flags, const char *symname)
{
    printf("la_symbind64(): symname = %s; sym->st_value = %p\n",
            symname, sym->st_value);
    printf("        ndx = %d; flags = 0x%x", ndx, *flags);
    printf("; refcook = %p; defcook = %p\n", refcook, defcook);

    return sym->st_value;
}

Elf32_Addr
la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
        uintptr_t *refcook, uintptr_t *defcook, La_i86_regs *regs,
        unsigned int *flags, const char *symname, long int *framesizep)
{
    printf("la_i86_gnu_pltenter(): %s (%p)\n", symname, sym->st_value);

    return sym->st_value;
}

SEE ALSO

ldd(1), dlopen(3), ld.so(8), ldconfig(8)


2019-03-06

⚠️ **GitHub.com Fallback** ⚠️