memfd_create(2) - wariua/manpages-ko GitHub Wiki

NAME

memfd_create - 읡λͺ… 파일 λ§Œλ“€κΈ°

SYNOPSIS

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

int memfd_create(const char *name, unsigned int flags);

DESCRIPTION

memfd_create()λŠ” 읡λͺ… νŒŒμΌμ„ μƒμ„±ν•΄μ„œ κ·Έ νŒŒμΌμ„ κ°€λ¦¬ν‚€λŠ” 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λ°˜ν™˜ν•œλ‹€. κ·Έ νŒŒμΌμ€ 일반 파일처럼 λ™μž‘ν•˜λ―€λ‘œ λ³€κ²½ν•˜κ±°λ‚˜ μž˜λΌλ‚΄κ±°λ‚˜ λ©”λͺ¨λ¦¬μ— λ§΅ ν•˜κ±°λ‚˜ ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ 일반 파일과 달리 램 μ•ˆμ—λ§Œ μžˆμœΌλ―€λ‘œ 기반 μ €μž₯μ†Œκ°€ νœ˜λ°œμ„±μ΄λ‹€. νŒŒμΌμ— λŒ€ν•œ μ°Έμ‘°κ°€ λͺ¨λ‘ μ—†μ–΄μ§€λ©΄ μžλ™μœΌλ‘œ ν•΄μ œλœλ‹€. κ·Έ 파일의 기반 νŽ˜μ΄μ§€ λͺ¨λ‘μ— 읡λͺ… λ©”λͺ¨λ¦¬κ°€ 쓰인닀. λ”°λΌμ„œ memfd_create()둜 λ§Œλ“  νŒŒμΌμ€ MAP_ANONYMOUS ν”Œλž˜κ·Έλ‘œ mmap(2)을 μ‚¬μš©ν•΄ ν• λ‹Ήν•œ 것 같은 λ‹€λ₯Έ 읡λͺ… λ©”λͺ¨λ¦¬ ν• λ‹Ήκ³Ό λ™μž‘ 방식이 κ°™λ‹€.

μ²˜μŒμ— 파일의 ν¬κΈ°λŠ” 0으둜 섀정돼 μžˆλ‹€. 호좜 후에 ftruncate(2)λ₯Ό μ‚¬μš©ν•΄ 파일 크기λ₯Ό μ„€μ •ν•΄ μ£Όμ–΄μ•Ό ν•  것이닀. (λ˜λŠ” write(2) 등을 ν˜ΈμΆœν•΄μ„œ νŒŒμΌμ„ μ±„μšΈ μˆ˜λ„ μžˆλ‹€.)

name에 μ€€ 이름은 파일λͺ…μœΌλ‘œ μ“°λ©° /proc/self/fd/ λ””λ ‰ν„°λ¦¬μ˜ λŒ€μ‘ν•˜λŠ” 심볼릭 링크의 λŒ€μƒμœΌλ‘œ ν‘œμ‹œλœλ‹€. ν‘œμ‹œλ˜λŠ” 이름 μ•žμ— 항상 memfd:κ°€ λΆ™μœΌλ©° 디버깅 μš©λ„λ‘œ 쓰일 뿐이닀. 파일 λ””μŠ€ν¬λ¦½ν„°μ˜ λ™μž‘μ— 이름이 영ν–₯을 μ£Όμ§€ μ•ŠμœΌλ©° κ·Έλž˜μ„œ 아무 λΆ€μž‘μš© 없이 μ—¬λŸ¬ 파일이 같은 이름을 κ°€μ§ˆ 수 μžˆλ‹€.

flags에 λ‹€μŒ 값듀을 λΉ„νŠΈ OR ν•΄μ„œ memfd_create()의 λ™μž‘ 방식을 λ°”κΏ€ 수 μžˆλ‹€.

