The kernel is no longer readable by non-root users

Bug #759725 reported by Richard W.M. Jones
328
This bug affects 69 people
Affects Status Importance Assigned to Milestone
linux (Ubuntu)
Won't Fix
Medium
Unassigned

Bug Description

The mode of the latest kernel has changed so it is no longer readable
by non-root users:

-rw-r--r-- 1 root root 4336016 2010-10-17 01:37 /boot/vmlinuz-2.6.35-22-generic
-rw-r--r-- 1 root root 4336912 2010-11-24 12:46 /boot/vmlinuz-2.6.35-23-generic
-rw-r--r-- 1 root root 4523072 2011-03-08 18:47 /boot/vmlinuz-2.6.38-6-generic
-rw------- 1 root root 4523936 2011-04-11 05:24 /boot/vmlinuz-2.6.38-8-generic

This prevents people from using this kernel to boot qemu
virtual machines as non-root.

Please change the mode back to make the kernel readable.

ProblemType: Bug
DistroRelease: Ubuntu 11.04
Package: linux-image-2.6.38-8-generic 2.6.38-8.42
Regression: Yes
Reproducible: Yes
ProcVersionSignature: Ubuntu 2.6.35-22.35-generic 2.6.35.4
Uname: Linux 2.6.35-22-generic x86_64
AlsaDevices: Error: command ['ls', '-l', '/dev/snd/'] failed with exit code 2: ls: cannot access /dev/snd/: No such file or directory
AplayDevices: aplay: device_list:240: no soundcards found...
Architecture: amd64
ArecordDevices: arecord: device_list:240: no soundcards found...
CRDA: Error: [Errno 2] No such file or directory
Date: Wed Apr 13 13:05:01 2011
HibernationDevice: RESUME=UUID=112bf9c4-620e-441f-abb3-aeac6aa15294
InstallationMedia: Ubuntu 10.10 "Maverick Meerkat" - Release amd64 (20101007)
IwConfig:
 lo no wireless extensions.

 eth0 no wireless extensions.
Lsusb: Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
MachineType: Red Hat KVM
PciMultimedia:

ProcEnviron:
 LANG=en_GB.UTF-8
 SHELL=/bin/bash
ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-2.6.35-22-generic root=UUID=1efa0b67-17df-484e-980c-8544fa2149fe ro quiet splash
RelatedPackageVersions:
 linux-restricted-modules-2.6.35-22-generic N/A
 linux-backports-modules-2.6.35-22-generic N/A
 linux-firmware 1.50
RfKill:

SourcePackage: linux
UpgradeStatus: No upgrade log present (probably fresh install)
dmi.bios.date: 01/01/2007
dmi.bios.vendor: Seabios
dmi.bios.version: 0.5.1
dmi.chassis.type: 1
dmi.chassis.vendor: Red Hat
dmi.modalias: dmi:bvnSeabios:bvr0.5.1:bd01/01/2007:svnRedHat:pnKVM:pvrRHEL6.0.0PC:cvnRedHat:ct1:cvr:
dmi.product.name: KVM
dmi.product.version: RHEL 6.0.0 PC
dmi.sys.vendor: Red Hat

Revision history for this message
Richard W.M. Jones (rich-annexia) wrote :
Revision history for this message
Scott Moser (smoser) wrote :

I'm confirming this, and marking marking it as medium.

It is fairly common practice to boot kvm or qemu with something like:
 kvm -kernel /boot/vmlinuz-$(uname -r)

There are easy workarounds (downloading the kernel and extracting and using it), but they're less than idea.

Changed in linux (Ubuntu):
importance: Undecided → Medium
status: New → Confirmed
Revision history for this message
Kees Cook (kees) wrote :

This mode change is "by design". For local admins that what to relax this restriction, you can use dpkg-statoverride:

  sudo dpkg-statoverride --add root root 0644 /boot/vmlinux-$(uname -r) --update

