5

This question already has an answer here:

Assuming that you can't reach the internet nor reboot the machine, how can I recover from

chmod -x chmod

?

marked as duplicate by Gilles permissions Jul 14 '16 at 18:01

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

7

1 - use a programming language that implements chmod

Ruby:

ruby -e 'require "fileutils"; FileUtils.chmod 0755, “chmod"'

Python:

python -c "import os;os.chmod('/bin/chmod', 0755)”

Perl:

perl -e 'chmod 0755, “chmod”'

Node.js:

require("fs").chmod("/bin/chmod", 0755);

C:

$ cat - > restore_chmod.c 
#include <sys/types.h>
#include <sys/stat.h>

int main () {
    chmod( "/bin/chmod", 0000755 );
}
^D

$ cc restore_chmod.c

$ ./a.out

2 - Create another executable with chmod

By creating an executable:

$ cat - > chmod.c 
int main () { }
^D

$ cc chmod.c

$ cat /bin/chmod > a.out

By copying an executable:

$ cp cat new_chmod

$ cat chmod > new_chmod

3 - Launch BusyBox (it has chmod inside)

4 - Using Gnu Tar

Create an archive with specific permissions and use it to restore chmod:

$ tar --mode 0755 -cf chmod.tar /bin/chmod

$ tar xvf chmod.tar

Do the same thing but on the fly, not even bothering to create the file:

tar --mode 755 -cvf - chmod | tar xvf -

Open a socket to another machine, create an archive and restore it locally:

$ tar --preserve-permissions -cf chmod.tar chmod

$ tar xvf chmod.tar

Another possibility would be to create the archive regularly and then editing it to alter the permissions.

5 - cpio

cpio allows you to manipulate archives; when you run cpio file, after the first 21 bytes there are three bytes that indicate the file permissions; if you edit those, you're good to go:

echo chmod |
  cpio -o |
  perl -pe 's/^(.{21}).../${1}755/' |
  cpio -i -u

6 - Dynamic loaders

/bin/ld.so chmod +x chmod

(actual paths may vary)

7 - /proc wizardry (untested)

Step by step:

  • Do something that forces the inode into cache (attrib, ls -@, etc.)
  • Check kcore for the VFS structures
  • Use sed or something similar to alter the execution bit without the kernel realising it
  • Run chmod +x chmod once

8 - Time Travel (git; yet untested)

First, let's make sure we don't get everything else in the way as well:

$ mkdir sandbox
$ mv chmod sandbox/
$ cd sandbox

Now let's create a repository and tag it to something we can go back to:

$ git init
$ git add chmod
$ git commit -m '1985'

And now for the time travel:

$ rm chmod
$ git-update-index --chmod=+x chmod
$ git checkout '1985'

There should be a bunch of git-based solutions, but I should warn you that you may hit a git script that actually tries to use the system's chmod

9 - Fighting Fire with Fire

It would be great if we could fight an Operating System with another Operating System. Namely, if we were able to launch an Operating System inside the machine and have it have access to the outer file system. Unfortunately, pretty much every Operating System you launch is going to be in some kind of Docker, Container, Jail, etc. So, sadly, that is not possible.

Or is it?

Here is the EMACs solution:

Ctrl+x b > *scratch* 
(set-file-modes "/bin/chmod" (string-to-number "0755" 8))
Ctrl+j

10 - Vim

The only problem with the EMACs solution is that I'm actually a Vim kind of guy. When I first delved into this topic Vim didn't have a way to do this, but in recent years someone made amends with the universe, which means we can now do this:

vim -c "call setfperm('chmod', 'rwxrwxrwx') | quit"

Not the answer you're looking for? Browse other questions tagged or ask your own question.