임베디드 시스템에서 SELinux 사용 경험 - 3장

이 장에서는 SELinux 정책을 실제로 사용하는 방법에 대한 자세한 내용을 다룹니다.

저자: 코리 미니야드, 몬타비스타 소프트웨어

제3장: OpenWRT 정책의 실제 적용

이전 두 장( 1장 과 2장 )에서는 SELinux와 OpenWRT 정책의 기본 사항을 소개했습니다. 이제 정책을 실제로 사용하는 방법에 대한 자세한 내용을 살펴보겠습니다. 이 정책은 대부분의 프로그램에서 공통적으로 수행하는 작업에 대해 헬퍼 매크로를 제공하도록 작성되었습니다. 헬퍼 매크로를 어디에서 찾아야 하는지 알기 위해서는 이러한 매크로가 어떻게 정의되고 사용되는지 이해해야 합니다.

기본 CIL 사용법

우선, 제한 대상이 되는 각 프로그램(또는 관련 프로그램 집합)은 src/agent 디렉토리에 정의되어 있습니다. 예를 들어 lxc 에 대한 규칙 집합을 보려면 src/agent/lxc.cil 파일을 참조하면 됩니다. 이 예제에서는 newgidmap 및 newuidmap 명령에 대한 정책을 생성하는 과정을 설명합니다.

감사 로그

먼저 이와 관련된 감사 로그를 살펴보겠습니다.

type=AVC msg=audit(02/17/21 06:26:07.530:64)<br /> avc: denied { execute } for pid=927 comm=lxc-usernsexec<br /> name=newuidmap dev="rootfs" ino=1167<br /> scontext=u:r:lxc.subj tcontext=u:r:file.execfile<br /> tclass=file permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 06:26:07.530:65)<br /> avc: denied { getattr } for pid=927 comm=lxc-usernsexec<br /> path=/usr/bin/newuidmap dev="rootfs" ino=1167<br /> scontext=u:r:lxc.subj tcontext=u:r:file.execfile<br /> tclass=file permissive=1<br /> .<br /> .<br /> .<br /> ----<br /> type=AVC msg=audit(02/17/21 06:26:07.540:75)<br /> avc: denied { open } for pid=929 comm=newuidmap<br /> path=/etc/subuid dev="rootfs" ino=2114<br /> scontext=u:r:lxc.subj tcontext=u:r:file.conffile<br /> tclass=file permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 06:26:07.540:76)<br /> avc: denied { getattr } for pid=929 comm=newuidmap<br /> path=/etc/subuid dev="rootfs" ino=2114<br /> scontext=u:r:lxc.subj tcontext=u:r:file.conffile<br /> tclass=file permissive=1

더 많은 것들이 있지만, 이것에 집중해 봅시다. 이것들 안에는 다음과 같은 것들이 있습니다.

  • 거부됨 - 이것들이 당신이 중요하게 생각하는 로그입니다. 다른 로그가 있을 수도 있습니다.
  • { xxx } 이것은 거부된 특정 작업입니다. 거부된 작업에 따라 의미는 달라집니다. 파일의 경우 open 또는 getattr 작업이 거부되었을 수 있습니다. 기능의 경우 해당 기능이 거부된 것입니다.
    comm - 실행 중인 프로그램의 이름입니다.
  • path/name/ino = 객체의 파일 경로/이름/inode(일반적으로 파일 시스템 기본 경로를 기준으로 함) 또는 객체의 이름입니다. 이러한 속성은 해당 속성이 없는 객체(예: 유닉스 소켓)의 경우에는 존재하지 않을 수 있습니다.
  • scontext - 작업을 수행하려는 소스 컨텍스트로, 거의 항상 실행 중인 프로그램의 주체 컨텍스트입니다.
  • tcontext - 대상 컨텍스트입니다. 작업에 따라 파일의 객체 컨텍스트(파일에 접근할 때) 또는 프로그램의 주체 컨텍스트(신호를 보낼 때)가 될 수 있습니다.
  • tclass - 이 필드는 반드시 살펴봐야 할 중요한 필드입니다. 대상의 클래스를 나타냅니다. 대상의 클래스에 따라 수행해야 하는 작업이 달라집니다. 디렉터리(dir) 클래스는 파일 클래스와 다릅니다. 기능 오류가 발생한 경우 cap_userns는 capability와 다릅니다.