To have this automatically happen with each new kernel, create /etc/kernel/postinst.d/statoverride:

  #!/bin/sh
  version="$1"
  # passing the kernel version is required
  [ -z "${version}" ] && exit 0
  dpkg-statoverride --add root root 0644 /boot/vmlinux-${version} --update

Changed in linux (Ubuntu):
status: Confirmed → Won't Fix
Revision history for this message
Kees Cook (kees) wrote :

Sorry, that should be "vmlinuz" not "vmlinux" in the above examples. :)

Revision history for this message
Richard W.M. Jones (rich-annexia) wrote :

What is being protected by this mode change? This kernel is distributed
on hundreds of mirrors -- there is no secret in here.

When we install libguestfs, we need to boot using this kernel. What change
do I need to make to libguestfs so that when a sysadmin installs it, it will
change the permissions back to 0644 automatically?

Revision history for this message
Kees Cook (kees) wrote : Re: [Bug 759725] Re: The kernel is no longer readable by non-root users

On Tue, Apr 26, 2011 at 11:21:38AM -0000, Richard W.M. Jones wrote:
> What is being protected by this mode change? This kernel is distributed
> on hundreds of mirrors -- there is no secret in here.

The mode changes do not protect a system from any dedicated attacker (for
the reason you state), but it does have real-world benefits against
simplistic kernel exploitation (keeping kernel symbols away from non-root
users). It is absolutely a trade-off.

> When we install libguestfs, we need to boot using this kernel. What change
> do I need to make to libguestfs so that when a sysadmin installs it, it will
> change the permissions back to 0644 automatically?

Shipping a pair of files in /etc/kernel/postinst.d/ and
/etc/kernel/postrm.d/ to call dpkg-statoverride --add and --remove
respectively is likely the cleanest approach to handling this.

--
Kees Cook
Ubuntu Security Team

Revision history for this message
Richard W.M. Jones (rich-annexia) wrote : Re: [Bug 759725] Re: The kernel is no longer readable by non-root users

On Tue, Apr 26, 2011 at 05:25:33PM -0000, Kees Cook wrote:
> On Tue, Apr 26, 2011 at 11:21:38AM -0000, Richard W.M. Jones wrote:
> > What is being protected by this mode change? This kernel is distributed
> > on hundreds of mirrors -- there is no secret in here.
>
> The mode changes do not protect a system from any dedicated attacker (for
> the reason you state), but it does have real-world benefits against
> simplistic kernel exploitation (keeping kernel symbols away from non-root
> users). It is absolutely a trade-off.

This non-root user that we imagine has no access to the world
wide web? This is absolutely nuts, sorry.

Rich.

--
Richard Jones
Red Hat

Revision history for this message
Richard W.M. Jones (rich-annexia) wrote :

By the way, I myself actually wrote code that walks through the kernel memory
finding the location of the symbols. You're not gaining any extra security by
making this change, but you are making Ubuntu less useful.

http://git.annexia.org/?p=virt-mem.git;a=blob;f=lib/virt_mem_kallsyms.ml;h=9e6eccb6629a2ea067ee46a7c690aea17e44c0d2;hb=HEAD#l39
http://git.annexia.org/?p=virt-mem.git;a=blob;f=lib/virt_mem_ksyms.ml;h=8a38caec5b9fa05904c3b9e8b5fcdb76871f27ae;hb=HEAD#l29

Revision history for this message
Kees Cook (kees) wrote :

I recognize this can get in some people's way, which is why I've tried to demonstrate how to adjust the local system to retain the more open permissions.

I am not saying they're hidden from being looked up externally (just fetching the kernel package's System.map file is easiest). But because the symbols can be extracted in the way you point out is why the kernel image itself needs to be unreadable. This change is to block the class of attacks carried out by script kiddies and automated systems that expect to be able to look up symbols locally and make exploits totally portable to all kernel versions. It changes the nature of future attacks, at least forcing attackers to take additional steps.

