Secret Memory โ `memfd_secret(2)` ์์คํ ํธ์ถ
๊ฐ์
Secret Memory๋ Linux ์ปค๋์์ _userspace๋ง ์ ๊ทผ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ ์์ญ_์ ์์ฑํ๋ ๋ฉ์ปค๋์ฆ์ด๋ค. memfd_secret(2) ์์คํ
ํธ์ถ์ ํตํด ์์ฑ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ mmapํ๋ฉด, ํด๋น ๋ฉ๋ชจ๋ฆฌ๋ ์ปค๋์ ์ง์ ๋งคํ(direct map)์์ ์ ์ธ๋๋ค. ์ฆ, ์ปค๋์ด ํ์ด์ง ํ
์ด๋ธ์์ ํด๋น ํ์ด์ง๋ฅผ ์ ๊ฑฐํ์ฌ ์์ฒด์ ์ผ๋ก๋ ์ฝ์ ์ ์๊ฒ ๋๋ค. ์ด๋ ๋น๋ฐํค ์ ์ฅ์, ์ํธํ ํค ๊ด๋ฆฌ,TEE(Trusted Execution Environment) ๋ฐํ์๊ณผ ๊ฐ์ ๋ณด์์ด ์ค์ํ ์ฌ์ฉ ์ฌ๋ก์ ํ์ฉ๋๋ค.
ํต์ฌ ์๋ฆฌ๋ ๊ฐ๋จํ๋ค: ํ์ด์ง๋ฅผ ํ ๋นํ ๋ค set_direct_map_invalid_noflush()๋ฅผ ํธ์ถํ์ฌ ์ปค๋์ linear map์์ ํด๋น ํ์ด์ง๋ฅผ unmapํ๊ณ , TLB ํ๋ฌ์๋ฅผ ํตํด ์ค์ ๋งคํ์ ๋ฌดํจํํ๋ค. ์ดํ ์ฌ์ฉ์ ๊ณต๊ฐ๋ง์ด ํ์ด์ง ํ
์ด๋ธ ์ํธ๋ฆฌ๋ฅผ ํตํด ํด๋น ํ์ด์ง์ ์ ๊ทผํ ์ ์๋ค. GUP(Get User Pages) ๊ฒฝ๋ก์์๋ secretmem ํ์ด์ง๋ ๋ช
์์ ์ผ๋ก ๊ฑฐ๋ถ๋์ด ์ปค๋์ด ์ฐํํ ์ ์๋๋ก ์ฐจ๋จ๋๋ค.
์์ค ํ์ผ ๊ฒฝ๋ก:
mm/secretmem.c โ ๋ฉ์ธ ๊ตฌํ (270์ค)
include/linux/secretmem.h โ ํค๋ (36์ค)
mm/gup.c โ GUP-fast secretmem ๊ฑฐ๋ถ ๋ก์ง
mm/mlock.c โ VM_LOCKED ํ๋๊ทธ ์ฒ๋ฆฌ
arch/x86/mm/pat/set_memory.c โ set_direct_map_invalid_noflush ๊ตฌํ
fs/anon_inodes.c โ anon_inode_make_secure_inode
๋น ๋ฅธ ์ ๊ฒ ๋ช ๋ น
# 1. secretmem ํ์ฑํ ์ฌ๋ถ ํ์ธ (์ปค๋ ๋น๋ ์ต์
)
cat /boot/config-$(uname -r) | grep SECRETMEM
# 2. memfd_secret ์์คํ
ํธ์ถ ์กด์ฌ ์ฌ๋ถ ํ์ธ
grep -c memfd_secret /usr/include/asm/unistd_64.h
# 3. ํ์ฌ secretmem ์ฌ์ฉ์ ์ (ํ์ฑ ํ์ผ ๋์คํฌ๋ฆฝํฐ)
sudo cat /proc/sys/kernel/secretmem_users 2>/dev/null || echo "sysctl ๋ฏธ์ง์"
# 4. ์ปค๋ ๋ชจ๋/ํ๋ผ๋ฏธํฐ ํ์ธ
cat /sys/module/secretmem/parameters/enable 2>/dev/null || echo "๋ชจ๋ ๋ฏธ๋ก๋"
# 5. /proc/meminfo์์ secretmem ๊ด๋ จ ํ์ธ
grep -i secret /proc/meminfo 2>/dev/null || echo "secretmem ์ ์ฉ ํญ๋ชฉ ์์"
# 6. ์ค์ ํ
์คํธ ํ๋ก๊ทธ๋จ ์ปดํ์ผ ๋ฐ ์คํ
cat > /tmp/test_secretmem.c << 'EOF'
#include <stdio.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
int fd = syscall(SYS_memfd_secret, O_CLOEXEC);
if (fd < 0) { perror("memfd_secret"); return 1; }
void *p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) { perror("mmap"); return 1; }
/* ์ฌ์ฉ์ ๊ณต๊ฐ์์๋ง ์ ๊ทผ ๊ฐ๋ฅ โ ์ปค๋ ์ง์ ๋งคํ์์ ์ ์ธ๋จ */
printf("secretmem ํ์ด์ง ํ ๋น ์ฑ๊ณต: %p\n", p);
munmap(p, 4096);
close(fd);
return 0;
}
EOF
gcc /tmp/test_secretmem.c -o /tmp/test_secretmem && /tmp/test_secretmem
# 7. ARM64 ๋ฑ ์ํคํ
์ฒ๋ณ direct map ์ ํ ํ์ธ
zgrep CONFIG_ARCH_HAS_SET_DIRECT_MAP /proc/config.gz 2>/dev/null || echo "config ๋ฏธ์ง์"
ํต์ฌ ์๋ฃ๊ตฌ์กฐ
`secretmem_vm_ops` โ VMA ์ฐ์ฐ ํ ์ด๋ธ
// mm/secretmem.c:111-113
static const struct vm_operations_struct secretmem_vm_ops = {
.fault = secretmem_fault, /* ํ์ด์ง ํดํธ ๋ฐ์ ์ ํธ์ถ๋๋ ํธ๋ค๋ฌ */
};
secretmem_fault()๋ฅผ ํธ์ถํ๋ค.vma->vm_ops == &secretmem_vm_ops๋ก secretmem VMA ์ฌ๋ถ๋ฅผ ํ๋จํ๋ค.`secretmem_fops` โ ํ์ผ ์ฐ์ฐ ํ ์ด๋ธ
// mm/secretmem.c:141-144
static const struct file_operations secretmem_fops = {
.release = secretmem_release, /* fd close ์ ์ฌ์ฉ์ ์ ๊ฐ์ */
.mmap_prepare = secretmem_mmap_prepare, /* mmap ์ค๋น ๋จ๊ณ์์ VMA ์ค์ */
};
mmap_prepare์ Linux 7.0์์ ๋์
๋ ์๋ก์ด mmap ๊ฒฝ๋ก๋ก, VMA ์์ฑ ์ ์ ๊ฒ์ฆ๊ณผ ์ค์ ์ ์ํํ๋ค.`secretmem_aops` โ ์ฃผ์ ๊ณต๊ฐ ์ฐ์ฐ ํ ์ด๋ธ
// mm/secretmem.c:158-162
const struct address_space_operations secretmem_aops = {
.dirty_folio = noop_dirty_folio, /* ๋ํฐ ํธ๋ํน ๋ถํ์ */
.free_folio = secretmem_free_folio, /* ํด์ ์ direct map ๋ณต์ + ์ ๋กํ */
.migrate_folio = secretmem_migrate_folio, /* ๋ง์ด๊ทธ๋ ์ด์
๊ฑฐ๋ถ (-EBUSY) */
};
migrate_folio๊ฐ -EBUSY๋ฅผ ๋ฐํํ๋ ์ด์ : secretmem ํ์ด์ง๋ ์ปค๋์ด ์ง์ ์ ๊ทผํ ์ ์์ผ๋ฏ๋ก ๋ง์ด๊ทธ๋ ์ด์
์ด ๋ถ๊ฐ๋ฅํ๋ค.free_folio์์ set_direct_map_default_noflush()๋ก direct map์ ๋ณต์ํ ๋ค folio_zero_segment()๋ก ๋ด์ฉ์ ์ ๋กํํ๋ค.`secretmem_fs` โ Pseudo ํ์ผ ์์คํ
// mm/secretmem.c:253-257
static struct file_system_type secretmem_fs = {
.name = "secretmem",
.init_fs_context = secretmem_init_fs_context,
.kill_sb = kill_anon_super,
};
memfd_secret์ด ์ฌ์ฉํ๋ ๊ฐ์ ํ์ผ ์์คํ
์ด๋ค.SB_I_NOEXEC | SB_I_NODEV ํ๋๊ทธ๋ก ์คํ/์ฅ์น ์ ๊ทผ์ ์ฐจ๋จํ๋ค.`secretmem_enable` โ ๋ชจ๋ ํ๋ผ๋ฏธํฐ
// mm/secretmem.c:38-41
static bool secretmem_enable __ro_after_init = 1;
module_param_named(enable, secretmem_enable, bool, 0400);
MODULE_PARM_DESC(secretmem_enable,
"Enable secretmem and memfd_secret(2) system call");
__ro_after_init์ผ๋ก ์ด๊ธฐํ ํ ์ฝ๊ธฐ ์ ์ฉ์ด ๋์ด ๋ฐํ์ ๋ณ๊ฒฝ์ ๋ฐฉ์งํ๋ค.CONFIG_SECRETMEM=n์ผ๋ก ์์ ํ ๋นํ์ฑํํ ์๋ ์๋ค.`secretmem_users` โ ํ์ฑ ์ฌ์ฉ์ ์นด์ดํฐ
// mm/secretmem.c:43
static atomic_t secretmem_users;
secretmem_active()๋ก ์ปค๋ ์ ์ฒด์์ secretmem์ด ์ฌ์ฉ ์ค์ธ์ง ํ์ธํ ์ ์๋ค.memfd_secret ์์คํ
ํธ์ถ์์ atomic_read(&secretmem_users) < 0 ๊ฒ์ฌ๋ก ์ค๋ฒํ๋ก์ฐ๋ฅผ ๋ฐฉ์งํ๋ค.ํต์ฌ ํจ์
1. `secretmem_fault()` โ ํ์ด์ง ํดํธ ํธ๋ค๋ฌ
// mm/secretmem.c:50-109
static vm_fault_t secretmem_fault(struct vm_fault *vmf)
์ญํ : secretmem VMA์์ ํ์ด์ง ํดํธ๊ฐ ๋ฐ์ํ์ ๋, ์ folio๋ฅผ ํ ๋นํ๊ณ ์ปค๋ direct map์์ ์ ๊ฑฐํ๋ค.
// mm/secretmem.c:61-100
if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode))
return vmf_error(-EINVAL);
filemap_invalidate_lock_shared(mapping);
retry:
folio = filemap_lock_folio(mapping, offset);
if (IS_ERR(folio)) {
folio = folio_alloc(gfp | __GFP_ZERO, 0);
if (!folio) {
ret = VM_FAULT_OOM;
goto out;
}
err = set_direct_map_invalid_noflush(folio_page(folio, 0));
if (err) {
folio_put(folio);
ret = vmf_error(err);
goto out;
}
__folio_mark_uptodate(folio);
err = filemap_add_folio(mapping, folio, offset, gfp);
if (unlikely(err)) {
/* ํฐ ํ์ด์ง ๋ถํ ์ด ํ์ํ๋ค๋ฉด, ๋ฌดํจํ ํ์ ์์ ์ ์ด๋ฏธ ์ํ๋จ */
set_direct_map_default_noflush(folio_page(folio, 0));
folio_put(folio);
if (err == -EEXIST)
goto retry;
ret = vmf_error(err);
goto out;
}
addr = (unsigned long)folio_address(folio);
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
}
ํ๋ฆ:
1. ํ์ผ ๋ฒ์ ์ด๊ณผ ๊ฒ์ฌ (i_size_read)
2. filemap_lock_folio()๋ก ๊ธฐ์กด folio ํ์
3. ์์ผ๋ฉด folio_alloc(gfp | __GFP_ZERO, 0)๋ก ์ folio ํ ๋น
4. set_direct_map_invalid_noflush()๋ก ์ปค๋ ์ง์ ๋งคํ ์ ๊ฑฐ
5. filemap_add_folio()๋ก ๋งคํ์ ์ถ๊ฐ
6. flush_tlb_kernel_range()๋ก TLB ๋ฌดํจํ
7. ๊ธฐ์กด folio๊ฐ ์์ผ๋ฉด ๊ทธ๋๋ก ๋ฐํ (VM_FAULT_LOCKED)
๋ฐ๋ณต ๋ก์ง: filemap_add_folio()๊ฐ -EEXIST๋ฅผ ๋ฐํํ๋ฉด goto retry๋ก ์ฌ์๋ํ๋ค.
2. `secretmem_mmap_prepare()` โ mmap ์ฌ์ ์ค์
// mm/secretmem.c:121-134
static int secretmem_mmap_prepare(struct vm_area_desc *desc)
์ญํ : mmap ์ VMA ํ๋๊ทธ๋ฅผ ์ค์ ํ๊ณ secretmem ์ ์ฉ vm_ops๋ฅผ ์ฐ๊ฒฐํ๋ค.
// mm/secretmem.c:123-133
const unsigned long len = vma_desc_size(desc);
if (!vma_desc_test_flags(desc, VMA_SHARED_BIT, VMA_MAYSHARE_BIT))
return -EINVAL;
vma_desc_set_flags(desc, VMA_LOCKED_BIT, VMA_DONTDUMP_BIT);
if (!mlock_future_ok(desc->mm, /* VMA ๊ณ ์ ์ฌ๋ถ = */ true, len))
return -EAGAIN;
desc->vm_ops = &secretmem_vm_ops;
return 0;
ํ๋ฆ:
1. VMA_SHARED_BIT | VMA_MAYSHARE_BIT ํ์ธ โ ๊ณต์ ๋งคํ๋ง ํ์ฉ
2. VMA_LOCKED_BIT | VMA_DONTDUMP_BIT ์ค์ โ VMA ๊ณ ์ + ์ฝ์ด ๋คํ ์ ์ธ
3. mlock_future_ok() ํ์ธ โ mlock ํ๋ ์ด๊ณผ ์ -EAGAIN
4. desc->vm_ops = &secretmem_vm_ops ์ฐ๊ฒฐ
์ ์ฝ ์กฐ๊ฑด: secretmem์ ๋ฐ๋์ shared ๋งคํ์ผ๋ก๋ง ์ฌ์ฉํ ์ ์๋ค.
3. `secretmem_file_create()` โ ํ์ผ ์์ฑ
// mm/secretmem.c:190-222
static struct file *secretmem_file_create(unsigned long flags)
์ญํ : memfd_secret ์์คํ
ํธ์ถ์ ํต์ฌ์ผ๋ก, anonymous inode ๊ธฐ๋ฐ ํ์ผ์ ์์ฑํ๋ค.
// mm/secretmem.c:196-215
inode = anon_inode_make_secure_inode(secretmem_mnt->mnt_sb, anon_name, NULL);
if (IS_ERR(inode))
return ERR_CAST(inode);
file = alloc_file_pseudo(inode, secretmem_mnt, "secretmem",
O_RDWR | O_LARGEFILE, &secretmem_fops);
if (IS_ERR(file))
goto err_free_inode;
mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
mapping_set_unevictable(inode->i_mapping);
inode->i_op = &secretmem_iops;
inode->i_mapping->a_ops = &secretmem_aops;
/* zero size์ธ ์ผ๋ฐ ํ์ผ์ฒ๋ผ ๋ณด์ด๊ฒ ์ฒ๋ฆฌ */
inode->i_mode |= S_IFREG;
inode->i_size = 0;
atomic_inc(&secretmem_users);
ํ๋ฆ:
1. anon_inode_make_secure_inode()๋ก ๋ณด์ ์ปจํ
์คํธ๊ฐ ์ ์ฉ๋ anonymous inode ์์ฑ
2. alloc_file_pseudo()๋ก pseudo ํ์ผ ํ ๋น
3. mapping_set_gfp_mask(GFP_HIGHUSER) โ ๊ณ ์ ๋ฉ๋ชจ๋ฆฌ์์๋ง ํ ๋น
4. mapping_set_unevictable() โ ํ์ ๋ถ๊ฐ๋ฅํ๋๋ก ์ค์
5. inode์ secretmem_iops, secretmem_aops ์ฐ๊ฒฐ
6. atomic_inc(&secretmem_users)๋ก ์ฌ์ฉ์ ์ ์ฆ๊ฐ
4. `memfd_secret()` โ ์์คํ ํธ์ถ ์ง์ ์
// mm/secretmem.c:224-238
SYSCALL_DEFINE1(memfd_secret, unsigned int, flags)
์ญํ : ์ฌ์ฉ์ ๊ณต๊ฐ์ memfd_secret(2) ์์คํ
ํธ์ถ์ ์ฒ๋ฆฌํ๋ค.
// mm/secretmem.c:226-237
/* ๋ก์ปฌ flags๊ฐ ์ ์ญ fcntl.h์ ์ถฉ๋ํ์ง ์๋์ง ํ์ธ */
BUILD_BUG_ON(SECRETMEM_FLAGS_MASK & O_CLOEXEC);
if (!secretmem_enable || !can_set_direct_map())
return -ENOSYS;
if (flags & ~(SECRETMEM_FLAGS_MASK | O_CLOEXEC))
return -EINVAL;
if (atomic_read(&secretmem_users) < 0)
return -ENFILE;
return FD_ADD(flags & O_CLOEXEC, secretmem_file_create(flags));
ํ๋ฆ:
1. secretmem_enable ๋ฐ can_set_direct_map() ํ์ธ โ ๋ฏธ์ง์ ์ -ENOSYS
2. ํ๋๊ทธ ์ ํจ์ฑ ๊ฒ์ฆ (mode/flag ๋ง์คํฌ + O_CLOEXEC)
3. secretmem_user ์ ์ค๋ฒํ๋ก์ฐ ๊ฒ์ฌ
4. secretmem_file_create() ํธ์ถ ํ FD_ADD()๋ก fd ๋ฐํ
๋ฐํ: ์ฑ๊ณต ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ, ์คํจ ์ errno.
5. `secretmem_free_folio()` โ folio ํด์
// mm/secretmem.c:152-156
static void secretmem_free_folio(struct folio *folio)
์ญํ : secretmem folio๊ฐ ํด์ ๋ ๋ direct map์ ๋ณต์ํ๊ณ ๋ด์ฉ์ ์ ๋กํํ๋ค.
ํ๋ฆ:
1. set_direct_map_default_noflush() โ ์ปค๋ ์ง์ ๋งคํ ๋ณต์
2. folio_zero_segment() โ ๋ฉ๋ชจ๋ฆฌ ๋ด์ฉ ์์ ์ ๊ฑฐ (๋ฐ์ดํฐ ๋์ถ ๋ฐฉ์ง)
๋ณด์ ์ค์์ฑ: ํด์ ์ ์ ๋กํํ์ง ์์ผ๋ฉด ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ํด๋น ๋ฌผ๋ฆฌ ํ์ด์ง๋ฅผ ํ ๋น๋ฐ์ ์์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์ ์๋ค.
ํธ์ถ ํ๋ฆ
์ฌ์ฉ์ ๊ณต๊ฐ: memfd_secret(O_CLOEXEC)
โ
โผ
SYSCALL_DEFINE1(memfd_secret)
โโ secretmem_enable / can_set_direct_map() ํ์ธ
โโ ํ๋๊ทธ ๊ฒ์ฆ
โโ secretmem_file_create()
โโ anon_inode_make_secure_inode() โ LSM ๋ณด์ ์ปจํ
์คํธ ์ ์ฉ
โโ alloc_file_pseudo() โ pseudo ํ์ผ ํ ๋น
โโ mapping_set_gfp_mask(GFP_HIGHUSER) โ ์ปค๋ ํ ๋น ์ ํ
โโ mapping_set_unevictable() โ ํ์ ๋ถ๊ฐ ์ค์
โโ atomic_inc(secretmem_users)
์ฌ์ฉ์ ๊ณต๊ฐ: mmap(fd, ...)
โ
โผ
secretmem_mmap_prepare()
โโ VMA_SHARED ๊ฒ์ฆ
โโ VM_LOCKED | VM_DONTDUMP ์ค์
โโ mlock_future_ok() ํ์ธ
โโ vm_ops = &secretmem_vm_ops
์ฌ์ฉ์ ๊ณต๊ฐ: ์ ๊ทผ (ํ์ด์ง ํดํธ)
โ
โผ
secretmem_fault()
โโ filemap_lock_folio() ํ์
โโ [์์ผ๋ฉด] folio_alloc(__GFP_ZERO)
โโ set_direct_map_invalid_noflush() โ ์ปค๋ ๋งคํ ์ ๊ฑฐ
โโ filemap_add_folio() โ ๋งคํ์ ์ถ๊ฐ
โโ flush_tlb_kernel_range() โ TLB ๋ฌดํจํ
GUP ๊ฒฝ๋ก (์ปค๋ ์ง์ ์ ๊ทผ ์ฐจ๋จ):
โโ vma_is_secretmem(vma) โ -EFAULT โ gup.c:1219
โโ secretmem_mapping(mapping) โ false โ gup_fast_folio_allowed():2803
ํด์ ์:
close(fd)
โโ secretmem_release()
โโ atomic_dec(secretmem_users)
folio ํด์ ์:
secretmem_free_folio()
โโ set_direct_map_default_noflush() โ direct map ๋ณต์
โโ folio_zero_segment() โ ๋ฐ์ดํฐ ์ ๋กํ
์กฐ๊ฑด๋ณ ๋น๊ต
memfd_secret ํ๋๊ทธ๋ณ ๋์
| ํ๋๊ทธ | ํ์ฉ ์ฌ๋ถ | ์ค๋ช |
|---|---|---|
| `O_CLOEXEC` | ํ์ฉ | exec() ์ fd ์๋ ๋ซ๊ธฐ |
| `O_RDWR` | ํ์ฉ (๊ธฐ๋ณธ๊ฐ) | ์ฝ๊ธฐ/์ฐ๊ธฐ ๋ชจ๋ |
| ๊ธฐํ flags | ๊ฑฐ๋ถ (`-EINVAL`) | mode ํ๋๊ทธ๋ ํ์ฌ ๋ฏธ์ฌ์ฉ (0x0) |
์ํคํ ์ฒ๋ณ direct map ์ ์ด ์ง์
| ์ํคํ ์ฒ | `can_set_direct_map()` | `set_direct_map_invalid_noflush()` | ๋น๊ณ |
|---|---|---|---|
| x86_64 | `true` (๊ธฐ๋ณธ๊ฐ) | `__set_pages_np()` | ์์ ์ง์ |
| ARM64 | ์กฐ๊ฑด๋ถ | ์กฐ๊ฑด๋ถ | `rodata_full` ๋๋ KFENCE ๋๋ Realm |
| RISC-V | `true` (๊ธฐ๋ณธ๊ฐ) | ์ง์ | ๊ธฐ๋ณธ ์ง์ |
| s390 | `true` (๊ธฐ๋ณธ๊ฐ) | ์ง์ | ๊ธฐ๋ณธ ์ง์ |
| LoongArch | `true` (๊ธฐ๋ณธ๊ฐ) | ์ง์ | ๊ธฐ๋ณธ ์ง์ |
GUP ๊ฒฝ๋ก์์์ secretmem ์ฒ๋ฆฌ
| ๊ฒฝ๋ก | ๋์ | ์ฝ๋ ์์น |
|---|---|---|
| GUP (slow path) | `vma_is_secretmem()` โ `-EFAULT` ๋ฐํ | `gup.c:1219` |
| GUP-fast (order-0 folio) | `secretmem_mapping()` โ `false` ๋ฐํ (๊ฑฐ๋ถ) | `gup.c:2803` |
| GUP-fast (large folio) | ๊ฒ์ฌ ๊ฑด๋๋ (secretmem์ order-0๋ง ์ฌ์ฉ) | `gup.c:2756` |
| GUP-fast (hugetlb) | ๊ฑด๋๋ (secretmem ๋ถ๊ฐ) | `gup.c:2766` |
secretmem vs ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ๊ฒฉ๋ฆฌ ๋ฉ์ปค๋์ฆ
| ํน์ฑ | Secret Memory | mlock | memfd_create | sealed memfd |
|---|---|---|---|---|
| ์ปค๋ ์ง์ ๋งคํ ์ ๊ฑฐ | **์** | ์๋์ค | ์๋์ค | ์๋์ค |
| GUP ์ฐจ๋จ | **์** | ์๋์ค | ์๋์ค | ์๋์ค |
| ํ์ ๋ถ๊ฐ | **์** | ์๋์ค | ์๋์ค | ์๋์ค |
| ์ฝ์ด ๋คํ ์ ์ธ | **์** | ์๋์ค | ์๋์ค | ์๋์ค |
| LSM ๋ณด์ ์ปจํ ์คํธ | **์** | ์๋์ค | ์๋์ค | ์๋์ค |
| ์ฌ์ฉ ์ฌ๋ก | ์ํธํ ํค ์ ์ฅ | ์ค์ ๋ฐฉ์ง | ์์ ํ์ผ | ๋ฆฌ์์ค ๋ณดํธ |
ํธ์ถ ํ๋ฆ ๋ค์ด์ด๊ทธ๋จ
์๋ฃ๊ตฌ์กฐ ๊ด๊ณ๋
๊ด๋ จ ๋ฌธ์
์ฐธ๊ณ ์๋ฃ
mm/secretmem.c (์ ์ฒด 270์ค โ ๋น๊ต์ ์๊ณ ์ง์ค์ ์ธ ๊ตฌํ)Documentation/mm/secretmem.rstmemfd_secret(2) man pageanon_inode_make_secure_inode()๋ฅผ ํตํ SELinux/AppArmor ์ปจํ
์คํธ ์ ์ฉ