MFD_CLOEXEC
μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°μ— 'execμ—μ„œ λ‹«κΈ°'(FD_CLOEXEC) ν”Œλž˜κ·Έλ₯Ό μ„€μ •ν•œλ‹€. 이게 μœ μš©ν•  수 μžˆλŠ” μ΄μœ μ— λŒ€ν•΄μ„  open(2)의 O_CLOEXEC ν”Œλž˜κ·Έ μ„€λͺ…을 보라.
MFD_ALLOW_SEALING
νŒŒμΌμ— λŒ€ν•œ 봉인 λ™μž‘μ„ ν—ˆμš©ν•œλ‹€. fcntl(2)의 F_ADD_SEALS 및 F_GET_SEALS λ™μž‘ λ…Όμ˜μ™€ μ•„λž˜ NOTESλ₯Ό μ°Έκ³ ν•˜λΌ. 졜초 봉인 집합은 λΉ„μ–΄ μžˆλ‹€. 이 ν”Œλž˜κ·Έκ°€ 섀정돼 μžˆμ§€ μ•ŠμœΌλ©΄ 졜초 봉인 집합이 F_SEAL_SEAL이 λœλ‹€. 즉 νŒŒμΌμ— λ‹€λ₯Έ 봉인을 μ„€μ •ν•  수 μ—†λ‹€.
MFD_HUGETLB (λ¦¬λˆ…μŠ€ 4.14λΆ€ν„°)
읡λͺ… 파일이 κ±°λŒ€ νŽ˜μ΄μ§€λ₯Ό μ΄μš©ν•΄ hugetlbfs 파일 μ‹œμŠ€ν…œ μ•ˆμ— λ§Œλ“€μ–΄μ§€κ²Œ λœλ‹€. hugetlbfs에 λŒ€ν•œ μžμ„Έν•œ λ‚΄μš©μ€ λ¦¬λˆ…μŠ€ 컀널 μ†ŒμŠ€ 파일 Documentation/admin-guide/mm/hugetlbpage.rstλ₯Ό 보라. flags에 MFD_HUGETLB와 MFD_ALLOW_SEALING을 ν•¨κ»˜ μ§€μ •ν•˜λŠ” 것은 λ¦¬λˆ…μŠ€ 4.16λΆ€ν„° μ§€μ›ν•œλ‹€.
MFD_HUGE_2MB, MFD_HUGE_1GB, ...

hugetlb νŽ˜μ΄μ§€ 크기λ₯Ό μ—¬λŸ¬ κ°€μ§€ μ§€μ›ν•˜λŠ” μ‹œμŠ€ν…œμ—μ„œ MFD_HUGETLB와 μ‘°ν•©ν•΄ μ‚¬μš©ν•΄μ„œ λ‹€λ₯Έ hugetlb νŽ˜μ΄μ§€ 크기(각각 2MB, 1GB, ...)λ₯Ό μ„ νƒν•œλ‹€. μ•Œλ €μ§„ κ±°λŒ€ νŽ˜μ΄μ§€ ν¬κΈ°λ“€μ˜ μ •μ˜κ°€ 헀더 파일 <linux/memfd.h>에 포함돼 μžˆλ‹€.

헀더 νŒŒμΌμ— 포함돼 μžˆμ§€ μ•Šμ€ κ±°λŒ€ νŽ˜μ΄μ§€ 크기λ₯Ό 인코딩 ν•˜λŠ” μžμ„Έν•œ 방법에 λŒ€ν•΄μ„  mmap(2)의 λΉ„μŠ·ν•œ μ΄λ¦„μ˜ μƒμˆ˜μ— λŒ€ν•œ μ„€λͺ…을 보라.

flags의 μ•ˆ μ“°λŠ” λΉ„νŠΈλ“€μ€ 0이어야 ν•œλ‹€.

λ°˜ν™˜ κ°’μœΌλ‘œ memfd_create()κ°€ λ°˜ν™˜ν•˜λŠ” μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό νŒŒμΌμ„ 가리킬 데 μ“Έ 수 μžˆλ‹€. κ·Έ 파일 λ””μŠ€ν¬λ¦½ν„°λŠ” 읽기 및 μ“°κΈ°(O_RDWR)둜 μ—΄λ € 있으며 파일 λ””μŠ€ν¬λ¦½ν„°μ— O_LARGEFILE이 섀정돼 μžˆλ‹€.

