Score:22

How to fix "chmod" permissions after running "chmod 222 /bin/chmod"?

ru flag

I ran chmod 222 /bin/chmod to know more about chmod. After that, when I run /bin/chmod, I get permission denied.

I tried to change the permissions of chmod back to 755, but it doesn't work.

Does anyone have tips about how to fix this?

Artur Meinild avatar
vn flag
What I find most fascinating is the ingenuity of the answers here. So far there are 8 different ways to restore 755 permissions to `chmod`.
Joshua avatar
cz flag
@U.Windl: It's one finger misposition off chmod 111, which is sane.
Score:44
cn flag
raj

You made chmod not executable.

There are three (no, actually four) options to revert from this situation:

  1. Reinstall the coreutils package, as mentioned in Artur Meinild's answer.

  2. My preferred solution:

    • boot from an installation medium and start a live Ubuntu session.

    • start the Disks application, find the partition where your Ubuntu installation resides and mount it. Note the path where the partition is mounted (something like /media/username/somename).

    • open a terminal and run:

      sudo chmod 755 /media/username/somename/usr/bin/chmod
      
    • unmount the partition, shutdown the live session and reboot from your normal installation.

  3. Be VERY CAREFUL when doing this! Run the following commands:

    sudo cp -p /usr/bin/ls /tmp/chmod
    sudo cp /usr/bin/chmod /tmp/chmod
    sudo /tmp/chmod 755 /usr/bin/chmod
    

    Explanation: first, we copy another file that is still executable (I chose /usr/bin/ls) to /tmp/chmod. By using the -p parameter to the cp command, we are preserving permissions, so we ensure that the resulting file is also executable.

    Next, we overwrite the just created /tmp/chmod file with the contents of actual /usr/bin/chmod, but without preserving permissions. The contents of /tmp/chmod is overwritten with actual chmod, but it is still executable.

    So we can use /tmp/chmod to restore permissions on the actual /usr/bin/chmod.

    Optionally we can delete /tmp/chmod, which is no more needed, but it is not necessary; on the next system boot, /tmp directory will be cleared anyway.

  4. You can use any programming language that supports the chmod() system call. As Ubuntu by default contains the Python interpreter, it would be probably easiest to use Python:

    sudo python3 -c 'import os; os.chmod("/usr/bin/chmod", 0755)'
    
cn flag
Option 4 is very simple, and there are several languages that are likely to be available: python, perl, php.
TripeHound avatar
us flag
+1. I had to discover option 3 for myself back in the 90s on a SCO Unix system after I'd (accidentally) removed execute permission from everything in `/bin` by mistake. The emergency boot disk had executable binaries on it, but _not_ a copy of `chmod`!
Josh avatar
id flag
+1 for mentioning my favorite clever solution: using `cp` to just copy a different binary with appropriate permissions and overwrite it
August Janse avatar
tr flag
Why is 2 your preferred solution? The others seem easier.
tz flag
@AugustJanse : 2 is way more flexible and powerfull: could help restore many things from a sane distro (permissions, suid, owners, etc, using that distro as a reference)
raj avatar
cn flag
raj
@AugustJanse I just think it's a "proper" or "canonical" (nothing related to a company name ;)) way to fix such an issue. The first is an overkill, the two others are a bit "hackish". And as mentioned in the comment above, this method is generally used to fix many other broken things.
user3840170 avatar
in flag
Isn’t `/tmp` mounted noexec in Ubuntu?
raj avatar
cn flag
raj
@user3840170 `/tmp` usually isn't a separate filesystem at all. It's just a regular directory under the root filesystem, at least in default install.
Score:25
jp flag

With rsync

rsync is available by default on Ubuntu ... In --archive, -a mode, it should only set the permissions (since the file will never change) ... i.e. when used in one shot like so:

$ sudo rsync -a --chmod=755 /bin/chmod /bin/chmod

With the install command

There is another utility called install from GNU core utilities as well which should be available by default on your system … It’s mainly used for copying just compiled files and make them executable i.e. install them and hence the name … It should give the copied file the permissions of rwxr-xr-x by default ... It also has the option -m to alter permissions of that file selectively on-the-fly (while you might not need that option in this case as the defaults should suffice), but you can always do:

$ sudo install -m +x /bin/chmod mychmod

Then, you can simply do:

$ sudo ./mychmod 755 /bin/chmod

With the dynamic linker/loader