설명을 마쳤으니 이제 본격적인 정책 수립으로 넘어가겠습니다.

초기 보험 증권 작성

감사 로그를 사용할 때 가장 먼저 해야 할 일은 "프로그램이 이런 동작을 해도 되는가?"라는 질문을 던지는 것입니다. 모든 것을 허용하지 말고, 프로그램이 무엇을 해야 하는지 생각해 보세요. 이는 AppArmor처럼 프로그램을 실행하고 자동으로 정책을 생성하는 방식보다 훨씬 큰 장점입니다. 허용해서는 안 될 버그를 프로그램에 허용하고 있을 수도 있습니다. 이 점은 매우 중요합니다. 프로그램이 잘못된 동작을 한다면 수정해야 합니다. 이제 본격적으로 정책을 작성해 보겠습니다.

위의 첫 번째 부분에서 볼 수 있듯이, 프로그램 ` lxc-usernsexec 는 프로그램 ` /usr/bin/newuidmap 실행합니다. 이 과정은 파일을 열고 읽는 등의 작업을 수행해야 하므로 더 많은 로그를 생성하지만, 이 시점에서는 어떤 일이 일어나고 있는지 알 수 있습니다. 우리는 ` newuidmap 이 lxc 유형의 파일에 접근할 수 없도록 하고, 설계된 기능만 수행하도록 해야 합니다. 또한, lxc ` newuidmap 할 수 있는 작업을 수행할 수 없도록 해야 합니다. 따라서 ` src/agent/newidmap.cil 에 `newuidmap` 파일을 생성하여 newuidmap 별도의 주체로 격리하겠습니다.

; Allow transition from sys.subj (more or less unconfined)<br /> ; to newidmap context<br /> (in .sys<br /> (call .newidmap.subj_type_transition (subj)))

; Allow unconfined to access newidmap files<br /> (in .file<br /> (call .newidmap.obj_type_transition_conffile<br /> (unconfined.subj_typeattr)))<br /><br /> (block newidmap<br /> ;;<br /> ;; Contexts<br /> ;;<br /><br /> ; Our configuration files<br /> (filecon<br /> "/etc/sub[gu]id"<br /> file<br /> conffile_file_context)<br /> ; Our executable files<br /> (filecon<br /> "/usr/bin/new[gu]idmap"<br /> file<br /> execfile_file_context)<br /><br /> ;;<br /> ;; Macros<br /> ;;<br /><br /> ; Allow access to our conf files<br /> (macro obj_type_transition_conffile ((type ARG1))<br /> (call .file.conffile_obj_type_transition<br /> (ARG1 conffile file "subgid"))<br /> (call .file.conffile_obj_type_transition<br /> (ARG1 conffile file "subuid")))<br /><br /> ; Allow access to execute our programs<br /> (macro obj_type_transition_execfile ((type ARG1))<br /> (call .file.execfile_obj_type_transition<br /> (ARG1 execfile file "newgidmap"))<br /> (call .file.execfile_obj_type_transition<br /> (ARG1 execfile file "newuidmap")))<br /><br /> ;;<br /> ;; Policy<br /> ;;<br /><br /> ; Create the newidmap types and basic macros<br /> (blockinherit .agent.base_template)<br /><br /> ; Create the types and macros for configuration file access<br /> (blockinherit .file.conf.obj_template)<br /><br /> ; Give ourselves read access to our configuration files.<br /> (call read_conffile_files (subj))<br /> )
첫 부분은 대부분의 프로그램에서 흔히 볼 수 있는 표준적인 코드입니다. ` in 은 각각 sys 블록과 files 블록에 내용을 추가한다는 의미입니다. 마치 기존 파일에 내용을 덧붙이는 것과 같습니다. filecon 사용하여 새로운 객체 컨텍스트로 파일을 생성할 경우, 파일이 생성될 때 올바른 레이블이 지정되도록 ` (in .file) `과 같은 구문을 추가해야 합니다.

` filecon 줄은 newuidmap (및 이 과정의 일부로 제약 조건을 설정하는 newgidmap )에서 사용하는 파일의 파일 컨텍스트를 설정합니다. 또한 실행 파일의 컨텍스트도 설정하는데, 이 컨텍스트를 사용하여 새로운 주체(프로세스) 컨텍스트를 설정합니다. 파일 이름이 정규 표현식이라는 점에 유의하세요.

` (blockinherit .agent.base_template) ` 블록은 ` newidmap.subj 주체 유형 속성 집합에 추가하는 등 몇 가지 작업을 수행합니다. 이 템플릿은 이전에 사용했던 주체 유형 ` newidmap.subj 와 실행 컨텍스트 ` execfile_file_context 를 생성합니다. 전체 내용을 확인하려면 ` src/agent.cil 파일의 ` agent 블록과 ` base_template 블록을 참조하십시오.

` (blockinherit .file.conf.obj_template) ` 구문은 설정 파일에 대해서도 유사한 작업을 수행합니다. 이 구문은 ` newidmap.conffile_file_context 를 생성하고, ` newidmap.conffile 타입을 생성한 다음, 해당 타입을 ` file 및 ` conffile 타입 속성에 추가하고, 주체가 다양한 방식으로 이러한 설정 파일에 접근할 수 있도록 하는 매크로를 생성합니다. 타입 속성 추가는 클래스에 타입을 추가하는 역할을 하며, 이 경우 `conffile` 및 `file` 타입 속성에 해당합니다.

마지막으로 ` (call read_conffile_files (subj)) `는 주체가 파일에 접근할 수 있도록 허용하는 명령어입니다. 이 명령어는 기본적으로 활성화되어 있지 않습니다.

` src/agent/lxc.cil 파일에 newidmap 프로그램에 접근할 수 있도록 몇 가지 내용을 추가해야 합니다.
; We can call newxidmap executables.<br /> (call .newidmap.subj_type_transition (subj))

이 코드는 newidmap 에서 생성한 매크로를 사용하여 newidmap 주체로 전환하고 파일을 실행합니다. 이제 정책을 빌드하고 설치합니다.

이제 감사 파일에서 newuidmap 검색해 보면, newuidmap 실행과 관련된 모든 문제, 그리고 newuidmap 이 구성 파일에 접근하는 문제가 모두 해결된 것을 확인할 수 있습니다. 하지만 여전히 몇 가지 문제가 남아 있습니다 (문제들을 그룹화하기 위해 순서를 약간 재배열했습니다).

type=AVC msg=audit(02/17/21 19:42:49.570:80)<br /> avc: denied { use } for pid=892 comm=newuidmap<br /> path=pipe:[2178] dev="pipefs" ino=2178<br /> scontext=u:r:newidmap.subj tcontext=u:r:lxc.subj<br /> tclass=fd permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.570:81)<br /> avc: denied { write } for pid=892 comm=newuidmap<br /> path=pipe:[2178] dev="pipefs" ino=2178<br /> scontext=u:r:newidmap.subj tcontext=u:r:lxc.subj<br /> tclass=fifo_file permissive=1

이는 lxc 가 newidmap 의 출력을 가져오기 위해 파이프를 열었기 때문입니다. tcontext 가 lxc.subj 로 표시되는 것을 보면 알 수 있는데, 이는 lxc 에 속한다는 의미입니다. 로그의 다른 부분에서는 read 필요한 다른 파이프도 통과했으므로 read 권한도 필요합니다. lxc.cil 파일에서 이 권한을 부여해야 합니다.

; We pass a pipe to newxidmap, let it have access<br /> (in .newidmap<br /> (call .lxc.readwriteinherited_fifo_file (subj))<br /> )

이제 to /proc 넘어가겠습니다.