The postinst.d and prerm.d solution should provide a reasonable work-around for the small number of systems that need it.

Revision history for this message
Richard W.M. Jones (rich-annexia) wrote :

On Tue, Apr 26, 2011 at 09:49:25PM -0000, Kees Cook wrote:
> But because the symbols can be extracted in the way you point out is
> why the kernel image itself needs to be unreadable. This change is
> to block the class of attacks carried out by script kiddies and
> automated systems that expect to be able to look up symbols locally
> and make exploits totally portable to all kernel versions.

You didn't appear to understand the code that I wrote: it gets out the
symbols from any version of the kernel by simply reading the kernel
*runtime memory*.

So the attacker now has two alternative methods: (a) fire up a web
browser or (b) inject shell code into the kernel which greps through
physical memory to find the symbol tables, and note method (b) works
with any kernel version without reference to the original vmlinuz
file.

> It changes the nature of future attacks, at least forcing attackers
> to take additional steps.

Yes, firing up a web browser or injecting an extra small piece of
shell code into the kernel.

Revision history for this message
Joel Whitehouse (me-t) wrote :

I need to mount a binary file that contains a filesystem so I can copy files onto it.

I could already do this using /dev/loop but I need to automate this without requiring root privileges for a build system.

To solve this problem, the guestmount folks pulled together TONS of code. They are creating a custom minimized kernel, emulating it with QEMU, booting it with the binary file attached, attaching FUSE to the mount point and connecting to it at the application layer. All to avoid needing /dev/loop and root access.

Guestmount used to work out of the box. And you just broke it "by-design" with a change that provides zero security or protection from anyone with a brain or an internet connection. I agree with Rich W. M. Jones. You are making ubuntu less useful.

Revision history for this message
Thiago Martins (martinx) wrote :

Since the vmlinuz-X.WY.Z-X-generic can be easily downloaded from the Internet, this "by design" change makes Ubuntu less useful.

Ubuntu needs to make "IT things" (Linux) better for humans, not worse... :-/

This is also afecting OpenStack... Reference: http://docs.openstack.org/icehouse/install-guide/install/apt/content/nova-compute.html

Revision history for this message
Axel Beckert (xtaran) wrote :

This also affects monitoring tools like e.g. the libs test in hobbit-plugins which compare the running kernel version to the one on disk. These tests don't run as root as they don't need to. Now they need elevated privileges just do this check... :-/

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in hobbit-plugins (Ubuntu):
status: New → Confirmed
Axel Beckert (xtaran)
Changed in hobbit-plugins (Ubuntu):
status: Confirmed → In Progress
assignee: nobody → Axel Beckert (xtaran)
Revision history for this message
god (humper) wrote :

Is it possible to change vmlinuz permissions so it's readable by members of special group (libguestfs)?.
This way admins could locally fix this "by design" stupidity easily for affected users instead of forcing maintainers for all the affected packages to supply statoverride scripts.

Revision history for this message
Chris Jeker (chjeker) wrote :

I changed the following under Ubuntu 14.10:
File /usr/lib/xymon/client/ext/libs
69c69
< my $kernel_image_read_command = "strings '$newest_kernel_image'";
---
> my $kernel_image_read_command = "$SUDO strings '$newest_kernel_image'";

ext$ ./libs
strings: /boot/vmlinuz-3.16.0-23-generic: Permission denied
status unknown.libs yellow Tue Oct 28 09:30:03 2014 - libs NOT ok
&yellow Kernel image /boot/vmlinuz-3.16.0-23-generic unreadable. Can't check kernel version!

ext$ ./libs_patched
BFD: /boot/vmlinuz-3.16.0-23-generic: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section .bss
status unknown.libs yellow Tue Oct 28 09:30:09 2014 - libs NOT ok
&green Newest kernel is running: 3.16.0-23-generic, version #31-Ubuntu SMP Tue Oct 21 17:56:17 UTC 2014

Revision history for this message
Chris Jeker (chjeker) wrote :

