unshare(2) - wariua/manpages-ko GitHub Wiki
unshare - νλ‘μΈμ€ μ€ν λ¬Έλ§₯ μΌλΆλ₯Ό λΆλ¦¬νκΈ°
#define _GNU_SOURCE
#include <sched.h>
int unshare(int flags);
unshare()
λ₯Ό ν΅ν΄ νλ‘μΈμ€(λλ μ€λ λ)κ° νμ¬ λ€λ₯Έ νλ‘μΈμ€(λλ μ€λ λ)μ 곡μ μ€μΈ μ€ν λ¬Έλ§₯ μΌλΆλ₯Ό λΆλ¦¬μν¬ μ μλ€. μ€ν λ¬Έλ§₯ μ€μμ λ§μ΄νΈ λ€μμ€νμ΄μ€ κ°μ μμλ fork(2)λ vfork(2)λ‘ μ νλ‘μΈμ€λ₯Ό λ§λ€ λ μ묡μ μΌλ‘ 곡μ λμ§λ§ κ°μ λ©λͺ¨λ¦¬ κ°μ λ€λ₯Έ μμλ clone(2)μΌλ‘ νλ‘μΈμ€ λ΄μ§ μ€λ λλ₯Ό λ§λ€ λ λͺ
μμ μΌλ‘ μμ²ν΄μ 곡μ ν μ μλ€.
unshare()
μ μ£Όλ μ©λλ νλ‘μΈμ€κ° μ νλ‘μΈμ€λ₯Ό λ§λ€μ§ μκ³ λ μκΈ° 곡μ μ€ν λ¬Έλ§₯μ μ μ΄ν μ μκ² νλ κ²μ΄λ€.
flags
μΈμλ μ€ν λ¬Έλ§₯μ μ΄λ μμλ€μ 곡μ ν΄μ ν μ§ μ§μ νλ λΉνΈ λ§μ€ν¬μ΄λ€. λ€μ μμλ€μ 0κ° μ΄μ OR ν΄μ μΈμλ₯Ό μ§μ νλ€.
CLONE_FILES
-
clone(2)
CLONE_FILES
νλκ·Έμ ν¨κ³Όλ₯Ό λ€μ§λλ€. νμΌ λμ€ν¬λ¦½ν° ν μ΄λΈμ 곡μ ν΄μ ν΄μ νΈμΆ νλ‘μΈμ€κ° λ μ΄μ λ€λ₯Έ νλ‘μΈμ€μ νμΌ λμ€ν¬λ¦½ν°λ₯Ό 곡μ νμ§ μκ² νλ€. CLONE_FS
-
clone(2)
CLONE_FS
νλκ·Έμ ν¨κ³Όλ₯Ό λ€μ§λλ€. νμΌ μμ€ν μμ±λ€μ 곡μ ν΄μ ν΄μ νΈμΆ νλ‘μΈμ€κ° λ μ΄μ λ€λ₯Έ νλ‘μΈμ€μ λ£¨νΈ λλ ν°λ¦¬(chroot(2)), νμ¬ λλ ν°λ¦¬(chdir(2)
), umask(umask(2)) μμ±μ 곡μ νμ§ μκ² νλ€. -
CLONE_NEWCGROUP
(리λ μ€ 4.6λΆν°) -
μ΄ νλκ·Έλ clone(2)
CLONE_NEWCGROUP
νλκ·Έμ ν¨κ³Όκ° κ°λ€. cgroup λ€μμ€νμ΄μ€λ₯Ό 곡μ ν΄μ νλ€.CLONE_NEWCGROUP
μ μ¬μ©νλ €λ©΄CAP_SYS_ADMIN
μλ₯μ΄ νμνλ€. -
CLONE_NEWIPC
(리λ μ€ 2.6.19λΆν°) -
μ΄ νλκ·Έλ clone(2)
CLONE_NEWIPC
νλκ·Έμ ν¨κ³Όκ° κ°λ€. IPC λ€μμ€νμ΄μ€λ₯Ό 곡μ ν΄μ ν΄μ νΈμΆ νλ‘μΈμ€κ° λ€λ₯Έ νλ‘μΈμ€μ 곡μ νμ§ μλ IPC λ€μμ€νμ΄μ€μ κ°λ³ μ¬λ³Έμ κ°μ§λλ‘ νλ€. μ΄ νλκ·Έ μ§μ μ μλμΌλ‘CLONE_SYSVSEM
κΉμ§ ν¨μνλ€.CLONE_NEWIPC
λ₯Ό μ¬μ©νλ €λ©΄CAP_SYS_ADMIN
μλ₯μ΄ νμνλ€. -
CLONE_NEWNET
(리λ μ€ 2.6.24λΆν°) -
μ΄ νλκ·Έλ clone(2)
CLONE_NEWNET
νλκ·Έμ ν¨κ³Όκ° κ°λ€. λ€νΈμν¬ λ€μμ€νμ΄μ€λ₯Ό 곡μ ν΄μ ν΄μ νΈμΆ νλ‘μΈμ€κ° κΈ°μ‘΄ μ΄λ νλ‘μΈμ€μλ 곡μ νμ§ μλ μ λ€νΈμν¬ λ€μμ€νμ΄μ€λ‘ μ΄λνκ² νλ€.CLONE_NEWNET
μ μ¬μ©νλ €λ©΄CAP_SYS_ADMIN
μλ₯μ΄ νμνλ€. CLONE_NEWNS
-
μ΄ νλκ·Έλ clone(2)
CLONE_NEWNS
νλκ·Έμ ν¨κ³Όκ° κ°λ€. λ§μ΄νΈ λ€μμ€νμ΄μ€λ₯Ό 곡μ ν΄μ ν΄μ νΈμΆ νλ‘μΈμ€κ° λ€λ₯Έ νλ‘μΈμ€μ 곡μ νμ§ μλ κ·Έ λ€μμ€νμ΄μ€μ κ°λ³ μ¬λ³Έμ κ°μ§λλ‘ νλ€. μ΄ νλκ·Έ μ§μ μ μλμΌλ‘CLONE_FS
κΉμ§ ν¨μνλ€.CLONE_NEWNS
λ₯Ό μ¬μ©νλ €λ©΄CAP_SYS_ADMIN
μλ₯μ΄ νμνλ€. μΆκ° λ΄μ©μ mount_namespaces(7) μ°Έκ³ . -
CLONE_NEWPID
(리λ μ€ 3.8λΆν°) -
μ΄ νλκ·Έλ clone(2)
CLONE_NEWPID
νλκ·Έμ ν¨κ³Όκ° κ°λ€. PID λ€μμ€νμ΄μ€λ₯Ό 곡μ ν΄μ ν΄μ νΈμΆ νλ‘μΈμ€κ° κΈ°μ‘΄ μ΄λ νλ‘μΈμ€μλ 곡μ νμ§ μλ μμλ€μ μν μ PID λ€μμ€νμ΄μ€λ₯Ό κ°μ§λλ‘ νλ€. νΈμΆ νλ‘μΈμ€κ° μ λ€μμ€νμ΄μ€λ‘ μ΄λνμ§ μλλ€. νΈμΆ νλ‘μΈμ€κ° μμ±νλ 첫 λ²μ§Έ μμμ΄ νλ‘μΈμ€ ID 1μ κ°μ§κ² λμ΄ κ·Έ μ λ€μμ€νμ΄μ€μμinit(1)
μ μν μ λ§‘λλ€.CLONE_NEWPID
λ μλμΌλ‘CLONE_THREAD
κΉμ§ ν¨μνλ€.CLONE_NEWPID
λ₯Ό μ¬μ©νλ €λ©΄CAP_SYS_ADMIN
μλ₯μ΄ νμνλ€. μΆκ° λ΄μ©μ pid_namespaces(7) μ°Έκ³ . -
CLONE_NEWUSER
(리λ μ€ 3.8λΆν°) -
μ΄ νλκ·Έλ clone(2)
CLONE_NEWUSER
νλκ·Έμ ν¨κ³Όκ° κ°λ€. μ¬μ©μ λ€μμ€νμ΄μ€λ₯Ό 곡μ ν΄μ ν΄μ νΈμΆ νλ‘μΈμ€κ° κΈ°μ‘΄ μ΄λ νλ‘μΈμ€μλ 곡μ νμ§ μλ μ μ¬μ©μ λ€μμ€νμ΄μ€λ‘ μ΄λνκ² νλ€.CLONE_NEWUSER
νλκ·Έλ₯Ό μ΄ clone(2)μΌλ‘ μμ±νλ μμ νλ‘μΈμ€μμμ²λΌ νΈμΆμκ° μ λ€μμ€νμ΄μ€μμ μμ ν μλ₯ μ§ν©μ μ»λλ€.CLONE_NEWUSER
λ₯Ό μν΄μ νΈμΆ νλ‘μΈμ€κ° λ€μ€ μ€λ λκ° μλμ΄μΌ νλ€.CLONE_NEWUSER
μ§μ μ μλμΌλ‘CLONE_THREAD
λ₯Ό ν¨μνλ€. 리λ μ€ 3.9λΆν°CLONE_NEWUSER
κ° μλμΌλ‘CLONE_FS
λ₯Ό ν¨μνκΈ°λ νλ€.CLONE_NEWUSER
λ₯Ό μν΄μ νΈμΆ νλ‘μΈμ€μ μ¬μ©μ ID λ° κ·Έλ£Ή IDκ° νΈμΆ μμ μ νΈμΆ νλ‘μΈμ€ μ¬μ©μ λ€μμ€νμ΄μ€ λ΄μ μ¬μ©μ ID λ° κ·Έλ£Ή IDλ‘ λ§€ν λμ΄ μμ΄μΌ νλ€.μ¬μ©μ λ€μμ€νμ΄μ€μ λν μΆκ° λ΄μ©μ user_namespaces(7) μ°Έκ³ .
-
CLONE_NEWUTS
(리λ μ€ 2.6.19λΆν°) -
μ΄ νλκ·Έλ clone(2)
CLONE_NEWUTS
νλκ·Έμ ν¨κ³Όκ° κ°λ€. UTS λ€μμ€νμ΄μ€λ₯Ό 곡μ ν΄μ ν΄μ νΈμΆ νλ‘μΈμ€κ° λ€λ₯Έ νλ‘μΈμ€μ 곡μ νμ§ μλ UTS λ€μμ€νμ΄μ€μ κ°λ³ μ¬λ³Έμ κ°μ§λλ‘ νλ€.CLONE_NEWUTS
λ₯Ό μ¬μ©νλ €λ©΄CAP_SYS_ADMIN
μλ₯μ΄ νμνλ€. -
CLONE_SYSVSEM
(리λ μ€ 2.6.26λΆν°) -
μ΄ νλκ·Έλ clone(2)
CLONE_SYSVSEM
νλκ·Έμ ν¨κ³Όλ₯Ό λ€μ§λλ€. μμ€ν V μΈλ§ν¬μ΄ μ‘°μ (semadj
) κ°λ€μ 곡μ ν΄μ ν΄μ νΈμΆ νλ‘μΈμ€κ° λ€λ₯Έ νλ‘μΈμ€μ 곡μ νμ§ μλ μλ‘μ΄ λΉsemadj
λͺ©λ‘μ κ°μ§λλ‘ νλ€. μ΄ νλ‘μΈμ€κ° νμ¬semadj
λͺ©λ‘μ λν μ°Έμ‘°λ₯Ό κ°μ§ λ§μ§λ§ νλ‘μΈμ€μ΄λ©΄ κ·Έ λͺ©λ‘μ μ‘°μ μ¬νλ€μ΄ semop(2)μμ κΈ°μ νλ λλ‘ ν΄λΉ μΈλ§ν¬μ΄λ€μ μ μ©λλ€.
μΆκ°λ‘ νΈμΆμκ° λ¨μΌ μ€λ λμ΄λ©΄ (μ¦ λ€λ₯Έ νλ‘μΈμ€ λ΄μ§ μ€λ λμ μ£Όμ 곡κ°μ 곡μ νκ³ μμ§ μμΌλ©΄) flags
μ CLONE_THREAD
, CLONE_SIGHAND
, CLONE_VM
μ μ§μ ν μ μλ€. κ·Έ κ²½μ°μ κ·Έ νλκ·Έλ€μ ν¨κ³Όκ° μλ€. (κ·Έλ¦¬κ³ CLONE_THREAD
μ§μ μ΄ μλμΌλ‘ CLONE_VM
μ ν¨μνκ³ CLONE_VM
μ§μ μ΄ μλμΌλ‘ CLONE_SIGHAND
λ₯Ό ν¨μνκΈ°λ νλ€.) νλ‘μΈμ€κ° λ€μ€ μ€λ λμΈ κ²½μ°μλ μ΄ νλκ·Έ μ¬μ© μ μ€λ₯ κ²°κ³Όκ° λμ¨λ€.
flags
λ₯Ό 0μΌλ‘ μ§μ νλ κ²½μ° unshare()
λ no-opμ΄λ€. νμ¬ νλ‘μΈμ€μ μ€ν λ¬Έλ§₯μ μ΄λ€ λ³κ²½λ νμ§ μλλ€.
μ±κ³΅ μ 0μ λ°ννλ€. μ€ν¨ μ -1μ λ°ννλ©° μ€λ₯λ₯Ό λνλ΄λλ‘ errno
λ₯Ό μ€μ νλ€.
EINVAL
-
flags
μ μ ν¨νμ§ μμ λΉνΈλ₯Ό μ§μ νλ€. EINVAL
-
flags
μCLONE_THREAD
λCLONE_SIGHAND
,CLONE_VM
μ μ§μ νμΌλ©° νΈμΆμκ° λ€μ€ μ€λ λμ΄λ€. EINVAL
-
flags
μCLONE_NEWIPC
λ₯Ό μ§μ νλλ° μ»€λμ΄CONFIG_SYSVIPC
λ°CONFIG_IPC_NS
μ΅μ μΌλ‘ ꡬμ±λμ§ μμλ€. EINVAL
-
flags
μCLONE_NEWNET
λ₯Ό μ§μ νλλ° μ»€λμ΄CONFIG_NET_NS
μ΅μ μΌλ‘ ꡬμ±λμ§ μμλ€. EINVAL
-
flags
μCLONE_NEWPID
λ₯Ό μ§μ νλλ° μ»€λμ΄CONFIG_PID_NS
μ΅μ μΌλ‘ ꡬμ±λμ§ μμλ€. EINVAL
-
flags
μCLONE_NEWUSER
λ₯Ό μ§μ νλλ° μ»€λμ΄CONFIG_USER_NS
μ΅μ μΌλ‘ ꡬμ±λμ§ μμλ€. EINVAL
-
flags
μCLONE_NEWUTS
λ₯Ό μ§μ νλλ° μ»€λμ΄CONFIG_UTS_NS
μ΅μ μΌλ‘ ꡬμ±λμ§ μμλ€. EINVAL
-
flags
μCLONE_NEWPID
λ₯Ό μ§μ νλλ° νλ‘μΈμ€κ° μμCLONE_NEWPID
νλκ·Έλ‘unshare()
λ₯Ό νΈμΆνλ€. ENOMEM
- 곡μ ν΄μ ν΄μΌ νλ νΈμΆμμ λ¬Έλ§₯ μμλ€μ 볡μ¬ν μΆ©λΆν λ©λͺ¨λ¦¬λ₯Ό ν λΉν μ μλ€.
-
ENOSPC
(리λ μ€ 3.7λΆν°) -
flags
μCLONE_NEWPID
λ₯Ό μ§μ νλλ° PID λ€μμ€νμ΄μ€ μ€μ²© κΉμ΄ μ νμ μ΄κ³Όνκ² λμλ€. pid_namespaces(7) μ°Έκ³ . -
ENOSPC
(리λ μ€ 4.9λΆν°. μ μλEUSERS
) -
flags
μCLONE_NEWUSER
λ₯Ό μ§μ νλλ° μ€μ²© μ¬μ©μ λ€μμ€νμ΄μ€ μ μ νμ μ΄κ³Όνκ² λμλ€. user_namespaces(7) μ°Έκ³ .리λ μ€ 3.11λΆν° 리λ μ€ 4.8κΉμ§μμλ μ΄ κ²½μ° μ§λ¨ μ€λ₯κ°
EUSERS
μλ€. -
ENOSPC
(리λ μ€ 4.9λΆν°) -
flags
μ ν κ°μ΄ μ μ¬μ©μ λ€μμ€νμ΄μ€ μμ±μ λνλ΄μ§λ§ κ·Έλ κ² νλ©΄/proc/sys/user
μμ λμ νμΌμ κ·μ λ μ νμ μ΄κ³Όνκ² λλ€. μμΈν λ΄μ©μ namespaces(7) μ°Έκ³ . EPERM
- νΈμΆ νλ‘μΈμ€κ° μ΄ λμμ νμν νΉκΆμ κ°μ§κ³ μμ§ μλ€.
EPERM
-
flags
μCLONE_NEWUSER
λ₯Ό μ§μ νλλ° νΈμΆμμ μ€ν¨ μ¬μ©μ IDλ μ€ν¨ κ·Έλ£Ή ID μ€ νλκ° λΆλͺ¨ λ€μμ€νμ΄μ€μ λ§€ν λμ΄ μμ§ μλ€. (user_namespaces(7) μ°Έκ³ .) -
EPERM
(리λ μ€ 3.9λΆν°) -
flags
μCLONE_NEWUSER
λ₯Ό μ§μ νλλ° νΈμΆμκ° chroot νκ²½ μμ μλ€. (μ¦, νΈμΆμμ λ£¨νΈ λλ ν°λ¦¬κ° νΈμΆμκ° μμΉν λ§μ΄νΈ λ€μμ€νμ΄μ€μ λ£¨νΈ λλ ν°λ¦¬μ μΌμΉνμ§ μλλ€.) -
EUSERS
(리λ μ€ 3.11λΆν° 리λ μ€ 4.8κΉμ§) -
flags
μCLONE_NEWUSER
λ₯Ό μ§μ νλλ° μ€μ²© μ¬μ©μ λ€μμ€νμ΄μ€ μ μ νμ μ΄κ³Όνκ² λμλ€. μμENOSPC
μ€λ₯ λ Όμ μ°Έκ³ .
리λ
μ€ μ»€λ 2.6.16μμ unshare()
μμ€ν
νΈμΆμ΄ μΆκ°λμλ€.
unshare()
μμ€ν
νΈμΆμ 리λ
μ€ μ μ©μ΄λ€.
clone(2)μΌλ‘ μ νλ‘μΈμ€λ₯Ό μμ±ν λ 곡μ ν μ μλ νλ‘μΈμ€ μμ±λ€μ λͺ¨λ unshare()
λ‘ κ³΅μ ν΄μ ν μ μλ 건 μλλ€. ꡬ체μ μΌλ‘ 컀λ 3.8 νμ¬ unshare()
λ CLONE_SIGHAND
, CLONE_THREAD
, CLONE_VM
μ ν¨κ³Όλ₯Ό λ€μ§λ νλκ·Έλ₯Ό ꡬννκ³ μμ§ μλ€. νμνλ©΄ ν₯ν κ·Έλ° κΈ°λ₯μ΄ μΆκ°λ μλ μλ€.
μλ νλ‘κ·Έλ¨μ unshare(1)
λͺ
λ Ήμ κ°λ¨νκ² κ΅¬νν κ²μ΄λ€. λ€μμ€νμ΄μ€ ν κ°μ§ λλ κ·Έ μ΄μμ 곡μ ν΄μ νκ³ λͺ
λ Ήν μΈμλ‘ λ°μ λͺ
λ Ήμ μ€ννλ€. λ€μμ μ΄ νλ‘κ·Έλ¨ μ¬μ© μμμΈλ°, μ λ§μ΄νΈ λ€μμ€νμ΄μ€μμ μ
Έμ μ€ννκ³ μ μλ μ
Έκ³Ό μ μ
Έμ΄ λΆλ¦¬λ λ§μ΄νΈ λ€μμ€νμ΄μ€μ μλμ§ νμΈνλ€.
$ readlink /proc/$$/ns/mnt
mnt:[4026531840]
$ sudo ./unshare -m /bin/bash
# readlink /proc/$$/ns/mnt
mnt:[4026532325]
λ readlink(1)
λͺ
λ Ή μΆλ ₯μ΄ λ€λ₯Έλ°, μ΄λ λ μ
Έμ΄ λ€λ₯Έ λ§μ΄νΈ λ€μμ€νμ΄μ€μ μμμ λ³΄μ¬ μ€λ€.
/* unshare.c
κ°λ¨ν unshare(1) λͺ
λ Ή ꡬν: λ€μμ€νμ΄μ€λ₯Ό unshare νκ³
λͺ
λ Ήμ μ€ν
*/
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
/* κ°λ¨ν μ€λ₯ μ²λ¦¬ ν¨μ: 'errno'μ κ°μ λ°λΌ μ€λ₯ λ©μμ§λ₯Ό
μ°κ³ νΈμΆ νλ‘μΈμ€ μ’
λ£ */
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
static void
usage(char *pname)
{
fprintf(stderr, "Usage: %s [options] program [arg...]\n", pname);
fprintf(stderr, "Options can be:\n");
fprintf(stderr, " -i unshare IPC namespace\n");
fprintf(stderr, " -m unshare mount namespace\n");
fprintf(stderr, " -n unshare network namespace\n");
fprintf(stderr, " -p unshare PID namespace\n");
fprintf(stderr, " -u unshare UTS namespace\n");
fprintf(stderr, " -U unshare user namespace\n");
exit(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{
int flags, opt;
flags = 0;
while ((opt = getopt(argc, argv, "imnpuU")) != -1) {
switch (opt) {
case 'i': flags |= CLONE_NEWIPC; break;
case 'm': flags |= CLONE_NEWNS; break;
case 'n': flags |= CLONE_NEWNET; break;
case 'p': flags |= CLONE_NEWPID; break;
case 'u': flags |= CLONE_NEWUTS; break;
case 'U': flags |= CLONE_NEWUSER; break;
default: usage(argv[0]);
}
}
if (optind >= argc)
usage(argv[0]);
if (unshare(flags) == -1)
errExit("unshare");
execvp(argv[optind], &argv[optind]);
errExit("execvp");
}
unshare(1)
, clone(2), fork(2), kcmp(2), setns(2), vfork(2), namespaces(7)
리λ
μ€ μ»€λ μμ€ νΈλ¦¬μ Documentation/userspace-api/unshare.rst
(리λ
μ€ 4.12 μ μλ Documentation/unshare.txt
)
2019-03-06