Another simple solution as well is to use the dynamic linker/loader itself ... This is a special way of running binaries as it doesn’t require permissions to do so (It is somewhat similar to running a non-executable shell script by passing it as an argument to /bin/sh for example) … Depending on the architecture your binary was compiled for, you most likely want to use the amd64 variant ... Find its name and path on your system with for example:

$ dpkg -S 'ld-linux*'
manpages: /usr/share/man/man8/ld-linux.8.gz
manpages: /usr/share/man/man8/ld-linux.so.8.gz
libc6:amd64: /lib64/ld-linux-x86-64.so.2
libc6:i386: /lib/i386-linux-gnu/ld-linux.so.2
libc6-i386: /lib32/ld-linux.so.2
libc6:i386: /lib/ld-linux.so.2
libc6:amd64: /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2

Then, simply use it in one shot like so:

$ sudo /lib64/ld-linux-x86-64.so.2 /bin/chmod 755 /bin/chmod

Else ...

Search your system for other utilities that can change/set file permissions ... One way is to search the manuals with e.g. man -K "chmod" ... Here are some of what I found on my system:

chacl(change the access control list of a file or directory):

$ sudo chacl u::rwx,g::r-x,o::r-x /bin/chmod

bwrap(container setup utility):

$ sudo bwrap --die-with-parent --bind / / --chmod 755 /bin/chmod -- /bin/true
marcelm avatar
cn flag
Re: dynamic loader: On Debian, and I assume Ubuntu as well, `/usr/bin/ld.so` does the same thing, so the slightly simpler `ld.so /bin/chmod 755 /bin/chmod` would suffice!
hr flag
AFAIK using the dynamic loader requires that `/bin/chmod` still has *read* permission I think? So that method would work for mode `6xx` or `4xx` but not `2xx`
ilkkachu avatar
co flag
@steeldriver, and Raffa, it still needs to, yes (`cp /bin/ls ./ls; chmod 0 ./ls; /lib64/ld-linux-x86-64.so.2 ./ls` and I get an error). But if you're running it as root, you get to ignore such pesky details as the permission bits, as root usually does, so it works there. Nothing to do with the dynamic loader being special here. (That's not to say it wouldn't be special when the kernel loads it as part of the normal process of executing a binary file, but that's what we're doing here.)
Raffa avatar
jp flag
@ilkkachu Ah I see what you mean, ... It should be invoked as the super user with `sudo` as in the example in my answer.
ilkkachu avatar
co flag
yes exactly, sudo makes the execution work here. (and of course that should be "that's _not_ what we're doing here." at the end of my last comment, blah.)
Raffa avatar
jp flag
@ilkkachu and @steeldriver ... In the sense of reading the file initially yes, both of you are right, but `sudo` or super user is needed anyway for that and for setting permissions on `/bin/chmod` as well ... I was talking about particularly the loading and running/executing part hence the special notation ... I wasn't talking about the reading part though, my bad :-).
U. Windl avatar
gf flag
@ilkkachu I updated the comment: I wonder: Given the mode 222 (-w--w--w-) can ld read it? And if it can, couldn't you simply copy it to elsewhere using `umask 0222; cat /bin/chmod >chmod.copy`, and finally `chmod.copy 0755 /bin/chmod; rm chmod.copy`?
ilkkachu avatar
co flag
@U.Windl, if you mean the command in the answer above: `sudo /lib64/ld-linux-x86-64.so.2 /bin/chmod`, then yes, `ld-linux-x86-64.so.2` can read it because it's being run as root via sudo, and root is exempt from the permission bits checks on reading. With `cat /bin/chmod >chmod.copy`, and given the mode 0222 (-w--w--w-), you won't be able to read it (as a regular user), since no-one has read access on it. Also, even if you do `sudo sh -c 'cat /bin/chmod >chmod.copy'`, the new file gets created without the x permission because normally programs don't add it when creating files.
U. Windl avatar
gf flag
@ilkkachu You are right: I was assuming all non-masked bits would be set when creating a new file.
Score:22
vn flag

You did about the only thing you should never do with chmod - you changed chmod itself to not be executable. Not even the powers of sudo will make this command work again (in its current form - see the other answers though).

A way to get it working again would be to reinstall the GNU coreutils package with this command:

sudo apt install --reinstall coreutils