type=AVC msg=audit(02/17/21 19:42:49.580:85)<br /> avc: denied { read } for pid=892 comm=newuidmap<br /> name=891 dev="proc" ino=2179<br /> scontext=u:r:newidmap.subj tcontext=u:r:lxc.subj<br /> tclass=dir permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.580:86)<br /> avc: denied { open } for pid=892 comm=newuidmap<br /> path=/proc/891 dev="proc" ino=2179<br /> scontext=u:r:newidmap.subj tcontext=u:r:lxc.subj<br /> tclass=dir permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.580:94)<br /> avc: denied { write } for pid=892 comm=newuidmap<br /> name=uid_map dev="proc" ino=2183<br /> scontext=u:r:newidmap.subj tcontext=u:r:lxc.subj<br /> tclass=file permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.580:93)<br /> avc: denied { getattr } for pid=892 comm=newuidmap<br /> path=/proc/891 dev="proc" ino=2179<br /> scontext=u:r:newidmap.subj tcontext=u:r:lxc.subj<br /> tclass=dir permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.580:95)<br /> avc: denied { open } for pid=892 comm=newuidmap<br /> path=/proc/891/uid_map dev="proc" ino=2183<br /> scontext=u:r:newidmap.subj tcontext=u:r:lxc.subj<br /> tclass=file permissive=1

lxc uid 맵을 설정해 달라고 요청하는 프로그램이 바로 이 프로그램입니다. 여기서 약간의 보안 문제가 발생합니다. newuidmap 프로그램은 ` /proc 에 있는 ` uid_map 파일에 쓰기 작업을 수행하는데, 이는 프로그램의 본래 목적이라고 볼 수 있습니다. 하지만 이 작업은 lxc 프로그램 자체에 대해 수행되므로, newuidmap은 lxc 파일에 대한 접근 권한을 갖게 됩니다.

` lxc.subj 컨텍스트에서 ` newuidmap 프로그램을 실행할 수도 있습니다. 하지만 그렇게 하려면 ` lxc.subj 에 ` newidmap 파일 및 ` newuidmap 에 필요한 기타 모든 것에 대한 접근 권한을 부여해야 합니다. 현재 분석에 따르면 `lxc.subj`는 컨테이너 내부 구조에 접근할 수 있으므로 외부에서 ` lxc.subj 로 실행하지 않는 것이 중요합니다. 컨테이너 내부 구조는 보호해야 할 가장 중요한 요소이기 때문입니다. 따라서 ` newidmap.cil 파일을 생성하여 배포할 예정이지만, 이것이 최선의 방법이 아닐 수도 있고, 이 애플리케이션에는 적합하지만 일반적으로는 문제가 될 수 있습니다.

따라서 lxc.cil 에서 이에 대한 접근을 허용해야 합니다. newidmap 출처를 알 수 없습니다. 접근 권한을 부여하기 위해 lxc 블록에 무언가를 추가해야 합니다. 표준 procfile 매크로는 표준 파일 컨텍스트인 lxc.fs 에서 작동하고, 이 경우에는 실행 파일 컨텍스트인 lxc.subj 에서 작동하지 않기 때문에 사용할 수 없습니다.

; This allows us to pass proc object to newidmap because the /proc/nnn<br /> ; files for things I execute will be owned by lxc.subj.<br /> (macro list_procsubj_dirs ((type ARG1))<br /> (allow ARG1 subj list_dir))<br /> (macro readwrite_procsubj_files ((type ARG1))<br /> (allow ARG1 subj readwrite_file))

그리고 이제 lxc.cil 에서 newidmap 접근 권한이 있음을 알려주세요.

; Let newxidmap access our /proc/nnn files to set the uid map<br /> (in .newidmap<br /> (call .lxc.list_procsubj_dirs (subj))<br /> (call .lxc.readwrite_procsubj_files (subj))<br /> )

마지막으로, /proc 자체는 procfile이므로 newidmap.cil 에서 해당 파일에 대한 접근 권한을 부여해야 합니다.

; Allow access to list files in /proc<br /> (call .fs.list_procfile_dirs (subj))

나머지는 newidmap.cil 에 대한 변경 사항입니다.

type=AVC msg=audit(02/17/21 19:42:49.580:87)<br /> avc: denied { create } for pid=892 comm=newuidmap<br /> scontext=u:r:newidmap.subj tcontext=u:r:newidmap.subj<br /> tclass=unix_stream_socket permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.580:88)<br /> avc: denied { connect } for pid=892 comm=newuidmap<br /> scontext=u:r:newidmap.subj tcontext=u:r:newidmap.subj<br /> tclass=unix_stream_socket permissive=1

유닉스 소켓에 대한 접근을 허용해야 합니다.

; Allow us to create and connect to a unix socket<br /> (allow subj self create_unix_stream_socket)

그 외에도 여러 가지 문제가 있습니다.

type=AVC msg=audit(02/17/21 19:42:49.580:89)<br /> avc: denied { search } for pid=892 comm=newuidmap<br /> name=run dev="rootfs" ino=1263<br /> scontext=u:r:newidmap.subj tcontext=u:r:varfile.runtimevarfile<br /> tclass=dir permissive=1

이건 좀 까다롭습니다. 하지만 ` runtimevarfile 을 보면 이 파일이 /var 에 있고 이름이 `run`인 것을 알 수 있습니다. 즉, /var/run 을 검색하려고 하는 것입니다. 간단합니다. varfile.runtime 에 검색 권한을 부여하면 됩니다.