fork(2) 및 execve(2)와 κ΄€λ ¨ν•΄μ„  일반적인 의미둠이 memfd_create()둜 λ§Œλ“  파일 λ””μŠ€ν¬λ¦½ν„°μ— μ μš©λœλ‹€. fork(2)둜 생긴 μžμ‹μ΄ 파일 λ””μŠ€ν¬λ¦½ν„° 사본을 λ¬Όλ €λ°›μœΌλ©° κ·Έ 사본은 νŒŒμΌμ„ 가리킨닀. 'execμ—μ„œ λ‹«κΈ°' ν”Œλž˜κ·Έλ₯Ό μ„€μ •ν•˜μ§€ μ•Šμ•˜μœΌλ©΄ execve(2)λ₯Ό κ±°μΉ˜λ©΄μ„œ 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ μœ μ§€λœλ‹€.

RETURN VALUE

성곡 μ‹œ memfd_create()λŠ” μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λ°˜ν™˜ν•œλ‹€. 였λ₯˜ μ‹œ -1을 λ°˜ν™˜ν•˜λ©° 였λ₯˜λ₯Ό λ‚˜νƒ€λ‚΄λ„λ‘ errnoλ₯Ό μ„€μ •ν•œλ‹€.

ERRORS

EFAULT
name의 μ£Όμ†Œκ°€ μœ νš¨ν•˜μ§€ μ•Šμ€ λ©”λͺ¨λ¦¬λ₯Ό 가리킀고 μžˆλ‹€.
EINVAL
flags에 μ•Œ 수 μ—†λŠ” λΉ„νŠΈκ°€ 포함돼 μžˆλ‹€.
EINVAL
name이 λ„ˆλ¬΄ κΈΈλ‹€. (μ’…λ£Œμš© 널 λ°”μ΄νŠΈλ₯Ό μ œμ™Έν•˜κ³  249λ°”μ΄νŠΈκ°€ μ œν•œ 길이이닀.)
EINVAL
flags에 MFD_HUGETLB와 MFD_ALLOW_SEALING을 ν•¨κ»˜ μ§€μ •ν–ˆλ‹€.
EMFILE
μ—΄λ¦° 파일 λ””μŠ€ν¬λ¦½ν„° κ°œμˆ˜μ— λŒ€ν•œ ν”„λ‘œμ„ΈμŠ€λ³„ μ œν•œμ— λ„λ‹¬ν–ˆλ‹€.
ENFILE
μ—΄λ¦° 파일 μ΄κ°œμˆ˜μ— λŒ€ν•œ μ‹œμŠ€ν…œ μ „μ—­ μ œν•œμ— λ„λ‹¬ν–ˆλ‹€.
ENOMEM
μƒˆ 읡λͺ… νŒŒμΌμ„ μƒμ„±ν•˜κΈ°μ— λ©”λͺ¨λ¦¬κ°€ μΆ©λΆ„ν•˜μ§€ μ•Šμ•˜λ‹€.

VERSIONS

λ¦¬λˆ…μŠ€ 3.17μ—μ„œ memfd_create() μ‹œμŠ€ν…œ 호좜이 처음 λ“±μž₯ν–ˆλ‹€. glibc 버전 2.27μ—μ„œ 지원이 μΆ”κ°€λ˜μ—ˆλ‹€.

CONFORMING TO

memfd_create() μ‹œμŠ€ν…œ ν˜ΈμΆœμ€ λ¦¬λˆ…μŠ€ μ „μš©μ΄λ‹€.

NOTES