This works only if started the ./libs localy, but not via xymonclient. There I got the error "sudo: no tty present and no askpass program specified", but I don't know how to adapt it, that it works also with the xymonclient.

Revision history for this message
Thiago Martins (martinx) wrote :

Any news on this?

Revision history for this message
god (humper) wrote :

As of 15.04 this embarrassing security theatre is still in place.

Mathew Hodson (mhodson)
no longer affects: hobbit-plugins (Ubuntu)
Revision history for this message
Andrea Frittoli (andrea-frittoli) wrote :

The correct override command is:

sudo dpkg-statoverride --add --update root root 0644 /boot/vmlinuz-$(uname -r)

Revision history for this message
Velkan (velkan-s) wrote :

Why guestmount can't work out of box? That was a perfect userspace option to get a loop device to test out-of-space errors.

Revision history for this message
Jason Heeris (detly) wrote :

Does this mean there is now no non-root way to extract files from filesystem images?

Revision history for this message
Ciro Santilli 六四事件 法轮功 (cirosantilli) wrote :

$ sudo dpkg-statoverride --add root root 0644 /boot/vmlinux-$(uname -r)
dpkg-statoverride: error: --add needs four arguments

only updated for a single kernel, and apparently not the one virt-make-fs is using.

I then did:

sudo chmod +r /boot/vmlinuz-*

and virt-make-fs was happy.

Revision history for this message
Jarl (jarl-dk) wrote :

A consequence of the design decision to prevent read-access for users is that a bug has emerged in libguestfs: https://bugs.launchpad.net/ubuntu/+source/libguestfs/+bug/1813662

Revision history for this message
Stefan Heinzmann (stefan-heinzmann) wrote :

Would it be possible to make the kernel readable by a special group (i.e. "kernel-readers"), which Ubuntu-distros could have installed by default?

In this case it would suffice to make users member of this group, if they want to use tools that need kernel read access.

Or would that somehow violate the Ubuntu maintainers sense of safety, too?

Revision history for this message
Alkis Georgopoulos (alkisg) wrote :

This forces us to run tftpd as root, to serve $CHROOT/boot to netboot clients,
so it's actually LESS secure than it was before the change.

Applying the stat workaround isn't always easy; sometimes $CHROOT/boot comes from a read-only loopback image.

Also note that initrd.img, which may actually contain private information, is world-readable.

Revision history for this message
Andrew Goodbody (cbrx-ajg) wrote :

Very disappointed to see this is marked as 'Wont fix'. It is pointless security theatre and is breaking useful things. In my case it is libguestfs. Please reconsider

Revision history for this message
Thiago Martins (martinx) wrote :

ROLL BACK THIS DAMN CHANGE!!!

Revision history for this message
iczero (iczero) wrote :

Fortunately, you can still get the current kernel quite easily:

curl $(python3 -c "import apt, os; print(apt.cache.Cache()['linux-image-' + os.uname().release].versions[0].uri)") | dpkg-deb -x - .

Revision history for this message
Hontvári József Levente (hontvari) wrote :

On Focal the correct command to (temporarily) fix the permission problem:

  sudo dpkg-statoverride --update --add root root 0644 /boot/vmlinux-$(uname -r)

However, I also feel that that making non secret information world readable would have been the Unix way. This change made the life of a few script kiddies a very bit harder, but also made the life of many legal users significantly harder (in contrast with a script kiddy they have to maintain the fix in a more formalized way).

Revision history for this message
LittleBigBrain (braingateway) wrote :

this actually make ubuntu much insecure because you have to run most tools with sudo and normally those tools recommend user NOT to run it with root. Other distros are still readable by normal user and they harden it via selinux.

Revision history for this message
remram44 (remirampin) wrote :

Trying to understand the process here. This change affects multiple people and projects, has no real rationale, worsens security, and is trivial to fix. Why is it still there? How do we escalate this past this Kees Cook's misplaced stubbornness?

