μλ ,
μ°μ , libseccompμ κ°μ¬λ립λλ€. μ°λ¦¬λ μ§κΈκΉμ§ λͺ λ λμ νλ‘λμ νκ²½μμ ν볡νκ² μ¬μ©νμΌλ©° μ΄λ€ λ¬Έμ λ λ°μνμ§ μμμ΅λλ€(μ§κΈκΉμ§). μ΄κ²μ΄ μ°λ¦¬ μ½λμ λ²κ·ΈμΈμ§, λ¬Έμμ λν μ€ν΄μΈμ§, μλλ©΄ λ€λ₯Έ κ²μΈμ§ νμ€νμ§ μμ΅λλ€. νμ§λ§ μ§λ ν λ¬ λμ μ΄κ²μ μΆμ νλ €κ³ λ Έλ ₯νμ§λ§ μ무 μμ©μ΄ μμμ΅λλ€.
μ΅κ·Όμ libseccomp 2.3.3(Debian μμ μ μ₯μ λ²μ )μμ 2.4.3μΌλ‘μ μ κ·Έλ μ΄λκ° ν¬ν¨λ Docker 컨ν μ΄λμ ν¨ν€μ§λ₯Ό μ κ·Έλ μ΄λνμ΅λλ€. λ€λ₯Έ μμ€ν ν¨ν€μ§λ μ κ·Έλ μ΄λλμμ§λ§ κΈ°λ‘νμ§ μμμ΅λλ€. μ°λ¦¬ 컀λμ μ κ·Έλ μ΄λλμ§ μμμΌλ©° λ²μ μ 4.19.0-8-amd64μ λλ€.
μ°λ¦¬λ SCMP_ACT_TRACE
λ₯Ό μ¬μ©νκ³ libseccompμ μμ¬ λ²νΈκ° μλ κΈ°λ³Έ μμ€ν
νΈμΆ λ²νΈλ₯Ό μ¬μ©νμ¬ μΆκ°λ SCMP_ACT_ALLOW
κ·μΉλ§μΌλ‘ ꡬμ±λ νν°λ₯Ό λΉλν©λλ€. exec
μ μ seccomp νν°λ₯Ό λΉλνκ³ λ‘λνλ 64λΉνΈ λμ°λ―Έ νλ‘μΈμ€λ₯Ό λΆκΈ°νμ¬ λ€λ₯Έ 64λΉνΈ λ°μ΄λ리λ₯Ό μμ±ν©λλ€.
μ°Έκ³ λ‘ μ΄κ²μ seccomp_rule_add
맀λ΄μΌ νμ΄μ§ μ μ μ¬ν μ€λ₯ κ²μ¬λ₯Ό μ¬μ©νλ seccomp μ΄κΈ°ν ββλ£¨ν΄ μ 체μ
λλ€.
κ·Έλ¬λ seccomp_load
λν νΈμΆμ 1/100,000 νλ‘μΈμ€ μ΄κΈ°ν κ·λͺ¨μ μμλ‘ -EINVAL
λ°ννκΈ° μμνμ΅λλ€. (κ·Έκ²μ μμ μ μΌλ‘ μ¬νν μ μκΈ° λλ¬Έμ λλ²κ·ΈνκΈ°κ° μ§λ£¨νμ΅λλ€.) μ΄ μκ° λμ μ°λ¦¬ μ ν리μΌμ΄μ
μ μ½λ λ³κ²½ μ¬νμ΄ μμμ΅λλ€. νν°μ μΆκ°λ μμ€ν
νΈμΆμ λͺ¨λ μ€νμμ λμΌν©λλ€.
무μμ΄ μλͺ»λ μ μλμ§(λλ 무μμ΄ μλͺ»λκ³ μλμ§ μμΈν μμ보λ λ°©λ²), λλ μ΄κ²μ΄ μ΄λ€ μμΌλ‘λ μμλλ κ²½μ°μ λν μμ΄λμ΄κ° μμ΅λκΉ? μλμ μΌλ‘ μμ§μ΄λ λΆλΆμ΄ λ§μ§ μμΌλ©° λ¬Έμμμ μ μ΄λ° μΌμ΄ λ°μν μ μλμ§μ λν λ΄μ©μ μ°Ύμ μ μμ΅λλ€.
μλ νμΈμ @Xyene λ
seccomp_load() μ½λ κ²½λ‘μμ -EINVALμ λ°ννλ κ³³μ λ§μ§ μμ΅λλ€. libseccomp v2.4.3 μ½λμ λν λΉ λ₯Έ κ²μ¬μ λ°λ₯΄λ©΄ μλͺ»λ scmp_filter_ctx
λλ νν°λ₯Ό λ‘λνλ prctl(...)
νΈμΆμ λν΄ λΆννλ 컀λ λλ¬ΈμΈ κ²μΌλ‘ 보μ
λλ€.
v2.4.3μ΄ μΌλ°μ μΌλ‘ μλνκ³ μ»€λμ λ³κ²½νμ§ μμ κ²μ κ³ λ €νλ©΄ prctl(...)
νΈμΆμ΄ μ ν¨νμ§ μμ νν° μ»¨ν
μ€νΈλ‘ μ΄λλ μμΈμΈμ§ μμ¬μ€λ½μ΅λλ€. μ
κ·Έλ μ΄λ μ΄ν νλ‘κ·Έλ¨μμ λ€λ₯Έ μ΄μν λμμ λ°κ²¬νμ
¨μ΅λκΉ? λ€λ₯Έ κ³³μ λ¬Έμ λ₯Ό μΌμΌν€λ λ©λͺ¨λ¦¬ μμ λ¬Έμ κ° μλμ§ κΆκΈν©λλ€.
libseccompμ μ€λ₯κ° μμ μ μμ§λ§ λͺ¨λ νκ· ν μ€νΈμ λν valgrind μ€νκ³Ό clang λ° Coverityλ₯Ό ββλͺ¨λ μ¬μ©νλ μ μ λΆμμ ν¬ν¨νλ μΌλ ¨μ κ²μ¬λ₯Ό ν΅ν΄ κ° λ¦΄λ¦¬μ€λ₯Ό μ€νν©λλ€.
λν μ΄κ²μ v2.4.3μμλ λμμ΄ λμ§ μμ§λ§ κ±°μ μ€λΉλ v2.5.0 릴리μ€μμ λͺ©νλ‘ νλ κ°μ μ¬ν μ€ νλλ λ¬Έμν λ° μ€λ₯ μ½λ μ²λ¦¬ κ°μ μ λλ€.
μ΅κ·Όμ libseccomp 2.3.3(Debian μμ μ μ₯μ λ²μ )μμ 2.4.3μΌλ‘μ μ κ·Έλ μ΄λκ° ν¬ν¨λ Docker 컨ν μ΄λμ ν¨ν€μ§λ₯Ό μ κ·Έλ μ΄λνμ΅λλ€. λ€λ₯Έ μμ€ν ν¨ν€μ§λ μ κ·Έλ μ΄λλμμ§λ§ κΈ°λ‘νμ§ μμμ΅λλ€. μ°λ¦¬ 컀λμ μ κ·Έλ μ΄λλμ§ μμμΌλ©° λ²μ μ 4.19.0-8-amd64μ λλ€.
μ½λμ κΈ°λ³Έ 컀λμ΄ λ³κ²½λμ§ μμλμ§ νμΈν΄μ£Όμ μ κ°μ¬ν©λλ€. λ¬Έμ λ₯Ό μΆμ νλ λ° λμμ΄ λ©λλ€.
μ°Έκ³ λ‘ μ΄κ²μ
seccomp_rule_add
맀λ΄μΌ νμ΄μ§ μ μ μ¬ν μ€λ₯ κ²μ¬λ₯Ό μ¬μ©νλ seccomp μ΄κΈ°ν ββλ£¨ν΄ μ 체μ λλ€.
λΉμ μ νν°λ λμκ² ν©λ¦¬μ μΌλ‘ 보μ λλ€.
무μμ΄ μλͺ»λ μ μλμ§(λλ 무μμ΄ μλͺ»λκ³ μλμ§ μμΈν μμ보λ λ°©λ²), λλ μ΄κ²μ΄ μ΄λ€ μμΌλ‘λ μμλλ κ²½μ°μ λν μμ΄λμ΄κ° μμ΅λκΉ? μλμ μΌλ‘ μμ§μ΄λ λΆλΆμ΄ λ§μ§ μμΌλ©° λ¬Έμμμ μ μ΄λ° μΌμ΄ λ°μν μ μλμ§μ λν λ΄μ©μ μ°Ύμ μ μμ΅λλ€.
v2.4.3 seccomp_load()
μ½λλ₯Ό μ΄ν΄λ³΄λ libseccompκ° -EINVAL
μ λ°ν μ½λλ₯Ό μμ±νλ κ³³μ΄ λ κ³³λΏμΈ κ² κ°μ΅λλ€.
seccomp_load()
283ν_gen_bpf_build_bpf()
λΌμΈ 1657μμ λ μ€λ₯λ λͺ¨λ μ ν¨νμ§ μμ νν°λ‘ μΈν΄ λ°μν©λλ€. λΉμ μ νν° μ½λλ₯Ό κΈ°λ°μΌλ‘ ν κ² κ°μ§ μμ΅λλ€.
seccomp_set_mode_filter()
μλ 컀λμ κΈ°λ³Έ λ°ν κ° μ -EINVAL
μ΄λ―λ‘ μμ€ν
μ λ€λ₯Έ νλͺ©μ΄ λ³κ²½λμ΄ ν΄λΉ κ²½λ‘λ‘ λ¨μ΄μ§ μ μμ΅λλ€. Dockerμμ μ€ν μ€μ΄λΌκ³ μΈκΈνμ΅λλ€. κΈ°λ³Έ Docker seccomp νν°λ₯Ό λΉνμ±ννκ³ μμ΅λκΉ?
seccomp_load()
μ€ν¨ ν if λ΄λΆμ μ½λμ λλ²κΉ
μ λ μΆκ°νκ³ μΆμ κ²μ
λλ€. μλ₯Ό λ€μ΄ νν° μ체μ PFC λ°/λλ BPFλ₯Ό μΆλ ₯νμ¬ ν©λ¦¬μ μΌλ‘ 보μ΄λμ§ νμΈν μ μμ΅λλ€. seccomp_export_pfc()
λ° seccomp_export_bpf()
.
v2.4.3
seccomp_load()
μ½λλ₯Ό μ΄ν΄λ³΄λ libseccompκ°-EINVAL
μ λ°ν μ½λλ₯Ό μμ±νλ κ³³μ΄ λ κ³³λΏμΈ κ² κ°μ΅λλ€.
seccomp_load()
283ν_gen_bpf_build_bpf()
λΌμΈ 1657
gen_bpf_generate(...)
λλ κ·Έ μ΄νμμ λ°κ²¬λ λͺ¨λ μ€ν¨λ src/system.c:267 μμ sys_filter_load(...)
μ μν΄ -ENOMEMμ ν¨κ³Όμ μΌλ‘ κ²°ν©λ©λλ€.
λλ "κΈ°μ΅ μμ"μΌλ‘ λλμκ°λ κ²μ μ«μ΄νλ€! λ무 λΉ λ₯΄μ§λ§ μ¬κΈ°μμλ κ·Έλ΄ μ μμ΅λλ€.
λΉ λ₯΄κ³ μμΈν λ΅λ³ κ°μ¬ν©λλ€! κ·Έλ€μ μ¬λ¬ νμ κ²½λ‘λ₯Ό μμ±νμ΅λλ€.slightly_smiling_face:
μ κ·Έλ μ΄λ μ΄ν νλ‘κ·Έλ¨μμ λ€λ₯Έ μ΄μν λμμ λ°κ²¬νμ ¨μ΅λκΉ? λ€λ₯Έ κ³³μ λ¬Έμ λ₯Ό μΌμΌν€λ λ©λͺ¨λ¦¬ μμ λ¬Έμ κ° μλμ§ κΆκΈν©λλ€.
μλ, μ΄κ²λ§. μ°λ¦¬μ λ¨μ λ° ν΅ν© ν
μ€νΈλ κ³μ ν΅κ³Όνκ³ μμΌλ©° μ΄ λ§€μ° λλ¬Έ EINVAL
νκ³ λ prodμ μ€λ₯κ° κΈ°λ‘λμ§ μμ΅λλ€. μ΄κ²μ νμ€ν κ·Έκ²μ μ΄λ¦¬λ₯μ νκ² λ§λλλ€. λλ λν λ©λͺ¨λ¦¬ μμμ μμ¬νμ§λ§ κ·Έκ²μ λ·λ°μΉ¨ν μ¦κ±°λ₯Ό μ°Ύμ§ λͺ»νμ΅λλ€ :slightly_frowning_face:
μ’ λ μμΈν λ΄μ©μ λ€μκ³Ό κ°μ΅λλ€.
seccomp_init
λ±μμ libseccomp μ체μμ λ°μν©λλ€.μ΄κ²μ μ
λ ₯νλ λμ μμ΄λμ΄κ° μμμ΅λλ€. malloc
ν¬ν¬ ν μ¬μ©νκΈ°μ μμ νμ§ μλ€λ 무μμ΄ μ΄μΌκΈ°λ₯Ό λ€μκ³ libseccomp μ체μ λͺ κ°μ§κ° μμ΅λλ€. Python μ± μ체λ _is_ λ€μ€ μ€λ λμ΄μ§λ§ κΈ°λ³Έ μ½λμ μλ λμ νμ GILμ μ μ§νλ―λ‘ μμ ν΄μΌ ν©λλ€(?). νμ§λ§ malloc-after-forkλ₯Ό ν΅ν΄ κ΅μ°© μνκ° λ°μνλ€λ μ΄μΌκΈ°λ§ λ€μμ΅λλ€. (μ΄κ²μ΄ λ€μ λΉμ¦λμ€ μμκ° seccomp_init
λ±μ ν¬ν¬ μ μ μ΄λνκ³ seccomp_load
ν¬μ€νΈ ν¬ν¬λ§ νΈμΆνκ³ μ€λ₯κ° κ³μ λ°μνλμ§ νμΈνλ κ² κ°μ΅λλ€.)
seccomp_load()κ° μ€ν¨ν ν if λ΄λΆμ μ½λμ λλ²κΉ μ λ μΆκ°νκ³ μΆμ κ²μ λλ€.
μ μν΄ μ£Όμ
μ κ°μ¬ν©λλ€! seccomp_export_pfc
μ λν νΈμΆμ μΆκ°νκ³ μ
λ ₯ λ΄μ©μ νν°( config->syscall_whitelist
)μ λ€ννμ΅λλ€. λ€μμ μ΄κ²μ΄ μ€ν¨νλ©΄ νμ μ‘°μΉλ₯Ό μ·¨νκ² μ΅λλ€.
μλ νμΈμ @Xyene - μ½ μΌμ£ΌμΌμ΄
λΆννλ μμ§ μλλλ€. seccomp_export_pfc
ν¨μΉλ₯Ό μΆκ°ν ν 침묡νμ΅λλ€. μ΄μ μ λ λ¬Έμ κ° λ°μνμ λ λ¬Έμ λ₯Ό μΊ‘μ²νκΈ° μν΄ ν΄λΉ ν¨μΉλ₯Ό λͺ¨λ VM(λ¨μ§ ν
μ€νΈμ©μ΄ μλ)μ νΈμνμ΅λλ€.
λλ 침묡μ μ΄μνκ² μκ°νμ§λ§ μ§κΈμ λͺ¨λ λλ²κΉ
/λ΄λ³΄λ΄κΈ° λ
Όλ¦¬κ° seccomp_load
μ€ν¨ _ν_ λ°μνκΈ° λλ¬Έμ μ°μ°μ μΌμΉλ‘ μκ°νκ³ μμΌλ―λ‘ μ€ν¨ μ체μ μν₯μ μ£Όμ΄μλ μ λ©λλ€.
μ§μ !
κ·Έκ²μ΄ 침묡νλ μ΄μ λ seccomp_export_bpf
μ΄ segfaulting( seccomp_load
λ€μμ νΈμΆλ κ²½μ° ν΄μΌ ν©λκΉ?)μ΄κ³ , λ΄κ° seccomp μ€ν¨λ₯Ό μ°Ύκ³ μλ κ³³μ΄ μλ λ€λ₯Έ κ³³μμ λ³΄κ³ λμκΈ° λλ¬Έμ
λλ€. λ μ€μν κ²μ ~150ν νΈμΆμμ λ¬Έμ λ₯Ό μμ μ μΌλ‘ μ¬νν μ μλ κ²½μ°μ λΆλͺμ³€κΈ° λλ¬Έμ μΌλΆ λ°°κ΄ μμ
μ ν΅ν΄ μΌλΆ μ½μ΄ λ€νλ₯Ό μΆμΆν μ μμ΄μΌ νλ€λ κ²μ
λλ€.
μ’μ, λλ μ½μ΄ λ€νλ₯Ό κΊΌλκ³ μ΄κ²μ΄ μΆμ μ΄μλ€: https://gist.github.com/Xyene/920f1cb098784a031f53c66a2f49d167
μ΄κ²μ jemallocμ realloc
λ£¨ν΄ λ΄μμ μΆ©λνκΈ° λλ¬Έμ μ½κ° μμ¬μ€λ¬μ μ΅λλ€. λν glibc mallocμ λμ μ¬μ©νλ©΄ λ¬Έμ κ° ν΄κ²°λ©λλ€(λΆννλ μ‘°κ°ν λ¬Έμ λ‘ μΈν΄ μ΄ κ²½μ° μ₯κΈ° μ΅μ
μ΄ μλλλ€).
λ€μμΌλ‘ jemallocμ κ°μ Έμ -O0
λ° λλ²κΉ
κΈ°νΈλ‘ μ»΄νμΌνκ³ μ¬μμ°μ λ€μ μ€ννμ΅λλ€. μ΄λ²μλ μ΄νκ° μλλΌ seccomp_load
μμ μΆ©λνμ΅λλ€! μ¬κΈ°μ κ·Έ μΆμ μ μ
λ‘λνμ΅λλ€: https://gist.github.com/Xyene/5da56168bcea337da85b2cd30704d12e
ν΄λΉ μΆμ μ μ€λν«:
#9 0x00007ff962698495 in free (ptr=0x5a5a5a5a5a5a5a5a) at src/jemalloc.c:2867
No locals.
#10 0x00007ff96062d087 in _program_free (prg=prg@entry=0x7ff95e963010) at gen_bpf.c:511
No locals.
#11 0x00007ff96062f605 in gen_bpf_release (program=program@entry=0x7ff95e963010) at gen_bpf.c:1986
No locals.
#12 0x00007ff96062c04f in sys_filter_load (col=col@entry=0x7ff95e9a5000) at system.c:293
rc = -1
prgm = 0x7ff95e963010
#13 0x00007ff96062b666 in seccomp_load (ctx=ctx@entry=0x7ff95e9a5000) at api.c:286
col = 0x7ff95e9a5000
jemallocμ κ²μνλ©΄ 0x5a
κ° μ΄λ―Έ ν΄μ λ κ²μ ν΄μ νλ €κ³ μλνλ μ½λλ₯Ό μΆ©λμν€λ νΉμ μλ λ‘ μ¬μ λ°μ΄νΈλ₯Ό freeλ‘ νμνλ λ° μ¬μ©λλ κ² κ°μ΅λλ€.
v2.4.3μ gen_bpf.c:511
λ λ€μκ³Ό κ°μ΅λλ€. https://github.com/seccomp/libseccomp/blob/1dde9d94e0848e12da20602ca38032b91d521427/src/gen_bpf.c#L505 -L513
κ·Έλ¬λ μ΄κ²μ νλ‘κ·Έλ¨μ μλͺ
μ΄ sys_filter_load
μ λ³Έλ¬ΈμΌ λΏμ΄λ―λ‘ μλ―Έκ° μμ΅λλ€.
λλ μ μ΄λ νλμ λ¬Έμ λ₯Ό λ°κ²¬νλ€κ³ μκ°ν©λλ€. gen_bpf_generate
;
state.bpf = prgm
zmalloc
κ° μ€ν¨νμ§ μλ ν _gen_bpf_build_bpf
κ° νΈμΆλκ³ rc
λ₯Ό κΈ°λ°μΌλ‘ state.bpf
κ° NULL
λ©λλ€.
rc != 0
, state.bpf
κ° _state_release
νΈμΆ μ prgm
λ‘ μ€μ λμ΄ μλ κ²½μ°λ₯Ό κ³ λ €νλ©΄. κ·Έλ¬λ©΄ prgm
κ° κ°λ¦¬ν€λ λ©λͺ¨λ¦¬κ° ν΄μ λ©λλ€.
λ€μμΌλ‘ gen_bpf_generate
λ ν΄μ λμμ§λ§ μ¬μ ν 0μ΄ μλ ν¬μΈν°μΈ return prgm
μ
λλ€.
sys_filter_load
λμκ°λ©΄ gen_bpf_generate
λ°νλκ³ prgm
λ NULL
μλλ―λ‘ κ³μ μ§νν©λλ€.
λ§μ§λ§μΌλ‘ sys_filter_load
μ λμμ gen_bpf_release
κ° μ΄λ―Έ λΉμ΄ μλ prgm
μ λν΄ νΈμΆλ©λλ€.
μ΄κ²μ _gen_bpf_build_bpf
κ° μ²μμ μ€ν¨νλ μ΄μ μ λν μ°λ €λ₯Ό ν΄κ²°νμ§ μμ§λ§ μ€ν¨ν κ²½μ° λ°μν μ μλ λμ κ²μ²λΌ 보μ
λλ€.
νΈμ§: μ€μ λ‘ μ΄κ²μ https://github.com/seccomp/libseccomp/commit/3a1d1c977065f204b96293cccfe7d3e5aa0d7ace μ λΆμμ©μΌλ‘ μμ λ κ² κ°μ΅λλ€
rc != 0μΈ κ²½μ°λ₯Ό κ³ λ €νλ©΄ state.bpfλ _state_release νΈμΆ μ μ¬μ ν prgmμΌλ‘ μ€μ λ©λλ€. μ΄λ κ² νλ©΄ prgmμ΄ κ°λ¦¬ν€λ λ©λͺ¨λ¦¬κ° ν΄μ λ©λλ€.
μν! μ’μ μΊμΉ @Xyene!
3a1d1c977065f204b96293cccce7d3e5aa0d7ace μ΄μμΌλ‘ μ΄ λ¬Έμ λ₯Ό μμ ν΄μΌ νλ€κ³ μκ°ν©λλ€. μ μ μκ°ν΄ λ³΄κ² μ΅λλ€... μμ μ΄ λ무 μ΄λ €μΈ κ²μ΄λΌκ³ μκ°νμ§ μμ΅λλ€... κ·Έλ¦¬κ³ PRμ ν μ μλμ§ νμΈν©λλ€.
3a1d1c9 μ΄μμΌλ‘ μ΄ λ¬Έμ λ₯Ό μμ ν΄μΌ νλ€κ³ μκ°ν©λλ€. μ μ μκ°μ ν΄λ³΄μ£ ... μμ μ΄ λ무 μ΄λ €μΈ κ² κ°μ§λ μμ΅λλ€... κ·Έλ¦¬κ³ PRμ ν μ μλμ§ νμΈνμμμ€.
μ΄λ°, λλ κ·Έκ²μ μμ±ν λ μ€λλ μ½λλ₯Ό λ³΄κ³ μμμ΅λλ€. μ, 3a1d1c9κ° μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ€κ³ μκ°νμ§λ§ λ¦΄λ¦¬μ€ 2.4 λΆκΈ°μ λν ν¨μΉκ° νμν©λλ€. μ΄μ μμ νκ² μ΅λλ€.
_(λ©ν: κ³μ μ§ννλ©΄μ μ΄ λ©μμ§λ₯Ό λ΄ λ°κ²¬μΌλ‘ κ³μ μ λ°μ΄νΈν μμ μ΄λ―λ‘ μ€νΈ λ©μΌμ 보λ΄μ§ μκ³ κΈ°λ‘ν μ μλ κ³³μ΄ μμ΅λλ€. :)_
μ’μ, ν¨μΉκ° μ μ©λ 2.4.3μΌλ‘ λμκ°μ μ€ν¨ν νν°λ₯Ό κΊΌλΌ μ μμμ΅λλ€: link .
λ³΄κ³ λ μμΈμ μ§κΈ ENOMEM
λμ EINVAL
λ΄κ° μκ°νλμ΄, μ£Όμ΄μ§ μμλλ€ _gen_bpf_build_bpf
μ€ν¨νκ³ λ°ν NULL
νλ‘κ·Έλ¨μ. κ·Έλ¬λ PFCλ μ μΈμλ©λλ€. _gen_bpf_build_bpf
μ λ°ν κ°μ λ³΄κ³ νλλ‘ seccomp μ½λλ₯Ό μμ νλ©΄ EFAULT
κ° μμΈμΌλ‘ νμλ©λλ€.
λΉ λ₯Έ ν΄νΉμΌλ‘ :%s/return -EFAULT/abort()
over src/gen_bpf.c
λ₯Ό μ€ννκ³ μ΄ μ€ν μΆμ μ μΆμΆν μ μμμ΅λλ€.
EFAULT μ€ν μΆμ
(gdb) bt full
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
set = {__val = {0, 140084028365964, 140083248439464, 140083248438968, 140083248431088, 140084028368143, 28659884033, 140083965300736,
140083248439464, 140083248438968, 140083248431088, 140084028351031, 140084019988760, 140083248439624, 140083248431200, 140084028372597}}
pid = <optimized out>
tid = <optimized out>
ret = <optimized out>
#1 0x00007f67daa4d55b in __GI_abort () at abort.c:79
save_stage = 1
act = {__sigaction_handler = {sa_handler = 0x7f67d6f3eec0, sa_sigaction = 0x7f67d6f3eec0}, sa_mask = {__val = {140083965300736,
140083965300736, 0, 0, 140083248438968, 140083248438968, 140083248439464, 140083248431504, 140084028417173, 140083964793344,
140083965300736, 140083248431552, 140083994791895, 140083248431552, 140083994787642, 140083965300736}}, sa_flags = -1404894496,
sa_restorer = 0x0}
sigs = {__val = {32, 0 <repeats 15 times>}}
#2 0x00007f67d8bfd455 in _gen_bpf_build_bpf (state=0x7f67ac4302e0, col=0x7f67d6f63040) at gen_bpf.c:1943
rc = 0
iter = 1
h_val = 1425818561
res_cnt = 0
jmp_len = 0
arch_x86_64 = 0
arch_x32 = -1
instr = {op = 32, jt = {tgt = {imm_j = 0 '\000', imm_k = 0, hash = 0, db = 0x0, blk = 0x0, nxt = 0}, type = TGT_NONE}, jf = {tgt = {
imm_j = 0 '\000', imm_k = 0, hash = 0, db = 0x0, blk = 0x0, nxt = 0}, type = TGT_NONE}, k = {tgt = {imm_j = 4 '\004', imm_k = 4,
hash = 4, db = 0x4, blk = 0x4, nxt = 4}, type = TGT_K}}
i_iter = 0x7f67d6fdcb60
b_badarch = 0x7f67d6fd9000
b_default = 0x7f67d6fd9060
b_head = 0x7f67d6fda1a0
b_tail = 0x7f67d6fd9000
b_iter = 0x0
b_new = 0x7f67d6fe3300
b_jmp = 0x0
db_secondary = 0x0
pseudo_arch = {token = 0, token_bpf = 0, size = ARCH_SIZE_UNSPEC, endian = ARCH_ENDIAN_LITTLE, syscall_resolve_name = 0x0,
syscall_resolve_num = 0x0, syscall_rewrite = 0x0, rule_add = 0x0}
#3 0x00007f67d8bfd560 in gen_bpf_generate (col=0x7f67d6f63040) at gen_bpf.c:1971
rc = 0
state = {htbl = {0x0 <repeats 256 times>}, attr = 0x7f67d6f63044, bad_arch_hsh = 889798935, def_hsh = 742199527, arch = 0x7f67ac4301e0,
bpf = 0x7f67d6f64010}
prgm = 0x7f67d6f64010
#4 0x00007f67d8bf64a7 in sys_filter_load (col=0x7f67d6f63040) at system.c:265
rc = 32615
prgm = 0x0
#5 0x00007f67d8bf4f10 in seccomp_load (ctx=0x7f67d6f63040) at api.c:287
col = 0x7f67d6f63040
μ΄λ 1943νμ ν΄λΉν©λλ€.
λ체μ νΉμ±μ κ°μν λ λμ°λ―Έ ν¨μμμ EFAULT
λ₯Ό μ μΈν μ μλ€κ³ μκ°ν©λλ€. μλνλ©΄ κ·Έκ²λ€μ΄ λ¨Όμ μ€λ¨λμμ κ²μ΄κΈ° λλ¬Έμ
λλ€.
κ·Έ ν, λλ HEADλ‘ λμΌν κ²μ μ¬ννλ €κ³ μλνμ΅λλ€. μ¬μ ν λ°μν©λλ€. λ€μμΌλ‘ %s:/goto build_bpf_free_blks/abort()
λ₯Ό λ°λ³΅ν©λλ€. μμΈμ λ€μκ³Ό κ°μ΅λλ€.
κ³ λ§κ²λ μ΄ κΈ°λ₯μ μ§§κ³ μμμ μ€ν¨ μ§μ λ§ μμμ΅λλ€. λμ€μ abort
λΌμ΄λ;
μΆμ νλ€
(gdb) bt full
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
set = {__val = {0, 140050183343588, 0, 448, 140049402494880, 140049402509040, 140049402494832, 140050183342988, 140049402495088,
140049402509040, 140049402494896, 140050183343588, 4294967296, 140049402509040, 140049402509040, 140049402509040}}
pid = <optimized out>
tid = <optimized out>
ret = <optimized out>
#1 0x00007f5ff953055b in __GI_abort () at abort.c:79
save_stage = 1
act = {__sigaction_handler = {sa_handler = 0x7f5ff595d260, sa_sigaction = 0x7f5ff595d260}, sa_mask = {__val = {139642271694862,
140050119389792, 0, 0, 140049402502840, 0, 140049402503336, 140049402502888, 140049402502840, 112, 384, 140049402502840, 140050149861504,
140049402495328, 140050149857273, 392}}, sa_flags = 448, sa_restorer = 0x7f5ff595d240}
sigs = {__val = {32, 0 <repeats 15 times>}}
#2 0x00007f5ff76edee5 in _bpf_append_blk (prg=0x7f5ff5964010, blk=0x7f5ff59df1a0) at gen_bpf.c:452
rc = -12
i_new = 0x0
i_iter = 0x7f5ff59fa178
old_cnt = 48
iter = 1
#3 0x00007f5ff76f3716 in _gen_bpf_build_bpf (state=0x7f5fcae302d0, col=0x7f5ff59c5000) at gen_bpf.c:2223
rc = 0
iter = 1
h_val = 1425818561
res_cnt = 0
jmp_len = 0
arch_x86_64 = 0
arch_x32 = -1
instr = {op = 32, jt = {tgt = {imm_j = 0 '\000', imm_k = 0, hash = 0, db = 0x0, blk = 0x0, nxt = 0}, type = TGT_NONE}, jf = {tgt = {
imm_j = 0 '\000', imm_k = 0, hash = 0, db = 0x0, blk = 0x0, nxt = 0}, type = TGT_NONE}, k = {tgt = {imm_j = 4 '\004', imm_k = 4,
hash = 4, db = 0x4, blk = 0x4, nxt = 4}, type = TGT_K}}
i_iter = 0x7f5ff59e1b60
b_badarch = 0x7f5ff59de000
b_default = 0x7f5ff59de060
b_head = 0x7f5ff59df1a0
b_tail = 0x7f5ff59de000
b_iter = 0x7f5ff59df1a0
b_new = 0x7f5ff59e8300
b_jmp = 0x7f5ff59df0e0
db_secondary = 0x0
pseudo_arch = {token = 0, token_bpf = 0, size = ARCH_SIZE_UNSPEC, endian = ARCH_ENDIAN_LITTLE, syscall_resolve_name = 0x0,
syscall_resolve_num = 0x0, syscall_rewrite = 0x0, rule_add = 0x0}
#4 0x00007f5ff76f3874 in gen_bpf_generate (col=0x7f5ff59c5000, prgm_ptr=0x7f5fcae30b40) at gen_bpf.c:2270
rc = 0
state = {htbl = {0x0, 0x7f5ff593ef80, 0x7f5ff593efe0, 0x7f5ff593efc0, 0x0, 0x7f5ff595d000, 0x7f5ff593ef60, 0x7f5ff593ef00,
0x0 <repeats 248 times>}, attr = 0x7f5ff59c5004, bad_arch_hsh = 889798935, def_hsh = 742199527, bpf = 0x7f5ff5964010,
arch = 0x7f5fcae301c0, b_head = 0x7f5ff59e8300, b_tail = 0x7f5ff59de120, b_new = 0x7f5ff59e8300}
prgm = <optimized out>
#5 0x00007f5ff76eb275 in sys_filter_load (col=0x7f5ff59c5000, rawrc=false) at system.c:307
rc = 0
prgm = 0x0
#6 0x00007f5ff76e9505 in seccomp_load (ctx=0x7f5ff59c5000) at api.c:386
col = 0x7f5ff59c5000
rawrc = false
λ°λΌμ realloc
λ€μ μ€ν¨νκ³ _bpf_append_blk
λ _gen_bpf_build_bpf
μν΄ λ§μ€νΉλμ΄ -EFAULT
-ENOMEM
λ₯Ό λ°νν©λλ€. μ΄κ²μ ν° λ¬Έμ λ μλμ§λ§ λ λμ μ€λ₯ λ³΄κ³ κ° 2.5μ λͺ©νλΌκ³ λ§νκΈ° λλ¬Έμ μ΄κ²μ΄ λ²μ λ΄μμ 보μ΄κΈ° λλ¬Έμ μΈκΈν κ²μ΄λΌκ³ μκ°νμ΅λλ€ :slightly_smiling_face:
μΌλΆ GDBλ₯Ό νκ³ λ€κΈ°:
(gdb) f 2
#2 0x00007f5ff76edee5 in _bpf_append_blk (prg=0x7f5ff5964010, blk=0x7f5ff59df1a0) at gen_bpf.c:452
452 abort();
(gdb) info args
prg = 0x7f5ff5964010
blk = 0x7f5ff59df1a0
(gdb) print prg->blks
$4 = (bpf_instr_raw *) 0x7f5ff59fa000
(gdb) x/32bx &prg->blks
0x7f5ff5964018: 0x00 0xa0 0x9f 0xf5 0x5f 0x7f 0x00 0x00
0x7f5ff5964020: 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
0x7f5ff5964028: 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
0x7f5ff5964030: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(gdb) print ((prg)->blk_cnt * sizeof(*((prg)->blks)))
$5 = 392
(gdb) print prg->blk_cnt
$6 = 49
μ΄κ²μ μ λ§λ‘ ν λΉμ μ€ν¨μ²λΌ 보μ΄κΈ° μμν©λλ€...
μν, μ΄ μ΄μΌκΈ°λ λ§μΉ¨λ΄ _μ€λ¦΄λ§_ν_ κ²°λ‘ μ λλ¬νμ΅λλ€. λ¬΄μ¨ μΌμ΄ μΌμ΄λκ³ μλμ§ μμλκ³ μμ μ¬νμ νμΈνμ΅λλ€.slightly_smiling_face:
ν₯λ―Έλ‘μ΄ μ΄μΌκΈ°κ° λ μ μμΌλ―λ‘ μ¬κΈ°μ μμ΅λλ€.
μμ
μλ₯Ό λΆκΈ°νλ μ£Όμ νλ‘μΈμ€λ μΌλ°μ μΌλ‘ ~80mb RSSμ μμ΅λλ€. λΆκΈ° νμλ rlimit
λ₯Ό ν΅ν΄ λ©λͺ¨λ¦¬ μ¬μ©λμ μ ννλ©° λλ‘λ 64MBλ‘ μ νν©λλ€. μ΄κ²μ νμ¬ λ©λͺ¨λ¦¬ μ¬μ©λμ΄ νκ³λ₯Ό μ΄κ³Όνλ μμΉμ λμ΄κ² λμ§λ§ μ΄κ²μ rlimit
νμ©λ©λλ€. _λλΆλΆμ_ λ©λͺ¨λ¦¬ ν λΉμλ 컀λμ μΆκ° μμ² μμ΄ libseccompμ μ΄κΈ°ν 루ν΄μ μ²λ¦¬νκΈ°μ μΆ©λΆν μ¬μ λ©λͺ¨λ¦¬λ₯Ό κ°κ² λ©λλ€. κ·Έλ¬λ κ·Έκ²μ΄ _νμ§ μλ_ κ²½μ°, κ·Έλ¦¬κ³ μΆκ° κ²½κΈ°μ₯μ΄λ 무μΈκ°λ₯Ό μν 곡κ°μ μμ²ν νμκ° μμ λ, νλ‘μΈμ€κ° μ΄λ―Έ νκ³λ₯Ό μ΄κ³ΌνκΈ° λλ¬Έμ 컀λμ κ·Έκ²μ μ 곡νμ§ μμ κ²μ
λλ€.
2.4.3μμ μ΄ λ©λͺ¨λ¦¬ νλ μ€ν¨λ EINVAL
λ° μ΄μ€ μμ λ‘ λνλ©λλ€. λ§μ€ν° ν¬μ€νΈ https://github.com/seccomp/libseccomp/commit/3a1d1c977065f204b96293cccfe7d3e5aa0d7ace μμ EFAULT
λμ λ³΄κ³ λ©λλ€. https://github.com/seccomp/libseccomp/pull/257μ μ μ©νλ©΄ ENOMEM
κ° μ¬λ°λ₯΄κ² λ³΄κ³ λ©λλ€.
μ΄κ²μ΄ λ§€μ° λλ¬Όκ² μΌμ΄λλ μ΄μ λ λͺ
λ°±ν΄μ§λλ€. ν λΉμκ° μ»€λμ λ λ§μ κ²μ μμ²νμ§ μκ³ BPF νλ‘κ·Έλ¨μ λΉλνκΈ°μ μΆ©λΆν λ©λͺ¨λ¦¬κ° μλμ§ μ¬λΆμ μ μ μΌλ‘ μμ‘΄ν©λλ€. glibcμ ν λΉμλ μ‘°κ°νκ° μμ΄λλ‘ νμ©νλ κ²μ λν΄ λ λμ¨νκΈ° λλ¬Έμ μ μ리μ μλ κ²½μ°μλ μ΄λ° μΌμ΄ λ°μνμ§ μμ΅λλ€. jemallocμ λ μ격ν κ²½κ³λ₯Ό μ€μ νκ³ seccomp_load
λμ λ©λͺ¨λ¦¬λ₯Ό μμ²ν΄μΌ ν νλ₯ μ λμ
λλ€.
μμ μ λͺ¨λ setrlimit
νΈμΆμ _after_ seccomp_load
μ
λλ€. μ΄λ κ² νλ©΄ realloc
κ° λ μ΄μ _bpf_append_blk
μμ μ€ν¨νμ§ μκ³ νν°κ° μ±κ³΅μ μΌλ‘ λ‘λλ©λλ€. μ΄κ²μ νν°κ° setrlimit
νμ©ν΄μΌ ν¨μ μλ―Ένμ§λ§ μ κ²½μ°μλ μ΄κ²μ΄ νμ©λμμ΅λλ€. λ³΄λ€ μΌλ°μ μΌλ‘ μ΄ λ¬Έμ λ https://github.com/seccomp/libseccomp/issues/123 κ³Ό κ°μ λ°©λ²μΌλ‘ ν΄κ²°λ κ²μ΄λΌκ³ μκ°ν©λλ€
@pcmoore , @drakenclimber -- μ΄ λ¬Έμ λ₯Ό λλ²κΉ νλ λ° λμμ μ£Όμ μ λ€μ ν λ² κ°μ¬λ립λλ€! μ§κΈ μ λ€μ λμ μ μμ΄μ κΈ°μ©λλ€. νμ§λ§ κ·νμ ν¬μΈν°λ κ±°κΈ°μ λλ¬νλ λ° λ§€μ° μ€μνμ΅λλ€.μ€λ§μΌλ¦¬:
μ΄ λ²κ·Έλ https://github.com/seccomp/libseccomp/commit/c0a6e6fd15f74c429a0b74e0dfd4de5a29aabebd 컀λ°μΌλ‘ μμ λμμ΅λλ€.
κ°μ₯ μ μ©ν λκΈ
λΆννλ μμ§ μλλλ€.
seccomp_export_pfc
ν¨μΉλ₯Ό μΆκ°ν ν 침묡νμ΅λλ€. μ΄μ μ λ λ¬Έμ κ° λ°μνμ λ λ¬Έμ λ₯Ό μΊ‘μ²νκΈ° μν΄ ν΄λΉ ν¨μΉλ₯Ό λͺ¨λ VM(λ¨μ§ ν μ€νΈμ©μ΄ μλ)μ νΈμνμ΅λλ€.λλ 침묡μ μ΄μνκ² μκ°νμ§λ§ μ§κΈμ λͺ¨λ λλ²κΉ /λ΄λ³΄λ΄κΈ° λ Όλ¦¬κ°
seccomp_load
μ€ν¨ _ν_ λ°μνκΈ° λλ¬Έμ μ°μ°μ μΌμΉλ‘ μκ°νκ³ μμΌλ―λ‘ μ€ν¨ μ체μ μν₯μ μ£Όμ΄μλ μ λ©λλ€.