memfd_create() μ‹œμŠ€ν…œ ν˜ΈμΆœμ€ μˆ˜λ™μœΌλ‘œ tmpfs(5) 파일 μ‹œμŠ€ν…œμ„ 마운트 ν•΄μ„œ κ±°κΈ°μ„œ νŒŒμΌμ„ μ—¬λŠ” λ°©μ‹μ˜ κ°„λ‹¨ν•œ λŒ€μ•ˆμ΄ 돼 μ€€λ‹€. memfd_create()의 주된 λͺ©μ μ€ fcntl(2)μ—μ„œ μ œκ³΅ν•˜λŠ” 파일 봉인 API와 ν•¨κ»˜ μ‚¬μš©ν•  파일 및 연계 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λ§Œλ“œλŠ” 것이닀.

파일 봉인 없이도 memfd_create() μ‹œμŠ€ν…œ ν˜ΈμΆœμ— μ“°μž„μƒˆκ°€ μžˆλ‹€. (κ·Έλž˜μ„œ MFD_ALLOW_SEALING ν”Œλž˜κ·Έλ‘œ λͺ…μ‹œμ μœΌλ‘œ μš”μ²­ν•˜μ§€ μ•ŠμœΌλ©΄ 파일 봉인이 κΊΌμ Έ μžˆλ‹€.) 특히 κ²°κ³Ό νŒŒμΌμ„ 파일 μ‹œμŠ€ν…œμ— μ‹€μ œλ‘œ μ—°κ²°μ‹œν‚¬ μ˜λ„κ°€ μ—†λŠ” κ²½μš°μ— tmp에 νŒŒμΌμ„ μƒμ„±ν•˜λŠ” κ²ƒμ΄λ‚˜ open(2) O_TMPFILEλ₯Ό μ‚¬μš©ν•˜λŠ” κ²ƒμ˜ λŒ€μ•ˆμœΌλ‘œ μ“Έ 수 μžˆλ‹€.

파일 봉인

파일 봉인이 μ—†λŠ” κ²½μš°μ—λŠ” 곡유 λ©”λͺ¨λ¦¬λ₯Ό 톡해 ν†΅μ‹ ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€λ“€μ΄ μ„œλ‘œλ₯Ό μ‹ λ’°ν•˜λ“ μ§€, μ•„λ‹ˆλ©΄ μ‹ λ’°ν•  수 μ—†λŠ” μƒλŒ€κ°€ 문제 μžˆλŠ” λ°©μ‹μœΌλ‘œ 곡유 λ©”λͺ¨λ¦¬ μ˜μ—­μ„ μ‘°μž‘ν•  κ°€λŠ₯성에 λŒ€μ²˜ν•΄μ•Ό ν•œλ‹€. 예λ₯Ό λ“€μ–΄ μ‹ λ’°ν•  수 μ—†λŠ” μƒλŒ€κ°€ 아무 λ•Œλ‚˜ 곡유 λ©”λͺ¨λ¦¬μ˜ λ‚΄μš©λ¬Όμ„ λ³€κ²½ν•  μˆ˜λ„ μžˆμ„ 것이고, 곡유 λ©”λͺ¨λ¦¬ μ˜μ—­μ„ 쀄여 버릴 μˆ˜λ„ μžˆμ„ 것이닀. μ•žμͺ½ κ°€λŠ₯성은 ν”„λ‘œμ„ΈμŠ€κ°€ 검사 μ‹œμ  μ‚¬μš© μ‹œμ (TOCTTOU) 경쟁 쑰건에 λ…ΈμΆœλ˜κ²Œ 놔둔닀. (보톡 곡유 λ©”λͺ¨λ¦¬ μ˜μ—­μ˜ 데이터λ₯Ό λ³΅μ‚¬ν•œ λ‹€μŒμ— 검사 및 μ‚¬μš©ν•˜λŠ” κ²ƒμœΌλ‘œ λŒ€μ²˜ν•œλ‹€.) λ’€μͺ½ κ°€λŠ₯성은 ν”„λ‘œμ„ΈμŠ€κ°€ 곡유 λ©”λͺ¨λ¦¬ μ˜μ—­μ˜ λ”λŠ” μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μœ„μΉ˜μ— μ ‘κ·Όν•˜λ € ν•  λ•Œ SIGBUSλ₯Ό λ°›κ²Œ ν•œλ‹€. (이 κ²½μš°μ— λŒ€μ²˜ν•˜λ €λ©΄ SIGBUS μ‹œκ·Έλ„μ— λŒ€ν•œ ν•Έλ“€λŸ¬ μ‚¬μš©μ΄ ν•„μš”ν•΄μ§„λ‹€.)

