Executing a bash script or a c binary on a file system with noexec option
Can anyone explain in details what is going on with the following. Let's imagine I am mounting a directory with noexec
option as follows:
mount -o noexec /dev/mapper/fedora-data /data
So to verify this I ran mount | grep data
:
/dev/mapper/fedora-data on /data type ext4 (rw,noexec,relatime,seclabel,data=ordered)
Now within /data
I'm creating a simple script called hello_world
as follows:
#!/bin/bash
echo "Hello World"
whoami
So I made the script executable by chmod o+x hello_world
(this will however have no effect on a file system with noexec
options) and I tried running it:
# ./hello_world
-bash: ./hello_world: Permission denied
However, prepanding bash
to the file yields to:
# bash hello_world
Hello World
root
So then I created a simple hello_world.c
with the following contents:
#include <stdio.h>
int main()
{
printf("Hello Worldn");
return 0;
}
Compiled it using cc -o hello_world.c hello_world
Now running:
# ./hello_world
-bash: ./hello_world: Permission denied
So I tried to run it using
/lib64/ld-linux-x86-64.so.2 hello_world
The error:
./hello_world: error while loading shared libraries: ./hello_world: failed to map segment from shared object: Operation not permitted
So this is of course true since ldd
returns the following:
ldd hello_world
ldd: warning: you do not have execution permission for `./hello_world'
not a dynamic executable
On another system where noexec
mount option doesn't apply I see:
ldd hellow_world
linux-vdso.so.1 (0x00007ffc1c127000)
libc.so.6 => /lib64/libc.so.6 (0x00007facd9d5a000)
/lib64/ld-linux-x86-64.so.2 (0x00007facd9f3e000)
Now my question is this: Why does running a bash script on a file system with noexec
option work but not a c
code? What is happening under the hood?
linux bash fedora filesystems c
add a comment |
Can anyone explain in details what is going on with the following. Let's imagine I am mounting a directory with noexec
option as follows:
mount -o noexec /dev/mapper/fedora-data /data
So to verify this I ran mount | grep data
:
/dev/mapper/fedora-data on /data type ext4 (rw,noexec,relatime,seclabel,data=ordered)
Now within /data
I'm creating a simple script called hello_world
as follows:
#!/bin/bash
echo "Hello World"
whoami
So I made the script executable by chmod o+x hello_world
(this will however have no effect on a file system with noexec
options) and I tried running it:
# ./hello_world
-bash: ./hello_world: Permission denied
However, prepanding bash
to the file yields to:
# bash hello_world
Hello World
root
So then I created a simple hello_world.c
with the following contents:
#include <stdio.h>
int main()
{
printf("Hello Worldn");
return 0;
}
Compiled it using cc -o hello_world.c hello_world
Now running:
# ./hello_world
-bash: ./hello_world: Permission denied
So I tried to run it using
/lib64/ld-linux-x86-64.so.2 hello_world
The error:
./hello_world: error while loading shared libraries: ./hello_world: failed to map segment from shared object: Operation not permitted
So this is of course true since ldd
returns the following:
ldd hello_world
ldd: warning: you do not have execution permission for `./hello_world'
not a dynamic executable
On another system where noexec
mount option doesn't apply I see:
ldd hellow_world
linux-vdso.so.1 (0x00007ffc1c127000)
libc.so.6 => /lib64/libc.so.6 (0x00007facd9d5a000)
/lib64/ld-linux-x86-64.so.2 (0x00007facd9f3e000)
Now my question is this: Why does running a bash script on a file system with noexec
option work but not a c
code? What is happening under the hood?
linux bash fedora filesystems c
add a comment |
Can anyone explain in details what is going on with the following. Let's imagine I am mounting a directory with noexec
option as follows:
mount -o noexec /dev/mapper/fedora-data /data
So to verify this I ran mount | grep data
:
/dev/mapper/fedora-data on /data type ext4 (rw,noexec,relatime,seclabel,data=ordered)
Now within /data
I'm creating a simple script called hello_world
as follows:
#!/bin/bash
echo "Hello World"
whoami
So I made the script executable by chmod o+x hello_world
(this will however have no effect on a file system with noexec
options) and I tried running it:
# ./hello_world
-bash: ./hello_world: Permission denied
However, prepanding bash
to the file yields to:
# bash hello_world
Hello World
root
So then I created a simple hello_world.c
with the following contents:
#include <stdio.h>
int main()
{
printf("Hello Worldn");
return 0;
}
Compiled it using cc -o hello_world.c hello_world
Now running:
# ./hello_world
-bash: ./hello_world: Permission denied
So I tried to run it using
/lib64/ld-linux-x86-64.so.2 hello_world
The error:
./hello_world: error while loading shared libraries: ./hello_world: failed to map segment from shared object: Operation not permitted
So this is of course true since ldd
returns the following:
ldd hello_world
ldd: warning: you do not have execution permission for `./hello_world'
not a dynamic executable
On another system where noexec
mount option doesn't apply I see:
ldd hellow_world
linux-vdso.so.1 (0x00007ffc1c127000)
libc.so.6 => /lib64/libc.so.6 (0x00007facd9d5a000)
/lib64/ld-linux-x86-64.so.2 (0x00007facd9f3e000)
Now my question is this: Why does running a bash script on a file system with noexec
option work but not a c
code? What is happening under the hood?
linux bash fedora filesystems c
Can anyone explain in details what is going on with the following. Let's imagine I am mounting a directory with noexec
option as follows:
mount -o noexec /dev/mapper/fedora-data /data
So to verify this I ran mount | grep data
:
/dev/mapper/fedora-data on /data type ext4 (rw,noexec,relatime,seclabel,data=ordered)
Now within /data
I'm creating a simple script called hello_world
as follows:
#!/bin/bash
echo "Hello World"
whoami
So I made the script executable by chmod o+x hello_world
(this will however have no effect on a file system with noexec
options) and I tried running it:
# ./hello_world
-bash: ./hello_world: Permission denied
However, prepanding bash
to the file yields to:
# bash hello_world
Hello World
root
So then I created a simple hello_world.c
with the following contents:
#include <stdio.h>
int main()
{
printf("Hello Worldn");
return 0;
}
Compiled it using cc -o hello_world.c hello_world
Now running:
# ./hello_world
-bash: ./hello_world: Permission denied
So I tried to run it using
/lib64/ld-linux-x86-64.so.2 hello_world
The error:
./hello_world: error while loading shared libraries: ./hello_world: failed to map segment from shared object: Operation not permitted
So this is of course true since ldd
returns the following:
ldd hello_world
ldd: warning: you do not have execution permission for `./hello_world'
not a dynamic executable
On another system where noexec
mount option doesn't apply I see:
ldd hellow_world
linux-vdso.so.1 (0x00007ffc1c127000)
libc.so.6 => /lib64/libc.so.6 (0x00007facd9d5a000)
/lib64/ld-linux-x86-64.so.2 (0x00007facd9f3e000)
Now my question is this: Why does running a bash script on a file system with noexec
option work but not a c
code? What is happening under the hood?
linux bash fedora filesystems c
linux bash fedora filesystems c
asked 5 hours ago
Valentin Bajrami
5,82911627
5,82911627
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
Executing command on this way:
bash hello_world
you make bash
read from file hello_world
(which is not forbidden).
In other cases OS try to run this file hello_world
and fail because of noexec
flag
Well the kernel will check the shebang to decide what instructions to expect/run. So running./hello_world
would mean the same right or am I missing the point here?
– Valentin Bajrami
4 hours ago
@ValentinBajrami, no, they execute on different way. Think about no execution flag on the file.
– Romeo Ninov
4 hours ago
add a comment |
What's happening in both cases is the same: to execute a file directly, the execute bit needs to be set, and the filesystem can't be mounted noexec. But these things don't stop reading those files.
The noexec filesystem option just plain isn't as smart as you'd like it to be. In the case of the bash script run as ./hello_world
, the #!
line isn't even checked, because the system sees that it should ignore the executable bit before even trying to run the file.
In the case of bash ./hello_world
, the script is never "executed" in the relevant sense. Instead, /bin/bash
is, and that then loads the file and does stuff. In the case of bash or another shell, the "stuff" is "execute a bunch of commands", but _now we're "past" anything that's going to check file execute bits. That check isn't responsible for what happens later.
Consider this case:
$ cat hello_world | /bin/bash
… or for those who do not like Pointless Use of Cat:
$ /bin/bash < hello_world
The "shbang" #!
sequence at the beginning of a file is just some nice magic for doing exactly the same thing — when you try to execute the file as a command. You might find this LWN.net article helpful: How programs get run.
add a comment |
Because the bash executable doesn't reside on said filesystem.
1
That is true but running./hello_world
would also us/bin/bash
which doesn't reside on a file system withnoexec
option mounted. If that is true then thec
program would run as well corerct?
– Valentin Bajrami
4 hours ago
1
Nope. That's not the way it works.
– tink
4 hours ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f490402%2fexecuting-a-bash-script-or-a-c-binary-on-a-file-system-with-noexec-option%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Executing command on this way:
bash hello_world
you make bash
read from file hello_world
(which is not forbidden).
In other cases OS try to run this file hello_world
and fail because of noexec
flag
Well the kernel will check the shebang to decide what instructions to expect/run. So running./hello_world
would mean the same right or am I missing the point here?
– Valentin Bajrami
4 hours ago
@ValentinBajrami, no, they execute on different way. Think about no execution flag on the file.
– Romeo Ninov
4 hours ago
add a comment |
Executing command on this way:
bash hello_world
you make bash
read from file hello_world
(which is not forbidden).
In other cases OS try to run this file hello_world
and fail because of noexec
flag
Well the kernel will check the shebang to decide what instructions to expect/run. So running./hello_world
would mean the same right or am I missing the point here?
– Valentin Bajrami
4 hours ago
@ValentinBajrami, no, they execute on different way. Think about no execution flag on the file.
– Romeo Ninov
4 hours ago
add a comment |
Executing command on this way:
bash hello_world
you make bash
read from file hello_world
(which is not forbidden).
In other cases OS try to run this file hello_world
and fail because of noexec
flag
Executing command on this way:
bash hello_world
you make bash
read from file hello_world
(which is not forbidden).
In other cases OS try to run this file hello_world
and fail because of noexec
flag
answered 4 hours ago
Romeo Ninov
5,13231827
5,13231827
Well the kernel will check the shebang to decide what instructions to expect/run. So running./hello_world
would mean the same right or am I missing the point here?
– Valentin Bajrami
4 hours ago
@ValentinBajrami, no, they execute on different way. Think about no execution flag on the file.
– Romeo Ninov
4 hours ago
add a comment |
Well the kernel will check the shebang to decide what instructions to expect/run. So running./hello_world
would mean the same right or am I missing the point here?
– Valentin Bajrami
4 hours ago
@ValentinBajrami, no, they execute on different way. Think about no execution flag on the file.
– Romeo Ninov
4 hours ago
Well the kernel will check the shebang to decide what instructions to expect/run. So running
./hello_world
would mean the same right or am I missing the point here?– Valentin Bajrami
4 hours ago
Well the kernel will check the shebang to decide what instructions to expect/run. So running
./hello_world
would mean the same right or am I missing the point here?– Valentin Bajrami
4 hours ago
@ValentinBajrami, no, they execute on different way. Think about no execution flag on the file.
– Romeo Ninov
4 hours ago
@ValentinBajrami, no, they execute on different way. Think about no execution flag on the file.
– Romeo Ninov
4 hours ago
add a comment |
What's happening in both cases is the same: to execute a file directly, the execute bit needs to be set, and the filesystem can't be mounted noexec. But these things don't stop reading those files.
The noexec filesystem option just plain isn't as smart as you'd like it to be. In the case of the bash script run as ./hello_world
, the #!
line isn't even checked, because the system sees that it should ignore the executable bit before even trying to run the file.
In the case of bash ./hello_world
, the script is never "executed" in the relevant sense. Instead, /bin/bash
is, and that then loads the file and does stuff. In the case of bash or another shell, the "stuff" is "execute a bunch of commands", but _now we're "past" anything that's going to check file execute bits. That check isn't responsible for what happens later.
Consider this case:
$ cat hello_world | /bin/bash
… or for those who do not like Pointless Use of Cat:
$ /bin/bash < hello_world
The "shbang" #!
sequence at the beginning of a file is just some nice magic for doing exactly the same thing — when you try to execute the file as a command. You might find this LWN.net article helpful: How programs get run.
add a comment |
What's happening in both cases is the same: to execute a file directly, the execute bit needs to be set, and the filesystem can't be mounted noexec. But these things don't stop reading those files.
The noexec filesystem option just plain isn't as smart as you'd like it to be. In the case of the bash script run as ./hello_world
, the #!
line isn't even checked, because the system sees that it should ignore the executable bit before even trying to run the file.
In the case of bash ./hello_world
, the script is never "executed" in the relevant sense. Instead, /bin/bash
is, and that then loads the file and does stuff. In the case of bash or another shell, the "stuff" is "execute a bunch of commands", but _now we're "past" anything that's going to check file execute bits. That check isn't responsible for what happens later.
Consider this case:
$ cat hello_world | /bin/bash
… or for those who do not like Pointless Use of Cat:
$ /bin/bash < hello_world
The "shbang" #!
sequence at the beginning of a file is just some nice magic for doing exactly the same thing — when you try to execute the file as a command. You might find this LWN.net article helpful: How programs get run.
add a comment |
What's happening in both cases is the same: to execute a file directly, the execute bit needs to be set, and the filesystem can't be mounted noexec. But these things don't stop reading those files.
The noexec filesystem option just plain isn't as smart as you'd like it to be. In the case of the bash script run as ./hello_world
, the #!
line isn't even checked, because the system sees that it should ignore the executable bit before even trying to run the file.
In the case of bash ./hello_world
, the script is never "executed" in the relevant sense. Instead, /bin/bash
is, and that then loads the file and does stuff. In the case of bash or another shell, the "stuff" is "execute a bunch of commands", but _now we're "past" anything that's going to check file execute bits. That check isn't responsible for what happens later.
Consider this case:
$ cat hello_world | /bin/bash
… or for those who do not like Pointless Use of Cat:
$ /bin/bash < hello_world
The "shbang" #!
sequence at the beginning of a file is just some nice magic for doing exactly the same thing — when you try to execute the file as a command. You might find this LWN.net article helpful: How programs get run.
What's happening in both cases is the same: to execute a file directly, the execute bit needs to be set, and the filesystem can't be mounted noexec. But these things don't stop reading those files.
The noexec filesystem option just plain isn't as smart as you'd like it to be. In the case of the bash script run as ./hello_world
, the #!
line isn't even checked, because the system sees that it should ignore the executable bit before even trying to run the file.
In the case of bash ./hello_world
, the script is never "executed" in the relevant sense. Instead, /bin/bash
is, and that then loads the file and does stuff. In the case of bash or another shell, the "stuff" is "execute a bunch of commands", but _now we're "past" anything that's going to check file execute bits. That check isn't responsible for what happens later.
Consider this case:
$ cat hello_world | /bin/bash
… or for those who do not like Pointless Use of Cat:
$ /bin/bash < hello_world
The "shbang" #!
sequence at the beginning of a file is just some nice magic for doing exactly the same thing — when you try to execute the file as a command. You might find this LWN.net article helpful: How programs get run.
edited 2 hours ago
answered 4 hours ago
mattdm
27.9k1172111
27.9k1172111
add a comment |
add a comment |
Because the bash executable doesn't reside on said filesystem.
1
That is true but running./hello_world
would also us/bin/bash
which doesn't reside on a file system withnoexec
option mounted. If that is true then thec
program would run as well corerct?
– Valentin Bajrami
4 hours ago
1
Nope. That's not the way it works.
– tink
4 hours ago
add a comment |
Because the bash executable doesn't reside on said filesystem.
1
That is true but running./hello_world
would also us/bin/bash
which doesn't reside on a file system withnoexec
option mounted. If that is true then thec
program would run as well corerct?
– Valentin Bajrami
4 hours ago
1
Nope. That's not the way it works.
– tink
4 hours ago
add a comment |
Because the bash executable doesn't reside on said filesystem.
Because the bash executable doesn't reside on said filesystem.
answered 4 hours ago
tink
4,12811218
4,12811218
1
That is true but running./hello_world
would also us/bin/bash
which doesn't reside on a file system withnoexec
option mounted. If that is true then thec
program would run as well corerct?
– Valentin Bajrami
4 hours ago
1
Nope. That's not the way it works.
– tink
4 hours ago
add a comment |
1
That is true but running./hello_world
would also us/bin/bash
which doesn't reside on a file system withnoexec
option mounted. If that is true then thec
program would run as well corerct?
– Valentin Bajrami
4 hours ago
1
Nope. That's not the way it works.
– tink
4 hours ago
1
1
That is true but running
./hello_world
would also us /bin/bash
which doesn't reside on a file system with noexec
option mounted. If that is true then the c
program would run as well corerct?– Valentin Bajrami
4 hours ago
That is true but running
./hello_world
would also us /bin/bash
which doesn't reside on a file system with noexec
option mounted. If that is true then the c
program would run as well corerct?– Valentin Bajrami
4 hours ago
1
1
Nope. That's not the way it works.
– tink
4 hours ago
Nope. That's not the way it works.
– tink
4 hours ago
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f490402%2fexecuting-a-bash-script-or-a-c-binary-on-a-file-system-with-noexec-option%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown