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