A general tip (that's especially important for Linux utilities): When learning about something, first read up on what each command does, secondly try out stuff in an isolated environment (container/VM), and only after that should you run commands on your production system.

chili555 avatar
cn flag
"and only *after* that should you run commands on your production system." One thousand upvotes!
Score:13
kz flag

In addition to all the other answers, if you have busybox installed, you can use that by running:

sudo busybox chmod 0755 /usr/bin/chmod

Busybox can be installed by enabling the universe repository, and then running:

sudo apt update && sudo apt install busybox
ilkkachu avatar
co flag
probably better to use `chmod 0755` to restore the permissions to what they originally were, instead of just adding the execute permission and leaving the other permissions off
ilkkachu avatar
co flag
@raj, I did wonder. Part of the reason I suggested in a comment was that I seem to have it on every Ubuntu I have access to, even ones where I don't think anyone would have explicitly installed it. The package descriptions say `busybox-static` is `Priority: standard`, which I guess it means it should be installed by default but perhaps someone will correct me.
Raffa avatar
jp flag
@ilkkachu Yes, indeed `busybox` is being shipped by default with Ubuntu for quiet a while now.
rando avatar
kz flag
@ilkkachu `busybox` has been included in most Linux distros to make initramfs generation easy.
raj avatar
cn flag
raj
@ilkkachu Indeed, it is. I assumed it's not because why anybody would need it by default on a general purpose, non space-limited system? But I have checked on my system (where I definitely did NOT install it) and it is there.
Score:12
cz flag

With on-the-fly tar mode changing (the # symbol means that the command should be run as root):

# cd /bin
# tar -mode 755 -cf chmod.tar chmod
# tar -xf chmod.tar

Old answer calling hexedit:

# cd /bin
# tar -cf chmod.tar chmod
# hexedit chmod.tar

Fix the permissions inside the tarball; it's the 0000222; change it to 0000755. Then run:

# tar -xf chmod.tar
U. Windl avatar
gf flag
Doesn't mode 222 prevent reading the file?
Joshua avatar
cz flag
@U.Windl: root don't care. (Intentional misspelling because meme)
Raffa avatar
jp flag
Ubuntu's GNU `tar` supports changing permissions on-the-fly i.e. `sudo tar --mode 0755 -cf chmod.tar /bin/chmod`.
Score:4
gf flag

According to the Emacs documentation elisp function

set-file-modes is an interactive built-in function in `C source code'.

so most likely it uses the chmodo system call.

So it seems logical to assume that in "Emacs dired" dired-do-chmod (M) will use that function too, allowing to reset the file mode by opening the /bin directory (via "C-x C-f"), locating chmod, and then pressing M to change the mode of the selected file(s).

As help explains:

M runs the command dired-do-chmod, which is an interactive autoloaded Lisp
function.

It is bound to M, <menu-bar> <operate> <chmod>.

(dired-do-chmod &optional ARG)

Change the mode of the marked (or next ARG) files.
Symbolic modes like `g+w' are allowed.
Type M-n to pull the file attributes of the file at point
into the minibuffer.
Score:3
gf flag

As any binary allowing to use the chmod(2) syscall with specific mode and file can fix the problem (as described in https://askubuntu.com/a/1483466/955948), you can add your own binary when no such binary is available (assuming a working C compiler (here: gcc) is installed):

Use this specific C program:

#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char *argv[])
{
        if (chmod("/bin/chmod", 0755) != 0) {
                perror("chmod failed");
                return 1;
        }
        return 0;
}

Then compile it, and finally execute it:

% make CFLAGS="-Wall -O" chmod
% ./chmod

(The make command will execute cc -Wall -O chmod.c -o chmod)

raj avatar
cn flag
raj
C compiler and other build tools are not installed in Ubuntu by default; you need to install them first. It's better to use some programming language that is already available with the default installation, like Perl or Python.
U. Windl avatar
gf flag
The OP did not make a statement whether it was a "default" installation. Of course `perl -e "chmod 0755, '/bin/chmod'"` would work, too. But one could also compile the needed binary on another machine. The binary, specifically when stripped, is probably less than 8kB in size.
ilkkachu avatar
co flag
if you can copy it from another system, with the copy getting the x permission bit (and being compatible wrt. any dynamic libraries), then you could likely just copy `/bin/chmod` from that other system and not need to compile anything. `scp -p /bin/chmod target:` or so.
Raffa avatar
jp flag
@ilkkachu A compatible executable copy of the binary should be available through APT download ... i.e. `mkdir extracted && apt download coreutils && dpkg-deb -xv coreutils*.deb extracted` for instance.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.