μ‹ λ’°ν•  수 μ—†λŠ” μƒλŒ€λ₯Ό 닀루렀면 곡유 λ©”λͺ¨λ¦¬ μ‚¬μš© μ½”λ“œμ— λ³΅μž‘λ„κ°€ 더해져야 ν•œλ‹€. λ©”λͺ¨λ¦¬ 봉인을 μ“°λ©΄ μƒλŒ€κ°€ λ°”λžŒμ§ν•˜μ§€ μ•Šμ€ λ°©μ‹μœΌλ‘œ 곡유 λ©”λͺ¨λ¦¬λ₯Ό μ‘°μž‘ν•  수 μ—†λ‹€κ³  μ•ˆμ‹¬ν•˜κ³  λ™μž‘ν•  수 μžˆμœΌλ―€λ‘œ κ·Έ μΆ”κ°€ λ³΅μž‘λ„λ₯Ό 없앨 수 μžˆλ‹€.

λ‹€μŒμ€ 봉인 λ©”μ»€λ‹ˆμ¦˜ μ‚¬μš© μ˜ˆμ‹œμ΄λ‹€.

  1. 첫 번째 ν”„λ‘œμ„ΈμŠ€κ°€ memfd_create()λ₯Ό μ¨μ„œ tmpfs(5) νŒŒμΌμ„ μƒμ„±ν•œλ‹€. 호좜이 λ‚΄λ†“λŠ” 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό 이후 λ‹¨κ³„λ“€μ—μ„œ μ‚¬μš©ν•œλ‹€.

  2. 첫 번째 ν”„λ‘œμ„ΈμŠ€κ°€ μ•žμ„œ μƒμ„±ν•œ 파일 크기λ₯Ό ftruncate(2)둜 μ‘°μ •ν•˜κ³  mmap(2)으둜 λ§΅ ν•œ λ‹€μŒ κ·Έ 곡유 λ©”λͺ¨λ¦¬λ₯Ό μ›ν•˜λŠ” λ°μ΄ν„°λ‘œ μ±„μš΄λ‹€.

  3. 첫 번째 ν”„λ‘œμ„ΈμŠ€κ°€ νŒŒμΌμ— λŒ€ν•œ μΆ”κ°€ 변경을 μ œμ•½ν•˜κΈ° μœ„ν•΄ fcntl(2) F_ADD_SEALS λ™μž‘μ„ μ΄μš©ν•΄ νŒŒμΌμ— ν•œ 개 μ΄μƒμ˜ 봉인을 ν•œλ‹€. (F_SEAL_WRITE 봉인을 ν•˜λŠ” κ²½μš°μ—λŠ” μ•ž λ‹¨κ³„μ—μ„œ λ§Œλ“  μ“°κΈ° κ°€λŠ₯ν•œ 곡유 맀핑을 λ¨Όμ € ν•΄μ œν•΄μ•Ό ν•  것이닀.)

  4. 두 번째 ν”„λ‘œμ„ΈμŠ€κ°€ κ·Έ tmpfs(5) νŒŒμΌμ— λŒ€ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό μ–»μ–΄μ„œ λ§΅ ν•œλ‹€. λ‹€μŒμ„ ν¬ν•¨ν•œ μ—¬λŸ¬ λ°©μ‹μœΌλ‘œ κ·Έλ ‡κ²Œ ν•  수 μžˆλ‹€.

    • memfd_create()λ₯Ό ν˜ΈμΆœν•œ ν”„λ‘œμ„ΈμŠ€κ°€ 결과둜 λ‚˜μ˜¨ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό μœ λ‹‰μŠ€ 도메인 μ†ŒμΌ“μ„ 톡해 두 번째 ν”„λ‘œμ„ΈμŠ€μ—κ²Œ 전솑할 수 μžˆλ‹€. (unix(7) 및 cmsg(3) μ°Έκ³ .) 그러면 두 번째 ν”„λ‘œμ„ΈμŠ€κ°€ mmap(2)으둜 κ·Έ νŒŒμΌμ„ λ§΅ ν•œλ‹€.

    • 두 번째 ν”„λ‘œμ„ΈμŠ€κ°€ fork(2)λ₯Ό 톡해 μƒμ„±λ˜μ–΄ μžλ™μœΌλ‘œ 파일 λ””μŠ€ν¬λ¦½ν„°μ™€ 맀핑을 λ¬Όλ €λ°›λŠ”λ‹€. (참고둜 이 κ²½μš°μ™€ λ‹€μŒ κ²½μš°μ—μ„œλŠ” 두 ν”„λ‘œμ„ΈμŠ€κ°€ 같은 μ‚¬μš©μž ID ν•˜μ—μ„œ 돌기 λ•Œλ¬Έμ— λ‹Ήμ—°ν•œ μ‹ λ’° 관계가 μžˆλ‹€. λ”°λΌμ„œ 보톡은 파일 봉인이 ν•„μš”ν•˜μ§€ μ•Šλ‹€.)

    • 두 번째 ν”„λ‘œμ„ΈμŠ€κ°€ /proc/<pid>/fd/<fd> νŒŒμΌμ„ μ—°λ‹€. μ—¬κΈ°μ„œ <pid>λŠ” (memfd_create()을 ν˜ΈμΆœν•œ) 첫 번째 ν”„λ‘œμ„ΈμŠ€μ˜ PID이고 <fd>λŠ” κ·Έ ν”„λ‘œμ„ΈμŠ€μ˜ memfd_create() 호좜이 λ°˜ν™˜ν•œ 파일 λ””μŠ€ν¬λ¦½ν„° λ²ˆν˜Έμ΄λ‹€. κ·ΈλŸ¬κ³ μ„œ 두 번째 ν”„λ‘œμ„ΈμŠ€κ°€ mmap(2)으둜 κ·Έ νŒŒμΌμ„ λ§΅ ν•œλ‹€.

  5. 두 번째 ν”„λ‘œμ„ΈμŠ€κ°€ fcntl(2) F_GET_SEALS λ™μž‘μ„ μ¨μ„œ κ·Έ νŒŒμΌμ— 적용된 λ΄‰μΈλ“€μ˜ λΉ„νŠΈ 마슀크λ₯Ό κ°€μ Έμ˜¨λ‹€. 이 λΉ„νŠΈ 마슀크λ₯Ό μ‚΄νŽ΄λ³΄λ©΄ 파일 λ³€κ²½ 방식에 μ–΄λ–€ μ œμ•½μ΄ κ°€ν•΄μ‘ŒλŠ”μ§€ μ•Œμ•„λ‚Ό 수 μžˆλ‹€. μ›ν•œλ‹€λ©΄ 두 번째 ν”„λ‘œμ„ΈμŠ€μ—μ„œ 봉인을 더 μ μš©ν•΄μ„œ μ œμ•½μ„ μΆ”κ°€λ‘œ κ°€ν•  수 μžˆλ‹€. (단 F_SEAL_SEAL 봉인이 μ μš©λ˜μ§€ μ•Šμ•˜μ–΄μ•Ό ν•œλ‹€.)

