아래에서 무슨 일이 일어나고 있는지 자세히 설명할 수 있는 사람이 있습니까? noexec
다음 옵션을 사용하여 디렉터리를 마운트한다고 가정해 보겠습니다 .
mount -o noexec /dev/mapper/fedora-data /data
그래서 이를 확인하기 위해 다음을 실행했습니다 mount | grep data
.
/dev/mapper/fedora-data on /data type ext4 (rw,noexec,relatime,seclabel,data=ordered)
지금은 다음과 같은 /data
간단한 스크립트를 만들고 있습니다 hello_world
.
#!/bin/bash
echo "Hello World"
whoami
그래서 스크립트를 실행 가능하게 만들고 chmod u+x hello_world
(그러나 이것은 options 가 있는 파일 시스템에는 아무런 영향을 미치지 않습니다 noexec
) 실행해 보았습니다.
# ./hello_world
-bash: ./hello_world: Permission denied
그러나 bash
파일을 전처리하면 다음이 생성됩니다.
# bash hello_world
Hello World
root
hello_world.c
그런 다음 다음 내용으로 간단한 것을 만들었습니다 .
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
다음을 사용하여 컴파일하십시오. cc -o hello_world hello_world.c
이제 다음을 실행하세요.
# ./hello_world
-bash: ./hello_world: Permission denied
그래서 나는 그것을 사용하여 실행해 보았습니다.
/lib64/ld-linux-x86-64.so.2 hello_world
실수:
./hello_world: error while loading shared libraries: ./hello_world: failed to map segment from shared object: Operation not permitted
물론 ldd
다음이 반환되므로 이는 정확합니다.
ldd hello_world
ldd: warning: you do not have execution permission for `./hello_world'
not a dynamic executable
noexec
마운트 옵션이 적용되지 않는 다른 시스템에서는 다음이 표시됩니다.
ldd hello_world
linux-vdso.so.1 (0x00007ffc1c127000)
libc.so.6 => /lib64/libc.so.6 (0x00007facd9d5a000)
/lib64/ld-linux-x86-64.so.2 (0x00007facd9f3e000)
이제 내 질문은 옵션이 있는 파일 시스템에서 bash 스크립트를 실행하면 noexec
작동하지만 c
컴파일된 프로그램은 작동하지 않는 이유는 무엇입니까? 뒤에서 무슨 일이 일어나는가?
답변1
두 경우 모두 발생하는 상황은 동일합니다. 파일을 직접 실행하려면 실행 비트를 설정해야 하며 파일 시스템은 noexec를 사용하여 마운트할 수 없습니다. 하지만 이런 것들은 아무것도 막지 못해요읽다그 문서들.
Bash 스크립트가 실행되고 ./hello_world
파일이 실행 가능하지 않으면(exec 권한 비트가 없거나 파일 시스템에 noexec가 없음) 다음 #!
줄이 표시됩니다 .확인도 안 했고, 시스템이 파일을 로드하지도 않기 때문입니다. 스크립트는 관련 의미에서 결코 "실행"되지 않습니다.
이 경우 bash ./hello_world
noexec 파일 시스템 옵션은 분명히 원하는 것만큼 똑똑하지 않습니다. bash
run 명령은 가 있는 파일 시스템에 있고 그렇지 /bin/bash
않습니다 . 따라서 실행하는데에는 문제가 없습니다. 시스템은 bash(또는 python, perl 등)가 인터프리터인지 여부에 상관하지 않습니다. 단지 사용자가 제공한 명령( )을 실행 하며 인수는 정확히 파일입니다. Bash 또는 기타 쉘의 경우 파일에는 실행할 명령 목록이 포함되어 있지만 이제 파일의 실행 비트를 확인할 항목이 "지나갔습니다". 점검 후 발생한 문제는 책임지지 않습니다./bin
noexec
/bin/bash
다음 상황을 고려해보세요.
$ cat hello_world | /bin/bash
...또는 고양이를 무의미하게 사용하는 것을 좋아하지 않는 분들을 위해:
$ /bin/bash < hello_world
#!
파일 시작 부분의 "shbang" 시퀀스는 파일을 명령으로 실행하려고 할 때 동일한 작업을 효과적으로 수행하는 멋진 마법입니다. 다음 LWN.net 기사가 도움이 될 수 있습니다.프로그램 작동 방식.
답변2
noexec
이전 답변은 (귀하의 경우) 명령줄에서 인터프리터가 명시적으로 호출될 때 이 설정이 스크립트 실행을 방해하지 않는 이유를 설명합니다 . /bin/bash
하지만 그게 전부라면 다음 명령도 작동합니다.
/lib64/ld-linux-x86-64.so.2 hello_world
당신이 지적했듯이 이것은 작동하지 않습니다. noexec
또 다른 효과가 있기 때문이죠 . 커널은 이 파일 시스템의 메모리 매핑 파일을 PROT_EXEC
활성화하는 것을 허용하지 않습니다.
메모리 매핑된 파일은 다양한 시나리오에서 사용됩니다. 가장 일반적인 두 가지 경우는 실행 파일과 라이브러리입니다. 프로그램이 시스템 호출을 사용하여 시작되면 execve
커널은 내부적으로 링커와 실행 파일에 대한 메모리 맵을 생성합니다. 필요한 추가 라이브러리는 mmap
활성화된 시스템 호출을 통해 링커에 의해 매핑된 메모리 입니다 PROT_EXEC
. 파일 시스템에서 라이브러리를 사용하려고 하면 noexec
커널이 mmap
호출 실행을 거부합니다.
/lib64/ld-linux-x86-64.so.2 hello_world
시스템 호출을 호출하면 execve
링커에 대한 메모리 맵만 생성되며, 링커는 hello_world
실행 파일을 열고 라이브러리에 대해 수행하는 것과 거의 동일한 방식으로 메모리 맵을 생성하려고 시도합니다. 이 시점에서 커널은 호출 실행을 거부 mmap
하고 오류가 발생합니다.
./hello_world: error while loading shared libraries: ./hello_world: failed to map segment from shared object: Operation not permitted
이 noexec
설정은 실행 권한 없이도 메모리 매핑을 허용하고(때때로 데이터 파일에 사용됨) 파일을 정상적으로 읽을 수 있도록 허용하므로 bash hello_world
효과가 있었습니다.
답변3
다음과 같이 명령을 실행하십시오.
bash hello_world
bash
파일에서 읽습니다 ( hello_world
금지되지 않음).
다른 경우에는 운영 체제가 이 파일을 실행하려고 시도 hello_world
하고 noexec
플래그와 함께 실패합니다.
답변4
bash 실행 파일이 해당 파일 시스템에 상주하지 않기 때문입니다.