Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Today I was told a tale by a Unix trainer, a tale where the root password got leaked to the students, and one of the fellas removed the execute permission from /usr/bin/chmod itself. How do you recover chmod in this case and make it executable again? Let's say getting it from an external source or recompiling it is not a preferable option, is there some smart hack that can recover this chmod itself?

Note that this happened a long time ago and I'm not looking for a solution for some current problem, just curious about what ways Unix provides us around such an issue.

share|improve this question
4  
Since all the answers provided are equally "right answers" here, I'm not marking any one of them in particular. Thanks to everyone who answered, every answer was educative in some way. –  sundar Jul 22 '13 at 17:36
    
Note that the "how do I do this without rebooting?" is as important an exercise as "How do I boot a rescue/installation media and fix this?". In my opinion you need to be able to do both - it might be a job saver some day. –  Thorbjørn Ravn Andersen Jul 23 '13 at 8:28
1  
The same question (and similar answers) exists on ServerFault, too. –  SpellingD Jul 23 '13 at 19:30
    
@SpellingD Thanks. It's weird reading that thread, like an alternate universe version of this question with only slightly different answers. And someone there answers they've seen the question previously on slideshare, and someone comments on that one that they've seen it on Reddit too! –  sundar Jul 23 '13 at 19:43

7 Answers 7

Pipe the contents of chmod into an already executable file

cp /usr/bin/executable_file ~/executable_file
cat /usr/bin/chmod > ~/executable_file
~/executable_file +x file_to_be_executed.sh
share|improve this answer

The chmod utility relies on the chmod() system call (see man 2 chmod). So you could do this with a few lines of C, or just about any other language that has a wrapper around it (which would be most of them). Very few *nix systems are going to lack a C compiler and a perl interpreter; most linux distros require the later to work.

perl -e 'chmod 0755, "foobar.file"'
share|improve this answer
3  
Thanks, that's sweet. I just tried it out in Perl and it worked. –  sundar Jul 21 '13 at 19:28
    
@sundar perl is indeed the fastest way to go. –  ott-- Jul 21 '13 at 19:55
2  
@ruakh, on Debian-based systems the perl-base package is marked as essential. Not having perl-base will make the package manager pretty unhappy. There are a large number of other essential/important tools like adduser that require perl, and are installed in an absolute bare-bones setup. –  Zoredache Jul 22 '13 at 5:24
1  
@ruakh The reason it is more true of perl than anything else is that perl 5 was around during linux's infancy, while (eg) python 2 was not. It is kind of the original "dynamically typed, object oriented interpreted" language. So in general the 3 most fundamental languages in the linux world would be 1) C, 2) bash, and 3) perl. Python has probably eclipsed it in popularity in recent years, but it is just not as historically relevant and thus less likely to be essential -- although in reality both of them are usually available anyway. –  goldilocks Jul 22 '13 at 14:44
1  
@goldilocks: Interesting! The Single Unix Specification does mark cc as "LEGACY" (and therefore optional), but I didn't realize that Linux distros were actually taking it up on that. :-P (Of course, it doesn't list perl at all, even as an optional utility.) –  ruakh Jul 22 '13 at 16:38

Use default interpreter languages to do this:

$ perl -e 'chmod 0755, "/bin/chmod"'
share|improve this answer

Easy. What you can do is prepare some other executable file, and then cp chmod over it.

 $ cp /bin/ls chmod
 $ cp /bin/chmod .

The first cp creates a file called chmod with executable permissions, but which is really the ls executable. The second cp populates this file with the binary code of chmod, while preserving the execute permissions of the target file (because we did not specify any options to carry over permissions of the source file).


Another approach is to use the install utility which is a glorified copying program which can set permissions in one step. (See the -m argument.)

$ install -m a+x /bin/chmod .
$ ./chmod # executes

The install program isn't part of the Unix specification, but it is found in BSD, and in GNU Coreutils. Both support the -m option with chmod-like syntax, both symbolic and octal.

share|improve this answer
    
I think this is the simplest and neatest solution here, tested on my Cygwin too, have an upboat. –  sundar Jul 22 '13 at 17:32
7  
Just make sure you're not inside /bin when you do this, or the first step will overwrite the real chmod. –  Matthew Crumley Jul 22 '13 at 17:57
1  
+1 for install. So many solutions. :) –  frostschutz Jul 23 '13 at 9:52

Some systems also have busybox installed in which case you may run:

busybox chmod +x /bin/chmod

Since you were asking for hacks, I just thought of another one:

mv /bin/chmod /bin/chmod.orig
cp -a /bin/chown /bin/chmod

Now you have a /bin/chmod that's executable but it's actually chown (i.e. some other binary). Now all we have to do is overwrite it with the original binary.

dd if=/bin/chmod.orig of=/bin/chmod

It keeps the +x flag so you just stole the +x of another file for this one.

Of course, if all those alternative binaries (including the loader, perl, python, gcc et cetera) were chmod -x, fixing it from a rescue system may be the only option.

share|improve this answer
    
Couldn't you just use cat instead of dd? –  jw013 Jul 22 '13 at 17:18
    
Yes... I ended up using dd because at first I thought it may need conv=notrunc or similar to prevent replacing the file entirely, but it does work with most commands that write files after all (including cat, cp, ...). –  frostschutz Jul 22 '13 at 17:44
    
great hack, really clever –  Kiwy Mar 14 at 8:49

You can run the loader directly, and pass it the command you want to run:

/lib/ld-linux.so /bin/chmod +x /bin/chmod

Your path to the loader might vary, and on a 64-bit system you need to choose the right one based on how chmod was compiled; the 64-bit version is named something like /lib/ld-linux-x86-64.so

share|improve this answer
30  
I love any day where I learn something new. –  EightBitTony Jul 21 '13 at 19:24
3  
Thanks. What permissions does ld-linux.so itself have? (I have only cygwin and it doesn't seem to have this file.) Is this an easy way to override the executable permission bit then? –  sundar Jul 21 '13 at 19:33
2  
minor correction: 64 bit libraries are usually under /lib64 –  Bratchley Jul 21 '13 at 20:43
4  
On x86 (32-bit) Linux, the dynamic linker must be at exactly the path /lib/ld-linux.so.2, on x86-64 (64-bit) Linux, the dynamic linker must be at exactly the path /lib64/ld-linux-x86-64.so.2. Both of these are normally symlinks to the correct file, but that exact path is required to be present. –  Jonathan Callen Jul 22 '13 at 2:43
6  
@gerrit If everything gets the execution bit unset, you reboot the system with a live CD and reset the permissions. However, in that case it's probably easier to just reinstall the whole system since who knows what has been borked in the process. –  Janoszen Jul 22 '13 at 10:00

First things off the top of my head,

  • Boot from any other source (network book, cd, etc.) and use the chmod on that source to set the permissions.
  • Write a tiny C program to change the permissions.
  • Write a perl script (ruby, php, python, etc.) to change the permissions

/usr/bin/chmod is just making a system call to change the permissions, you can make that system call yourself in any number of ways.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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