EXAMPLE

memfd_create()와 파일 봉인 API μ‚¬μš© 방식을 보여 μ£ΌλŠ” 두 κ°€μ§€ μ˜ˆμ‹œ ν”„λ‘œκ·Έλž¨μ΄ μ•„λž˜μ— μžˆλ‹€.

첫 번째 ν”„λ‘œκ·Έλž¨μΈ t_memfd_create.cμ—μ„œλŠ” memfd_create()둜 tmpfs(5) νŒŒμΌμ„ λ§Œλ“€κ³ , 파일 크기λ₯Ό μ„€μ •ν•˜κ³ , λ©”λͺ¨λ¦¬λ‘œ λ§΅ ν•˜κ³ , μ„ νƒμ μœΌλ‘œ νŒŒμΌμ— λͺ‡ κ°€μ§€ 봉인을 λ‘”λ‹€. ν”„λ‘œκ·Έλž¨μ΄ λͺ…λ Ήν–‰ 인자λ₯Ό μ„Έ κ°œκΉŒμ§€ λ°›λŠ”λ° 처음 두 κ°œλŠ” ν•„μˆ˜μ΄λ‹€. 첫 번째 μΈμžλŠ” νŒŒμΌμ— 연계할 이름이고 두 번째 μΈμžλŠ” νŒŒμΌμ— μ„€μ •ν•  크기이며 선택적인 μ„Έ 번째 μΈμžλŠ” νŒŒμΌμ— μ„€μ •ν•  봉인을 λ‚˜νƒ€λ‚΄λŠ” λ¬Έμžμ—΄μ΄λ‹€.