Revision history for this message
Michael Meffie (mije) wrote :

I'm still trying to reliably workaround this pointless bug. It seems one needs to create a script in /etc/kernel/postinst.d to run dpkg-stateoveride --update, but that command is not idempotent, so kernel updates fail if you update existing versions.

Revision history for this message
Michael Meffie (mije) wrote :

Looks like this workaround is working for me as new kernel versions are released:

    $ cat /etc/kernel/postinst.d/statoverride
    #!/bin/sh
    version="$1"
    [ -z "${version}" ] && exit 0
    dpkg-statoverride --update --add root root 0644 /boot/vmlinuz-${version}

That file must be executable.

Revision history for this message
James Cuzella (trinitronx) wrote :

The "statoverride" script appears to work on the first run for each kernel. However, any subsequent times the `dpkg-statoverride` command exits with errorcode 2:

    $ apt-get install something-triggering-dkms

    Processing triggers for linux-image-5.4.0-96-generic (5.4.0-96.109) ...
    /etc/kernel/postinst.d/dkms:
     * dkms: running auto installation service for kernel 5.4.0-96-generic
       ...done.
    /etc/kernel/postinst.d/initramfs-tools:
    update-initramfs: Generating /boot/initrd.img-5.4.0-96-generic
    /etc/kernel/postinst.d/statoverride:
    dpkg-statoverride: error: an override for '/boot/vmlinuz-5.4.0-96-generic' already exists; aborting
    run-parts: /etc/kernel/postinst.d/statoverride exited with return code 2
    dpkg: error processing package linux-image-5.4.0-96-generic (--configure):
     installed linux-image-5.4.0-96-generic package post-installation script subprocess returned error exit status 1
    Errors were encountered while processing:
     linux-image-5.4.0-96-generic

    E: Sub-process /usr/bin/dpkg returned an error code (1)

Adding the `--force-statoverride-add` flag fixed the issue:

    #!/bin/sh

    # https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725

    set -e
    version="$1"
    if [ -z "$version" ]; then
        exit 0
    fi
    exec dpkg-statoverride --force-statoverride-add --update --add root root 0644 "/boot/vmlinuz-${version}"

After that change, now the kernel dkms trigger succeeds:

    Setting up linux-image-5.4.0-96-generic (5.4.0-96.109) ...
    Processing triggers for linux-image-5.4.0-96-generic (5.4.0-96.109) ...
    /etc/kernel/postinst.d/dkms:
     * dkms: running auto installation service for kernel 5.4.0-96-generic
       ...done.
    /etc/kernel/postinst.d/initramfs-tools:
    update-initramfs: Generating /boot/initrd.img-5.4.0-96-generic
    /etc/kernel/postinst.d/statoverride:
    dpkg-statoverride: warning: an override for '/boot/vmlinuz-5.4.0-96-generic' already exists, but --force specified so will be ignored
    /etc/kernel/postinst.d/zz-update-grub:
    Sourcing file `/etc/default/grub'
    Sourcing file `/etc/default/grub.d/init-select.cfg'
    Generating grub configuration file ...
    Found linux image: /boot/vmlinuz-5.4.0-96-generic
    Found initrd image: /boot/initrd.img-5.4.0-96-generic
    Found linux image: /boot/vmlinuz-5.4.0-94-generic
    Found initrd image: /boot/initrd.img-5.4.0-94-generic
    Found linux image: /boot/vmlinuz-5.4.0-91-generic
    Found initrd image: /boot/initrd.img-5.4.0-91-generic
    Found memtest86+ image: /boot/memtest86+.elf
    Found memtest86+ image: /boot/memtest86+.bin
    Found Ubuntu 20.04.3 LTS (20.04) on /dev/md126p1
    done

If this is to be added as a postinst.d to the libguestfs-tools package, please don't forget the `--force-statoverride-add` flag... or else we introduce a new dkms / kernel postinst.d trigger idempotency bug.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.