66

I recently found out that if I edit GRUB before booting and I add rw init=/bin/bash I end up with a root shell.

Being in a condition that I want to understand everything I would like to know why this happens. I mean is it a bug? is it a feature? is it there to help admins to fix things as it only works if you have physical access to a computer?

Is it provided by GRUB or the actual kernel?

2
  • 14
    If you want to "fix" this, lock GRUB and your BIOS with a password and put your hard disk first in boot order. If someone else has physical access and can put the (non-encrypted) hard disk into another computer, you have lost anyway
    – jofel
    Commented Mar 18, 2012 at 20:21
  • Generally speaking, common wisdom is that if someone has hardware level access to the point where they can modify the grub boot line, it's too late to worry about security restrictions anyway. Commented Feb 10 at 9:03

6 Answers 6

60

This is a feature, and is used for system maintainance: it allows a sysadmin to recover a system from messed-up initialization files or change a forgotten password.

This post in the Red Hat mailing list explains some things:

In Unix-like systems, init is the first process to be run, and the ultimate ancestor of all processes ever run. It's responsible for running all the init scripts.

You're telling the Linux kernel to run /bin/bash as init, rather than the system init. [...]

Thus, you are not exploiting anything, you are just using a standard kernel feature.

Besides, as noted in a comment, the rw flag is separate from init=, it just tells the system to mount the root file system as read-write (so you can e.g. edit the misconfigured file or change a password).

0
27

Your system has mechanisms for running and debugging (like the init parameter) and it probably has security mechanisms to stop unwanted users from taking advantage of them. These are features, not bugs.

The bootloader is responsible for starting the OS. OS security obviously doesn't apply at that point. You could just load a different kernel, initrd, root fs or set different options (like init path). If you want to stop users from doing that, it must be done at the bootloader.

Your system (probably a PC, so BIOS) loads the bootloader and so, obviously, bootloader security doesn't apply to it. If you want to stop users from making the bios boot from USB or such, you need to do that on that level.

Your system may be on a desk somewhere. If you want to stop users from opening the coputer and switching the hdd for one of their own or removing the drive to mount it in their machines, you need to do it on a physical level. And it won't stop them from picking up the whole desk and driving away in their getaway van...

That's the way security is. Elephants all the way down.

1
  • 3
    Nice summary. Might want to add hdd encryption to that, as a possible answer against the van.
    – MvG
    Commented Aug 2, 2013 at 20:56
17

This is simply how the kernel was designed. There has to be something to run when the computer starts, and while there is a default, the kernel command line allows you to change that default.

Normally it runs a program called "init", usually found at /bin/init or /sbin/init. This program is responsible for all the system startup and creating a usable environment.

Specifying init=/bin/bash tells the kernel to run /bin/bash instead (which is a shell). Specifying rw tells the kernel to boot with the hard disk in read-write mode instead of read-only mode. Traditionally the kernel starts with the disk in read-only mode and a process later on checks the integrity of the disk before switching to read-write.

2
  • This doesn't answer the question, which asks: why does Linux allow this? Commented Feb 8 at 13:49
  • 3
    @reinierpost -- It did answer the question at the time. When the question was originally written it was simply "what happens". The "why does it happen" was a later edit and I didn't go back to edit the answer. I've rephrased the answer so that it matches.
    – tylerl
    Commented Feb 9 at 18:25
8

Pieced together from kernel.org:

KNL     Is a kernel start-up parameter.

init=   [KNL]
        Format: <full_path>
        Run specified binary instead of /sbin/init as init
        process.

rw      [KNL] Mount root device read-write on boot
7

init= can take any executable

init= can take any executable, including shell scripts. The underlying reason is likely that the exec syscall can directly handle both ELF executables and shebangs.

Here for example I demonstrate how to create an arbitrary minimal C compiled init: How to create a custom Linux distro that runs just one program and nothing else?

So why would it not accept /bin/bash, of all things, which is just a regular executable, and can actually be useful? :-)

Next, you should also to try to understand what the trade-offs will be with your regular init such as systemd or Busybox'

Basically, with a raw /bin/bash, you:

Job control can be restored on Busybox' init and other similar inits with a leading - in the inittab:

tty3::respawn:-/bin/sh

The more normal inittab entries, which use login and keep spawning shells if you do Ctrl+D are:

::respawn:/sbin/getty -L ttyS0 0 vt100

which use the getty executable, but TODO: I haven't been able to spawn those myself without the Busybox init: getty start from command line?

You can use this setup to play around with it and reach the above conclusions.

3

This is a feature from the kernel: it allows its “caller”, i.e. the boot loader, great flexibility. Grub provides you with the means to make use of this flexibility while booting, but it also provides you with the means to restrict this kind of tampering. This makes particular sense in those cases where unauthorized users may get hold of the boot process, but are otherwise denied access to the hard drive itself.

You must log in to answer this question.