두 번째 ν”„λ‘œκ·Έλž¨μΈ t_get_seals.cλ₯Ό μ΄μš©ν•΄ memfd_create()둜 μƒμ„±λœ κΈ°μ‘΄ νŒŒμΌμ„ μ—΄μ–΄μ„œ κ·Έ νŒŒμΌμ— 적용된 봉인 집합을 μ‚΄νŽ΄λ³Ό 수 μžˆλ‹€.

λ‹€μŒ μ…Έ μ„Έμ…˜μ€ 이 ν”„λ‘œκ·Έλž¨λ“€μ˜ μ‚¬μš© 방식을 보여 μ€€λ‹€. λ¨Όμ € tmpfs(5) νŒŒμΌμ„ λ§Œλ“€κ³  λͺ‡ κ°€μ§€ 봉인을 μ„€μ •ν•œλ‹€.

$ ./t_memfd_create my_memfd_file 4096 sw &
[1] 11775
PID: 11775; fd: 3; /proc/11775/fd/3

이 μ‹œμ μ—μ„œ t_memfd_create ν”„λ‘œκ·Έλž¨μ€ λ°°κ²½μ—μ„œ 싀행을 κ³„μ†ν•œλ‹€. memfd_create()둜 μ—΄μ—ˆλ˜ 파일 λ””μŠ€ν¬λ¦½ν„°μ— λŒ€μ‘ν•˜λŠ” /proc/[pid]/fd νŒŒμΌμ„ 또 λ‹€λ₯Έ ν”„λ‘œκ·Έλž¨μ—μ„œ μ—΄μ–΄μ„œ memfd_create() 생성 νŒŒμΌμ— λŒ€ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό 얻을 수 μžˆλ‹€. κ·Έ 경둜λͺ…을 μ΄μš©ν•΄ 심볼릭 링크 /proc/[pid]/fd의 λ‚΄μš©μ„ ν™•μΈν•˜κ³  t_get_seals ν”„λ‘œκ·Έλž¨μ„ μ΄μš©ν•΄ κ·Έ νŒŒμΌμ— 적용된 봉인듀을 λ³Έλ‹€.

$ readlink /proc/11775/fd/3
/memfd:my_memfd_file (deleted)
$ ./t_get_seals /proc/11775/fd/3
Existing seals: WRITE SHRINK

ν”„λ‘œκ·Έλž¨ μ†ŒμŠ€: t_memfd_create.c

#define _GNU_SOURCE
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                        } while (0)

