Why is root user denied access to a file?
I would like to understand in which cases root can be denied access to a file. I am working on a machine I didn't configure (on my personal laptop I obivously don't have this problem) and I am having this problem which can be boiled down to simply this:
touch test.sh &&\
echo 'echo $PATH' >> test.sh &&\
sudo sh test.sh
will give the error: sh: 0: Can't open test.sh
(bash: test.sh: Permission denied
with bash
).
I tried to see if I was under SELinux by running
getenforce
, but the command was not found.I tried
sudo chown root test.sh
, but it gives the error:chown: cannot access 'test.sh': Permission denied
.Same thing happened when trying to change the ownership of the directory.
I am not necessarily asking for a solution to the overall problem but I want to understand how it's possible that root is denied some access.
EDIT
On the same machine, if I create a local user (all the above was done as a user logged in via a shared network), all works fine.
Solution 1:
tl;dr if you run
export PATH=.:$PATH # wrong
then your above mentioned set of commands will ~~work~~ however avoid this solution ... Why ? ... when you run an executable giving it either a full path
/my/cool/binary
or relative path
./../cool/binary # notice this begins with a ./ period slash
you directly control where the executable is coming from ... however if by mistake or by some rogue process your env var PATH gets updated with a prepend of a dir(s) which contains (wrong or malicious) executables with matching names
export PATH=/wrong/dir:/hackers/own/dir:$PATH
and you just use
myexecutable_name # using naked binary name
you could be running
/wrong/dir/myexecutable_name
when you intended to run
/actual/good/dir/myexecutable_name
which is why production code or anything run as root should explicitly spell out where the binary is coming from
Now going back to your original question ... your code assumes PATH includes current dir '.' which it should not contain for prod ids or root
export PATH=.:$PATH # wrong - bad for root or prod id yet handy for dev folks
instead execute using full path ... problem is you want to avoid possibility of running wrong binary which happens to be in your current dir when you intended to run binary from the standard dir as defined in your PATH
Not convinced ? spend some quality time with critical infrastructure code especially which is at an intersection between responsibilities ... where team B binary is executing a binary from team A and you will always see full path used ... another inspiration is to beef up on namespace conflicts