; Allow search on /var/run<br /> (call var.search_fs_dirs (subj))

자, 이제 더 자세히 알아보겠습니다.

type=AVC msg=audit(02/17/21 19:42:49.580:90)<br /> avc: denied { read } for pid=892 comm=newuidmap<br /> name=passwd dev="rootfs" ino=1239<br /> scontext=u:r:newidmap.subj tcontext=u:r:nameservice.miscfile<br /> tclass=file permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.580:91)<br /> avc: denied { open } for pid=892 comm=newuidmap<br /> path=/etc/passwd dev="rootfs" ino=1239<br /> scontext=u:r:newidmap.subj tcontext=u:r:nameservice.miscfile<br /> tclass=file permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.580:92)<br /> avc: denied { getattr } for pid=892 comm=newuidmap<br /> path=/etc/passwd dev="rootfs" ino=1239<br /> scontext=u:r:newidmap.subj tcontext=u:r:nameservice.miscfile<br /> tclass=file permissive=1

newuidmap /etc/passwd 에서 값을 읽어야 합니다. 다른 프로그램들도 이와 같은 방식으로 작동하므로, 이미 이를 처리하는 매크로가 있을 가능성이 높습니다. 좀 더 자세히 살펴보면 ` file/miscfile/nameservicesmiscfile.cil 파일의 ` nameservice 블록에서 관련 매크로를 찾을 수 있을 것입니다. 이 매크로를 사용하면 됩니다.

; Allow access to /etc/passwd<br /> (call nameservice.read_miscfile_files (subj))

그리고 몇 가지 기능 관련 문제가 있습니다.

type=AVC msg=audit(02/17/21 19:42:49.580:96)<br /> avc: denied { sys_admin } for pid=892 comm=newuidmap<br /> capability=sys_admin<br /> scontext=u:r:newidmap.subj tcontext=u:r:newidmap.subj<br /> tclass=cap_userns permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.580:97)<br /> avc: denied { setuid } for pid=892 comm=newuidmap capability=setuid<br /> scontext=u:r:newidmap.subj tcontext=u:r:newidmap.subj<br /> tclass=capability permissive=1<br /> ----<br /> type=AVC msg=audit(02/17/21 19:42:49.590:98)<br /> avc: denied { setgid } for pid=893 comm=newgidmap capability=setgid<br /> scontext=u:r:newidmap.subj tcontext=u:r:newidmap.subj<br /> tclass=capability permissive=1

이것들은 기본적인 허가만 있으면 됩니다:

; Capabilities we need to set the uids and guids<br /> (allow subj self (cap_userns (sys_admin)))<br /> (allow subj self (capability (setuid setgid)))

