Build snaps with hardened toolchain by default

Major distros compile all packages with hardened toolchain by default: Fedora, Debian, Ubuntu, Archlinux.

I think snaps shouldn’t be inferior to distro-compiled packages in this aspect.

Specifically all snaps should be build at least with:
Stack protector: C/XXFLAGS: -fstack-protector-strong or use gcc compiled with with --enable-default-ssp option.
PIE: C/XXFLAGS: -fPIE, LDFLAGS: -pie or use gcc compiled with with --enable-default-pie option.
Fortify source: CPPFLAGS or C/XXFLAGS: -D_FORTIFY_SOURCE=2.
RELRO: LDFLAGS: -Wl,-z,relro.
BIND_NOW: LDFLAGS: -Wl,-z,now.

Compile-time security features can be checked with checksec tool.

1 Like

I agree.

That said, if the application is being built with the Ubuntu toolchain (ie, gcc/etc coming from the Ubuntu archive), this should already be happening by default, unless snapcraft is disabling it. When are you seeing that hardening options are not on by default?

Here are my test results with snap on Archlinux (the /usr/bin/* results are from Archlinux packages):

checksec -f /var/lib/snapd/snap/core/current/bin/bash
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
Partial RELRO   Canary found      NX enabled    No PIE          No RPATH   No RUNPATH   Yes     13              33      /var/lib/snapd/snap/core/current/bin/bash

checksec -f /usr/bin/bash
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   Yes     13              33      /usr/bin/bash

checksec -f /var/lib/snapd/snap/core/current/bin/mount
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
Partial RELRO   Canary found      NX enabled    No PIE          No RPATH   No RUNPATH   Yes     4               6       /var/lib/snapd/snap/core/current/bin/mount

checksec -f /usr/bin/mount
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   Yes     4               8       /usr/bin/mount

checksec -f /var/lib/snapd/snap/core/current/bin/umount
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
Partial RELRO   Canary found      NX enabled    No PIE          No RPATH   No RUNPATH   Yes     3               5       /var/lib/snapd/snap/core/current/bin/umount

checksec -f /usr/bin/umount
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   Yes     3               7       /usr/bin/umount

checksec -f /var/lib/snapd/snap/vlc/current/usr/bin/vlc
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
Partial RELRO   Canary found      NX enabled    No PIE          RPATH      No RUNPATH   Yes     4               6       /var/lib/snapd/snap/vlc/current/usr/bin/vlc

checksec -f /usr/bin/vlc
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   Yes     2               3       /usr/bin/vlc

The conclusion is BIND_NOW and PIE are missing from snap binaries. Keep in mind that mount/umount (also ping) are setuid so hardening them has additional importance.

Looking at the table in https://wiki.ubuntu.com/Security/Features I guess this is because PIE and BIND_NOW are mandatory only since Ubuntu 17.10 (Artful Aardvark) so perhaps moving snap base to 18.04 will fix this (assuming snaps are being build with ubuntu toolchain).