/usr/bin/vim vs. /bin/vim

vim

I get that binaries can be in different places. What I don't understand is why when I run whereis, which and type it says vim is at /usr/bin/vim, but when I try to run it using sudo it says I can't run /bin/vim.

They are not links, and their content is the same. But I have persmission to perform sudo on /usr/bin/vim, which is not being called and I have no idea why!

[user@host conf.d]$ sudo vim test.conf
[sudo] password for user: 
Sorry, user user is not allowed to execute '/bin/vim test.conf' as root on host.domain.com.br.
[user@host conf.d]$ whereis vim
vim: /usr/bin/vim /usr/share/vim /usr/share/man/man1/vim.1.gz
[user@host conf.d]$ which vim
/usr/bin/vim
[user@host conf.d]$ type vim
vim is /usr/bin/vim
[user@host conf.d]$ ll /bin/vi*
-rwxr-xr-x. 1 root root  910040 Jun 10 03:56 /bin/vi
lrwxrwxrwx. 1 root root       2 Set 30 11:38 /bin/view -> vi
-rwxr-xr-x. 1 root root 2289656 Jun 10 03:56 /bin/vim
lrwxrwxrwx. 1 root root       3 Set 30 12:14 /bin/vimdiff -> vim
-rwxr-xr-x. 1 root root    2084 Jun 10 03:56 /bin/vimtutor
[user@host conf.d]$ ll /usr/bin/vi*
-rwxr-xr-x. 1 root root  910040 Jun 10 03:56 /usr/bin/vi
lrwxrwxrwx. 1 root root       2 Set 30 11:38 /usr/bin/view -> vi
-rwxr-xr-x. 1 root root 2289656 Jun 10 03:56 /usr/bin/vim
lrwxrwxrwx. 1 root root       3 Set 30 12:14 /usr/bin/vimdiff -> vim
-rwxr-xr-x. 1 root root    2084 Jun 10 03:56 /usr/bin/vimtutor
[user@host conf.d]$ md5sum /usr/bin/vim
e5a9c498add4fa49a39a720a826f954c  /usr/bin/vim
[user@host conf.d]$ md5sum /bin/vim
e5a9c498add4fa49a39a720a826f954c  /bin/vim
[user@host conf.d]$ 

Best Answer

Some basics about search paths

When you run a command that does not contain slashes, such as vim, the shell needs to know which file (or shell builtin/function) to execute. It finds this by following the search path, defined in the PATH environment variable. The PATH variable is a list of paths separated by colons, and the shell will look for the command name within each of those paths in that order.

For example, a basic PATH from a Debian installation looks like the following:

/usr/local/bin:/usr/bin:/bin

In this case, you find /usr/bin/vim first, as shown by the output of which vim and type vim.

Now, when you run a command via sudo where the env_reset and secure_path options are specified, sudo will reset the search path to the contents of secure_path before executing the command you pass it. This means that a command you run via sudo could have a different search path, and could find a different executable from running the command directly.

For example, a basic sudo PATH from Debian:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Your scenario

What I suspect is happening here is your secure_path either specifies an order where /bin comes before /usr/bin, or the latter does not exist at all. In that case, the shell will look for vim and eventually find /bin/vim, since that exists. And if only /usr/bin/vim is whitelisted, then the former may not be allowed to run.

You can check your current PATH with echo $PATH. You can check your sudo's PATH with sudo env | grep PATH. If your admin has set whitelists only allowing vim, then you can go into sudo vim and run the command :echo $PATH.

You should be able to get around it by specifying an absolute path, i.e. sudo /usr/bin/vim.


Why does search_path exist?

As for why sudo sets a different path, consider this attack scenario:

Your PATH is just an environment variable. It can be set in many different ways, possibly invisible to the user. You could have insecure directories in it that allow anyone to write to them. If someone creates a malicious executable file named something like ls, then when you run ls you'd be executing this file instead of the real ls.

But the damage would be limited to what your account has access to. Now, say you run sudo ls - if the PATH is taken from your current PATH rather than being reset, then you've now run a malicious executable with root privileges - a privilege escalation attack. Far more possible damage than just running as your own user.

Now, you can argue that an attacker with the ability to place files in your PATH or otherwise modify your PATH can already do a lot of damage. And you're probably right. There's opinions on both sides about the usefulness of secure_path, which I won't get into here.

Related Question