그래서 우리는 이 모든 과정을 거쳐 모든 것이 제대로 작동하도록 만든 다음 다시 살펴봅니다.

type=AVC msg=audit(02/17/21 22:58:46.460:139)<br /> avc: denied { read write } for pid=929 comm=newuidmap<br /> path=socket:[2241] dev="sockfs" ino=2241<br /> scontext=u:r:newidmap.subj tcontext=u:r:lxc.subj<br /> tclass=unix_stream_socket permissive=1

이 부분은 파일의 더 아래쪽에 있으며, 아마도 newuidmap 의 다른 호출에서 발생한 것 같습니다. 어떤 이유에서인지 lxc 에서 유닉스 스트림 소켓을 상속받고 있습니다. 이는 아마도 lxc 의 버그일 가능성이 높으며, exec 전에 fork에서 소켓을 닫지 않는 문제일 수 있지만, 경고는 억제할 수 있습니다. newuidmap 해당 소켓을 사용하지 않는다면 문제가 되지 않습니다. ` in .newidmap 파일에 다음 내용을 추가하세요.

; This appears to be due to a bug in lxc, it's not closing a socket<br /> ; that gets passed when newxidmap is called. Suppress the log<br /> ; as we know about this.<br /> (dontaudit subj .lxc.subj readwrite_unix_stream_socket)

이를 위한 매크로가 없으므로 직접 코드를 작성해야 합니다.

그렇게 간단하지 않아요

제가 이 작업을 쉽게 보이게 만들었지만, 실제로는 그렇지 않습니다. 저는 이 작업에 하루 종일 매달렸습니다. 그 후 OpenWRT 관리자가 코드를 검토하고 제가 잘못한 부분을 꼼꼼히 지적해 주었습니다. 보안에 대한 이해가 필수적입니다. 직접 파고들어 살펴보고 문제를 해결해야 합니다. 예상대로 작동하지 않는 경우가 많고, 시행착오를 거쳐야 합니다. 컴파일러 메시지는 좀 더 유용했으면 좋겠습니다(물론 이전 정책 컴파일러보다는 훨씬 낫습니다). 조금씩 작업하고 다시 컴파일하여 어떤 부분이 문제를 일으켰는지 파악하는 것이 가장 좋습니다.

각 구성 요소와 작동 방식

여기서 대부분의 작업을 수행하는 기본 메커니즘은 ` macro `, ` call ` 및 ` block ` 연산입니다. 그 외에도 ` in ` 및 ` blockinherit ` 연산이 있습니다.

이 함수들은 위치에 구애받지 않는다는 점에 유의하십시오. 파일에서 사용하기 전에 매크로를 선언할 필요가 없습니다. 일반적으로 순서는 중요하지 않습니다. 하지만 매크로를 재정의하는 경우와 같은 예외적인 경우가 있습니다.

매크로 및 호출

` macro `는 이름 그대로 C 언어의 매크로와 같습니다. 매크로에 있는 내용이 ` call 문 자리에 들어가고, 인수는 원래 함수의 인수로 대체됩니다. 아주 간단합니다.

블록 및 블록상속

블록은 네임스페이스를 생성하고 해당 네임스페이스 내에서 연산을 허용합니다. 이 네임스페이스는 컨텍스트에 따라 다양한 기능을 수행합니다.

네임스페이스 블록

위의 ` newidmap 블록과 같은 일부 블록은 주어 및 목적어 컨텍스트를 정의하기 위한 네임스페이스를 생성하는 데 사용됩니다. ` subj 가 많이 사용되는 것을 볼 수 있는데, 이는 다음과 같이 생성됩니다.

(blockinherit agent.base_template)

그리고 이것은 블록 내의 주제 컨텍스트입니다. 이 특정 blockinhert는 매우 많은 작업을 수행하며, 이것이 바로 우리가 OpenWrt 정책을 시작점으로 사용한 이유 중 하나입니다. 그렇지 않았다면 작성해야 할 코드가 엄청나게 많았을 것입니다. ` src/agent.cil 파일을 살펴보면 이 블록이 수행하는 모든 작업을 확인할 수 있습니다.

다음과 같은 일을 할 때:

(blockinherit .file.conf.obj_template)

` file 블록 안에 있는 ` conf 블록 안에 있는 ` obj_template 블록을 불러오고 있습니다. 그러면 블록 이름을 기반으로 conffile 객체가 생성됩니다. 이 경우 ` newidmap 블록에는 ` newidmap.conffile 생성됩니다. 위의 코드는 블록의 네임스페이스에 ` conffile_file_context 를 생성합니다. 블록에 정의된 매크로는 생성된 모든 유형과 함께 해당 블록 이름으로 사용할 수 있습니다. 예를 들어, `newidmap` conffile 컨텍스트를 참조해야 하는 경우 ` .newidmap.conffile_file_context 를 사용할 수 있습니다.

템플릿 블록

이것들은 ` blockinherit 에서 사용되는 블록들입니다. 기본적으로 현재 블록 이름을 사용하여 삽입 위치에 맞게 사용자 정의되는 템플릿입니다. 거의 직접 삽입되는 방식입니다. 예를 들어 다음과 같은 블록이 있는 경우:

(block asdf<br /> (blockabstract asdf)<br /> (macro1 m1 ....)<br /> (macro2 m2 ....))

그리고 저는 그것을 다른 블록에서 사용합니다.

(block jkl<br /> (blockinherit asdf))

마치 다음과 같을 것입니다:

(block jkl<br /> (macro1 m1 ....)<br /> (macro2 m2 ....))

` blockabstract 문은 해당 블록이 blockinherited 만을 위해 설계되었으며, 블록에서 직접적인 코드를 생성하지 않음을 선언합니다.

~에

`in` 문은 기존 블록에 내용을 추가합니다. 예를 들어 다음과 같은 코드가 있었습니다.

(in .newidmap<br /> (call .lxc.readwriteinherited_fifo_file (subj))<br /> )

` lxc.cil 파일에서처럼 말이죠. 매번 ` newidmap.cil 파일에 뭔가를 추가하는 건 비효율적이기 때문입니다. 대신, 해당 파일을 사용하는 곳에 추가하면 됩니다. 그러면 해당 파일은 자신이 그 파일을 사용하고 있다는 것을 알고 있게 되니까요.

` in 문은 내용을 그대로 블록에 삽입합니다. 즉, ` subj 는 대상 블록의 주제어가 되므로 사용하기가 더 쉽습니다.

다음 블로그 게시물도 기대해주세요!

MVSecure 서비스 및 MVXpert 서비스 에 대해 자세히 알아보세요.

Please reach out to discuss your particular scenario today.

전문가와 상담하기 sales@mvista.com으로 이메일 보내기

Keep reading

Related blogs

View all posts
CGX Jun 08, 2026

캐리어급 리눅스에 대한 설명: 2026년 이후 임베디드 개발자가 기대해야 할 사항

최신 임베디드 팀이 고가용성, 결정론적, 보안성, 그리고 장기적인 유지보수가 가능한 Linux 플랫폼에서 기대해야 할 사항들을 살펴보세요.

Read article
MVXpert May 04, 2026

임베디드 리눅스용 Yocto 배포판과 리눅스 배포판 중 어느 것을 선택해야 할까요?

임베디드 리눅스 시스템을 구축하고 유지 관리할 때 Yocto와 리눅스 배포판 중 어떤 것이 더 나은 선택인지 알아보세요.

Read article
MVSecure May 02, 2025

임베디드 시스템에서 SELinux 사용 경험 - 4장

보안 강화 리눅스(SELinux)의 정책 구조에 대해 논의해 보겠습니다.

Read article
nec
nokia
ericsson
samsung
cisco
lg
stjude
guidant
fujitsu
infinera
hp
canon
siemens
motorola
tellabs
nec
nokia
ericsson
samsung
cisco
lg
stjude
guidant
fujitsu
infinera
hp
canon
siemens
motorola
tellabs