int
main(int argc, char *argv[])
{
    int fd;
    unsigned int seals;
    char *addr;
    char *name, *seals_arg;
    ssize_t len;

    if (argc < 3) {
        fprintf(stderr, "%s name size [seals]\n", argv[0]);
        fprintf(stderr, "\t'seals' can contain any of the "
                "following characters:\n");
        fprintf(stderr, "\t\tg - F_SEAL_GROW\n");
        fprintf(stderr, "\t\ts - F_SEAL_SHRINK\n");
        fprintf(stderr, "\t\tw - F_SEAL_WRITE\n");
        fprintf(stderr, "\t\tS - F_SEAL_SEAL\n");
        exit(EXIT_FAILURE);
    }

    name = argv[1];
    len = atoi(argv[2]);
    seals_arg = argv[3];

    /* tmpfs에 읡λͺ… 파일 생성. νŒŒμΌμ— 봉인 ν•  수 있게 ν•˜κΈ° */

    fd = memfd_create(name, MFD_ALLOW_SEALING);
    if (fd == -1)
        errExit("memfd_create");

    /* λͺ…λ Ήν–‰μ—μ„œ μ§€μ •ν•œ λŒ€λ‘œ 파일 크기 μ‘°μ • */

    if (ftruncate(fd, len) == -1)
        errExit("truncate");

    printf("PID: %ld; fd: %d; /proc/%ld/fd/%d\n",
            (long) getpid(), fd, (long) getpid(), fd);

    /* νŒŒμΌμ„ λ§΅ ν•˜κ³  κ·Έ 맀핑에 데이터λ₯Ό μ±„μš°λŠ” μ½”λ“œλŠ” μƒλž΅ */

    /* λͺ…λ Ήν–‰ 인자 'seals'λ₯Ό λ°›μ•˜μœΌλ©΄ νŒŒμΌμ— 봉인 μ„€μ • */

    if (seals_arg != NULL) {
        seals = 0;

        if (strchr(seals_arg, 'g') != NULL)
            seals |= F_SEAL_GROW;
        if (strchr(seals_arg, 's') != NULL)
            seals |= F_SEAL_SHRINK;
        if (strchr(seals_arg, 'w') != NULL)
            seals |= F_SEAL_WRITE;
        if (strchr(seals_arg, 'S') != NULL)
            seals |= F_SEAL_SEAL;

        if (fcntl(fd, F_ADD_SEALS, seals) == -1)
            errExit("fcntl");
    }

    /* memfd_create()둜 μƒμ„±ν•œ 파일이 계속 μ‘΄μž¬ν•˜λ„λ‘
       싀행을 계속 */

    pause();

    exit(EXIT_SUCCESS);
}

ν”„λ‘œκ·Έλž¨ μ†ŒμŠ€: t_get_seals.c

#define _GNU_SOURCE
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                        } while (0)

int
main(int argc, char *argv[])
{
    int fd;
    unsigned int seals;

    if (argc != 2) {
        fprintf(stderr, "%s /proc/PID/fd/FD\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    fd = open(argv[1], O_RDWR);
    if (fd == -1)
        errExit("open");

    seals = fcntl(fd, F_GET_SEALS);
    if (seals == -1)
        errExit("fcntl");

    printf("Existing seals:");
    if (seals & F_SEAL_SEAL)
        printf(" SEAL");
    if (seals & F_SEAL_GROW)
        printf(" GROW");
    if (seals & F_SEAL_WRITE)
        printf(" WRITE");
    if (seals & F_SEAL_SHRINK)
        printf(" SHRINK");
    printf("\n");

    /* νŒŒμΌμ„ λ§΅ ν•˜κ³  κ²°κ³Ό λ§€ν•‘ λ‚΄μš©μ— μ ‘κ·Όν•˜λŠ” μ½”λ“œλŠ” μƒλž΅ */

    exit(EXIT_SUCCESS);
}

SEE ALSO

fcntl(2), ftruncate(2), mmap(2), shmget(2), shm_open(3)


2019-03-06

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