Sudo and Filesystem Permissions

roundchk

New Member
Joined
Jan 12, 2024
Messages
3
Reaction score
4
Credits
45
I was researching an issue recently that really threw me off, I solved the issue but I don't exactly understand why the solution works and was hoping for someone that can confirm my understanding and maybe share some insight. ChatGPT gave me an explanation that I can't find in any official documents or in the man page for sudo or on the website for sudo.

The problem: You are logged in as a user with sudo privileges and you want to copy files from a directory you don't have permissions to. The command sudo cp /var/example/files* ~/dest/ fails with the error message "cp: cannot stat '/var/example/files*': No such file or directory". The assumption was that with sudo your command (mv or cp) runs with root privileges and yet here we find, seemingly, that root could not access the source directory. The directory "example" has chmod 700 in this scenario and chown root:root, and within that directory the user actually owns the files.

The solution: This was fixed by expanding the permissions of the example directory to chmod 777 and the best response I got from ChatGPT in trying to understand the nature of this issue was this; "sudo does not circumvent file system permissions during its own execution; it escalates privileges for the command it is executing."

Final Thoughts:
ChatGPT seems to explain the situation in an obvious way, which seems valid after solving the problem, I don't know if it's inferring an explanation from the situation or giving me an actual explanation. There is no explanation of this fact in the man pages for sudo, I could not find an explanation from the community in my searches (my searches could have been bad). I even tried crawling the source code of sudo but got a bit exhausted by that. The best I can say is I confirmed that response of course by launching an actual root shell sudo su - and sure enough the same command above with the same original directory permissions works as expected.

I'm either crazy, something else entirely is going on, or it is that simple.

Is this a revelation about sudo for anyone else?
Can anyone help me identify an official explanation for this behavior with sudo?
And does anyone know other interesting or generally unexpected sudo behaviors?
 


Sudo uses the user's environment, not root's. That's reflected in sudo's use of the user's password. That means that the filesystems available to the user are accessible.

EDIT: I found the AI answer by Bard more explanatory, so I'm reproducing it here:
Code:
Here's a breakdown of what it means that sudo keeps the user's environment in Linux:

- Environment Variables:

    Linux uses environment variables to store settings and information that programs can use.
    They include things like:
        HOME directory
        PATH (where to find executable programs)
        SHELL (default command interpreter)
        USER and LOGNAME (current user's name)

- sudo's Default Behavior:

    When you run a command with sudo, it typically creates a new, sanitized environment for security reasons.
    This means most of your user's environment variables are not passed to the command being run as root.
    However, sudo does preserve a minimal set of essential variables by default:
        TERM
        PATH
        HOME
        MAIL
        SHELL
        LOGNAME
        USER
        SUDO_* (variables set by sudo itself)

- Preserving Specific Variables:

    If you need to keep additional environment variables for a specific command, you have several options:
        -E or --preserve-env flag: This tells sudo to preserve all of the user's environment variables. Example: sudo -E command
        Setting variables within the command: You can set variables directly within the sudo command. Example: sudo VARIABLE=value command
        Defaults env_keep in /etc/sudoers: This allows you to specify variables to preserve for all sudo commands.
        Environment files: You can create environment files (e.g., in /etc/sudoers.d) to specify variables for specific commands or users.

- Security Considerations:

    It's essential to be cautious when preserving environment variables with sudo.
    Untrusted variables could potentially be exploited for malicious purposes.
    Only preserve variables that are genuinely necessary for the command to function correctly.

- Key Points:

    sudo doesn't preserve the entire user environment by default.
    It's possible to control which variables are kept for specific commands or globally.
    Consider security implications before preserving variables.
 
Last edited:
I'm either crazy, something else entirely is going on, or it is that simple.
Personally, after exhausting all the seriously deep "fixes", I find the simple works....every time.

Remember.....Linux....k.i.s.s
 
hmm.. do you have files* in the directory?
you are trying to copy a file named "file"
Because file named file does not exist in specific directory you are getting this error.
If you want to copy all files from /var/example/
you run
cp /var/example/* ~/dest/
if these are root's files only root can manipulate these files. I doubt that in ../examples/.. you will have files belonging to root
 
hmm.. do you have files* in the directory?
you are trying to copy a file named "file"
Because file named file does not exist in specific directory you are getting this error.
If you want to copy all files from /var/example/
you run
cp /var/example/* ~/dest/
if these are root's files only root can manipulate these files. I doubt that in ../examples/.. you will have files belonging to root

Well, he clearly knows his way around the system.

He must have something like:
/var/example/files01
/var/example/files02
/var/example/files03
...
and so on...

The goal is to copy that group of files, not all the files in that directory. The operation is perfectly valid and the files are present. This is confirmed beforehand.

The same operation works perfectly well if he first invokes sudo su -

The question is why is a sudoer (not root) facing so many challenges while attempting to complete the same operation using the "sudo" prepend.
 
He must have something like:
/var/example/files01
/var/example/files02
/var/example/files03
then
cp /var/example/files* would clearly work.

cp: cannot stat '/var/example/files*': No such file or directory.
Means incorrectly specified dir/file name
If files belong to root, you will get insufficient privilege error:
error: cannot stat 'file': Permission denied
you don't have enough permissions
 
then
cp /var/example/files* would clearly work.


Means incorrectly specified dir/file name
If files belong to root, you will get insufficient privilege error:

you don't have enough permissions
You must not have read my post, I wasn't asking you to solve a problem because I already did.

The real question is, does any documentation exist anywhere that actually clearly outlines this aspect of sudo? I couldn't find anything, as I outlined, even the man files don't explain this aspect of the sudo command. And then in addition to that, are there other edge cases someone should know? This thread can help future people searching google get a better grasp on sudo.
 
@roundchk - might I just ask the following question?

What were the files actually named? First 3 or 4 would suffice.

If the files and example folder no longer exist, perhaps you can reproduce the exercise and let me know.

TIA

Wizard

... and welcome to linux.org both @roundchk and @ruyelpequenocid :)

Chris Turner
wizardfromoz
 
I replicated your example as in how you described the situation.
Code:
[maarten@lilith ~]$ ls -l | grep example
drwxr-xr-x 1 maarten maarten   0 Jan 13 09:36 dest-example
drwx------ 1 root    root     30 Jan 13 09:31 example
[maarten@lilith ~]$ sudo ls -l example/
total 0
-rw------- 1 maarten maarten 0 Jan 13 09:31 file1
-rw------- 1 maarten maarten 0 Jan 13 09:31 file2
-rw------- 1 maarten maarten 0 Jan 13 09:31 file3
I got the same results, but only when doing a wildcard copy.
Code:
[maarten@lilith ~]$ sudo cp example/file* dest-example/
cp: cannot stat 'example/file*': No such file or directory
[maarten@lilith ~]$ echo $?
1
However when you don't use a wildcard but a specific filename the copy is successful.
Code:
[maarten@lilith ~]$ sudo cp example/file1 dest-example/
[maarten@lilith ~]$ echo $?
0
[maarten@lilith ~]$ ls -l dest-example/
total 0
-rw------- 1 root root 0 Jan 13 09:41 file1
So that would make me think it has to do something with globbing in combination with sudo, because in the example where I copy a specific file the user owned files are still in the directory owned by root with 700 permissions.

I did a search and came across these answers, both explain why sudo behaves differently when using globbing.

So you want the glob to be expanded by the root user and not by your user, in practice that looks like this.
Code:
[maarten@lilith ~]$ sudo bash -c "cp example/file* dest-example/"
[maarten@lilith ~]$ echo $?
0
[maarten@lilith ~]$ ls -l dest-example/
total 0
-rw------- 1 root root 0 Jan 13 09:51 file1
-rw------- 1 root root 0 Jan 13 09:51 file2
-rw------- 1 root root 0 Jan 13 09:51 file3
In conclusion this has to do with globbing in combination with sudo and not with something strange/undocumented thing going on with sudo.
 
Last edited:
I replicated your example as in how you described the situation.
Code:
[maarten@lilith ~]$ ls -l | grep example
drwxr-xr-x 1 maarten maarten   0 Jan 13 09:36 dest-example
drwx------ 1 root    root     30 Jan 13 09:31 example
[maarten@lilith ~]$ sudo ls -l example/
total 0
-rw------- 1 maarten maarten 0 Jan 13 09:31 file1
-rw------- 1 maarten maarten 0 Jan 13 09:31 file2
-rw------- 1 maarten maarten 0 Jan 13 09:31 file3
I got the same results, but only when doing a wildcard copy.
Code:
[maarten@lilith ~]$ sudo cp example/file* dest-example/
cp: cannot stat 'example/file*': No such file or directory
[maarten@lilith ~]$ echo $?
1
However when you don't use a wildcard but a specific filename the copy is successful.
Code:
[maarten@lilith ~]$ sudo cp example/file1 dest-example/
[maarten@lilith ~]$ echo $?
0
[maarten@lilith ~]$ ls -l dest-example/
total 0
-rw------- 1 root root 0 Jan 13 09:41 file1
So that would make me think it has to do something with globbing in combination with sudo, because in the example where I copy a specific file the user owned files are still in the directory owned by root with 700 permissions.

I did a search and came across these answers, both explain why sudo behaves differently when using globbing.

So you want the glob to be expanded by the root user and not by your user, in practice that looks like this.
Code:
[maarten@lilith ~]$ sudo bash -c "cp example/file* dest-example/"
[maarten@lilith ~]$ echo $?
0
[maarten@lilith ~]$ ls -l dest-example/
total 0
-rw------- 1 root root 0 Jan 13 09:51 file1
-rw------- 1 root root 0 Jan 13 09:51 file2
-rw------- 1 root root 0 Jan 13 09:51 file3
In conclusion this has to do with globbing in combination with sudo and not with something strange/undocumented thing going on with sudo.

Same here.

If I copy a single file the operation succeds.

But if I use the wildcard * (in any fashion) the operation fails.

I think that answer from StackOverflow you found and shared with us is spot on when it says: "The globbing you are performing takes place before the sudo is executed".
 
@f33dm3bits That's interesting, I never came across that stackoverflow which clarifies that globbing takes place before sudo actually runs. I specifically tried to strace the sudo command to see if something like that was going on but didn't get that level of detail from strace so it never stood out to me.

That definitely helps more specifically explain what's going on, thank you!
 
Last edited:
Actually, I'd like to set the record straight here, on some input which is only half correct, and some of which is incorrect.

Don't take anything personal out of this, please. I do this purely to be sure that the information provided at this site is as accurate as possible :)

For those of you who are interested, see the information I provide in the Spoiler below (click the header to open, and click to close again). This was performed on my Fedora 39 for the RPM side, but I have also performed it on, and with the same results

  • Gecko Linux (based on openSUSE)
  • Calculate Linux (based on Gentoo)
  • Debian Linux 12 Bookworm
  • Ubuntu and its flavours
  • Linux Mint
  • Arch-based distros such as Manjaro, Arcolinux, and so on
I will provide my conclusions at the end.

chris@Fedora39:~$ mkdir ~/dest
chris@Fedora39:~$ sudo mkdir /var/example
[sudo] password for chris:
chris@Fedora39:~$ cd /var/example
chris@Fedora39:/var/example$ sudo touch files{01..05}
chris@Fedora39:/var/example$ ls -l
total 0
-rw-r--r--. 1 root root 0 Jan 14 15:46 files01
-rw-r--r--. 1 root root 0 Jan 14 15:46 files02
-rw-r--r--. 1 root root 0 Jan 14 15:46 files03
-rw-r--r--. 1 root root 0 Jan 14 15:46 files04
-rw-r--r--. 1 root root 0 Jan 14 15:46 files05
chris@Fedora39:/var/example$ sudo chown chris:chris files*
chris@Fedora39:/var/example$ ls -l
total 0
-rw-r--r--. 1 chris chris 0 Jan 14 15:46 files01
-rw-r--r--. 1 chris chris 0 Jan 14 15:46 files02
-rw-r--r--. 1 chris chris 0 Jan 14 15:46 files03
-rw-r--r--. 1 chris chris 0 Jan 14 15:46 files04
-rw-r--r--. 1 chris chris 0 Jan 14 15:46 files05
chris@Fedora39:/var/example$ sudo chmod 700 /var/example
chris@Fedora39:/var/example$ cd ~
chris@Fedora39:~$ sudo cp /var/example/files* ~/dest
cp: cannot stat '/var/example/files*': No such file or directory
chris@Fedora39:~$ sudo chmod 755 /var/example
chris@Fedora39:~$ sudo cp /var/example/files* ~/dest
chris@Fedora39:~$ ls -l ~/dest
total 0
-rw-r--r--. 1 root root 0 Jan 14 15:52 files01
-rw-r--r--. 1 root root 0 Jan 14 15:52 files02
-rw-r--r--. 1 root root 0 Jan 14 15:52 files03
-rw-r--r--. 1 root root 0 Jan 14 15:52 files04
-rw-r--r--. 1 root root 0 Jan 14 15:52 files05
chris@Fedora39:~$

A number of The Viewers can likely see where I am going with this.

On incorrect input, #6 from @Aristarchus

He must have something like:
/var/example/files01
/var/example/files02
/var/example/files03
then
cp /var/example/files* would clearly work.


cp: cannot stat '/var/example/files*': No such file or directory.
Means incorrectly specified dir/file name
If files belong to root, you will get insufficient privilege error:

error: cannot stat 'file': Permission denied
you don't have enough permissions

I can say No, No, and partly Yes but for other reasons.

For the OP @roundchk , if you had first performed, from ~

Code:
ls -l /

and. once you created /var/example

Code:
ls -l /var

you would have seen them be defined as being mostly of 755 level, that is

drwxr-xr-x

The only folders in / which have 700 are lost+found and root

Arch-based are an exception to that base, using 750 for root, that is

drwxr-x---

Once /var/example is changed to 755, the operation goes through with allowing globbing and copying the files to ~/dest

However, the files copied end up being owned by Root, which you may not want.

If you were to use, under a 755 environment for /var/example

Code:
cp files* ~/dest

that works, and the copied files are owned by the user.

Hope this clarifies things.

Cheers

Chris Turner
wizardfromoz
 
I usually come across directories I have no rights for when I make changes to the partition, such as formatting it and/or mounting it with a different name. And since I always forget to change the permissions after that, I always get a message like "insufficient permissions". But I also have an alias with which I fix the problem easily. The alias is ownrado and this is the command behind it:

Code:
sudo chown -Rv rado:rado

After I set that, all future files and dirs automatically inherit those permissions.
Or, if the target dir is in on the root partitions, I use the same command, only instead of "rado:rado", it's "root:root" after which using sudo to modify the dir works like a charm.
 

Members online


Latest posts

Top