# [Raspberrypi 3 && Grsecurity] Patcher kernel avec Grsec ?

## jaypeche

Bonsoir à tous,

J'ai dernièrement fait l'acquisition du RPI3 et je souhaite l'utiliser comme serveur de remplacement pour Apache.

J'ai suivi à la lettre le wiki gentoo https://wiki.gentoo.org/wiki/Raspberry_Pi, et l'installation s'est déroulée sans problème.

J'ai installé un stage3 avec un profil hardened et je souhaiterais dans l'idéal disposer d'un kernel patché grsec voire hardened.

De ce que j'ai pu lire sur la toile, les sources officielles rpi, sont modifiées à partir des vanilla-sources afin d'apporter le support des technologies arm et rpi. 

Après quelques tests... Il n'est pas aisé de patcher celui-çi car il a été grandement modifié pour prendre en charge lle matériel. (Processeur armV8, wifi, bluetooth, boot, firmware, etc...)

Je souhaiterais pour que mon système hardened soit cohérent, compiler un kernel disposant des options grsecurity. https://grsecurity.net/download.php#test

 :Idea:  Pensez-vous qu'il soit possible d'y inclure ces patchs de sécurité ? et si oui quelles options me recommanderiez-vous ?

Merçi.

```
localhost ~ # uname -a 

Linux localhost 4.4.42-raspberrypi-v7+ #1 SMP Sun Jan 15 02:05:22 CET 2017 armv7l ARMv7 Processor rev 4 (v7l) BCM2709 GNU/Linux

```

```
localhost ~ # emerge --info

Portage 2.3.0 (python 3.4.5-final-0, hardened/linux/arm/armv7a, gcc-4.9.4-hardenednopiessp, glibc-2.23-r3, 4.4.42-raspberrypi-v7+ armv7l)

=================================================================

System uname: Linux-4.4.42-raspberrypi-v7+-armv7l-ARMv7_Processor_rev_4_-v7l-with-gentoo-2.3

KiB Mem:      975608 total,    113936 free

KiB Swap:          0 total,         0 free

Timestamp of repository gentoo: Wed, 18 Jan 2017 18:00:01 +0000

sh bash 4.3_p48-r1

ld GNU ld (Gentoo 2.25.1 p1.1) 2.25.1

app-shells/bash:          4.3_p48-r1::gentoo

dev-lang/perl:            5.22.3_rc4::gentoo

dev-lang/python:          2.7.12::gentoo, 3.4.5::gentoo

dev-util/cmake:           3.5.2-r1::gentoo

dev-util/pkgconfig:       0.28-r2::gentoo

sys-apps/baselayout:      2.3::gentoo

sys-apps/openrc:          0.22.4::gentoo

sys-apps/sandbox:         2.10-r1::gentoo

sys-devel/autoconf:       2.69::gentoo

sys-devel/automake:       1.14.1::gentoo, 1.15::gentoo

sys-devel/binutils:       2.25.1-r1::gentoo

sys-devel/gcc:            4.9.4::gentoo

sys-devel/gcc-config:     1.7.3::gentoo

sys-devel/libtool:        2.4.6-r2::gentoo

sys-devel/make:           4.1-r1::gentoo

sys-kernel/linux-headers: 4.4::gentoo (virtual/os-headers)

sys-libs/glibc:           2.23-r3::gentoo

Repositories:

gentoo

    location: /usr/portage

    sync-type: rsync

    sync-uri: rsync://rsync.gentoo.org/gentoo-portage

    priority: -1000

x-portage

    location: /usr/local/portage

    masters: gentoo

    priority: 0

ACCEPT_KEYWORDS="arm"

ACCEPT_LICENSE="* -@EULA"

CBUILD="armv7a-hardfloat-linux-gnueabi"

CFLAGS="-O2 -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard"

CHOST="armv7a-hardfloat-linux-gnueabi"

CONFIG_PROTECT="/etc /usr/share/gnupg/qualified.txt"

CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/fonts/fonts.conf /etc/gconf /etc/gentoo-release /etc/php/apache2-php5.6/ext-active/ /etc/php/cgi-php5.6/ext-active/ /etc/php/cli-php5.6/ext-active/ /etc/revdep-rebuild /etc/sandbox.d /etc/terminfo"

CXXFLAGS="-O2 -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard"

DISTDIR="/usr/portage/distfiles"

FCFLAGS="-O2 -pipe -march=armv7-a"

FEATURES="assume-digests binpkg-logs config-protect-if-modified distlocks ebuild-locks fixlafiles merge-sync news parallel-fetch preserve-libs protect-owned sandbox sfperms strict unknown-features-warn unmerge-logs unmerge-orphans userfetch userpriv usersandbox usersync xattr"

FFLAGS="-O2 -pipe -march=armv7-a"

GENTOO_MIRRORS="http://distfiles.gentoo.org"

LANG="fr_FR.utf8"

LDFLAGS="-Wl,-O1 -Wl,--as-needed"

MAKEOPTS="-j4"

PKGDIR="/usr/portage/packages"

PORTAGE_CONFIGROOT="/"

PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages --exclude=/.git"

PORTAGE_TMPDIR="/var/tmp"

USE="acl apache2 arm armv5te armv6 armv6t2 berkdb bzip2 cli cracklib crypt cxx dri gd gdbm hardened iconv ipv6 modules ncurses nls nptl openmp pam pax_kernel pcre pic pie readline seccomp session ssl ssp tcpd unicode urandom xattr xtpax zlib" APACHE2_MODULES="actions alias auth_basic authn_alias authn_anon authn_core authn_dbm authn_file authz_core authz_dbm authz_groupfile authz_host authz_owner authz_user autoindex cache cgi cgid dav dav_fs dav_lock deflate dir env expires ext_filter file_cache filter headers include info log_config logio mime mime_magic negotiation rewrite setenvif socache_shmcb speling status unique_id unixd userdir usertrack vhost_alias ratelimit version" CALLIGRA_FEATURES="kexi words flow plan sheets stage tables krita karbon braindump author" CAMERAS="ptp2" COLLECTD_PLUGINS="df interface irq load memory rrdtool swap syslog" ELIBC="glibc" GPSD_PROTOCOLS="ashtech aivdm earthmate evermore fv18 garmin garmintxt gpsclock itrax mtk3301 nmea ntrip navcom oceanserver oldstyle oncore rtcm104v2 rtcm104v3 sirf superstar2 timing tsip tripmate tnt ublox ubx" INPUT_DEVICES="keyboard mouse evdev" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LIBREOFFICE_EXTENSIONS="presenter-console presenter-minimizer" LINGUAS="fr" OFFICE_IMPLEMENTATION="libreoffice" PHP_TARGETS="php5-6" PYTHON_SINGLE_TARGET="python2_7" PYTHON_TARGETS="python2_7 python3_4" RUBY_TARGETS="ruby21" USERLAND="GNU" VIDEO_CARDS="exynos fbdev omap omapfb dummy v4l" XTABLES_ADDONS="quota2 psd pknock lscan length2 ipv4options ipset ipp2p iface geoip fuzzy condition tee tarpit sysrq steal rawnat logmark ipmark dhcpmac delude chaos account"

Unset:  CC, CPPFLAGS, CTARGET, CXX, EMERGE_DEFAULT_OPTS, INSTALL_MASK, LC_ALL, PORTAGE_BUNZIP2_COMMAND, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS, USE_PYTHON

```

----------

## El_Goretto

Regarde un peu ce qui se dit sur le net, en particuliers côté copperheadOS (l'android qui se veut "hardened"), car il me semble avoir lu sur un billet de chez eux qu'il n'y a pas de version grsec ARM (et il n'y en aura jamais) et que ARM64 est très partiellement implémenté (et ils expliquent un peu le point de vue du projet upstream).

Pour le moment, du véritable hardened/grsec, c'est sur x86_64. "Et pis c'est tout." (enfin bon, de mémoire, hein, tant mieux si je me plante  :Wink: )

----------

## jaypeche

Bonjour El'go,

Toujours fidèle au poste   :Wink:  !

Je vais regarder du côté de copperheadOS pour en savoir un peu plus...

 *Quote:*   

> 
> 
> Important Notice Regarding Public Availability of Stable Patches
> 
> Due to continued violations by several companies in the embedded industry of grsecurity®'s trademark and registered copyrights, effective September 9th 2015 stable patches of grsecurity are being made available to commercial customers only. For more information, read the full announcement.
> ...

 

Il me semble effectivement qu'il n'y ai pas de prise en charge pour les systèmes embarqués avec la version de test de grsecurity. Peut être que la version commerciale, oui !

De ce que je vois il y'a bien un profile hardened/arm (celui que j'utilise) donc ça doit être réalisable sur certaines plateformes, le kernel hardened est lui marqué ~arm.

La particularité de raspberrypi c'est qu'il y a des adaptations pour la prise en charge matérielle de l'architecture. Il y a aussi quelques "blob" ou firmware qui eux sont créer par la raspberrypi foundation.

N'importe comment je ne peux pas appliquer de patch grsec sans qu'il n'y ai erreurs, patch ne retrouve pas ses petits !

Et à la compilation du kernel après avoir forcer le patch, j'obtiens ces erreurs :

```
pingwho linux # make

  CHK     include/config/kernel.release

  CHK     include/generated/uapi/linux/version.h

  CHK     include/generated/utsrelease.h

make[1]: « include/generated/mach-types.h » est à jour.

  CHK     include/generated/bounds.h

  CHK     include/generated/timeconst.h

  CC      arch/arm/kernel/asm-offsets.s

In file included from include/linux/atomic.h:4:0,

                 from include/linux/spinlock.h:417,

                 from include/linux/seqlock.h:35,

                 from include/linux/time.h:5,

                 from include/uapi/linux/timex.h:56,

                 from include/linux/timex.h:56,

                 from include/linux/sched.h:19,

                 from arch/arm/kernel/asm-offsets.c:14:

./arch/arm/include/asm/atomic.h: In function ‘__atomic_add_unless’:

./arch/arm/include/asm/atomic.h:144:2: erreur: expected ‘:’ or ‘)’ before ‘__OVERFLOW_POST’

  __OVERFLOW_POST

  ^

./arch/arm/include/asm/atomic.h:133:16: attention : unused variable ‘tmp’ [-Wunused-variable]

  unsigned long tmp;

                ^

./arch/arm/include/asm/atomic.h:132:14: attention : unused variable ‘newval’ [-Wunused-variable]

  int oldval, newval;

              ^

./arch/arm/include/asm/atomic.h: In function ‘atomic_inc_unchecked’:

./arch/arm/include/asm/atomic.h:277:2: erreur: implicit declaration of function ‘atomic_add_unchecked’ [-Werror=implicit-function-declaration]

  atomic_add_unchecked(1, v);

  ^

./arch/arm/include/asm/atomic.h: In function ‘atomic_dec_unchecked’:

./arch/arm/include/asm/atomic.h:282:2: erreur: implicit declaration of function ‘atomic_sub_unchecked’ [-Werror=implicit-function-declaration]

  atomic_sub_unchecked(1, v);

  ^

./arch/arm/include/asm/atomic.h: In function ‘atomic64_dec_if_positive’:

./arch/arm/include/asm/atomic.h:534:2: erreur: expected ‘:’ or ‘)’ before ‘__OVERFLOW_POST_RETURN64’

  __OVERFLOW_POST_RETURN64

  ^

./arch/arm/include/asm/atomic.h:524:6: attention : unused variable ‘tmp’ [-Wunused-variable]

  u64 tmp;

      ^

./arch/arm/include/asm/atomic.h: In function ‘atomic64_add_unless’:

./arch/arm/include/asm/atomic.h:571:2: erreur: expected ‘:’ or ‘)’ before ‘__OVERFLOW_POST’

  __OVERFLOW_POST

  ^

./arch/arm/include/asm/atomic.h:556:16: attention : unused variable ‘tmp’ [-Wunused-variable]

  unsigned long tmp;

                ^

./arch/arm/include/asm/atomic.h:555:12: attention : unused variable ‘val’ [-Wunused-variable]

  long long val;

            ^

In file included from include/linux/atomic.h:577:0,

                 from include/linux/spinlock.h:417,

                 from include/linux/seqlock.h:35,

                 from include/linux/time.h:5,

                 from include/uapi/linux/timex.h:56,

                 from include/linux/timex.h:56,

                 from include/linux/sched.h:19,

                 from arch/arm/kernel/asm-offsets.c:14:

include/asm-generic/atomic-long.h: In function ‘atomic_long_add_return_unchecke ’:

include/asm-generic/atomic-long.h:84:1: erreur: implicit declaration of function ‘atomic_add_return_unchecked_relaxed’ [-Werror=implicit-function-declaration]

 ATOMIC_LONG_ADD_SUB_OP(add,,_unchecked)

 ^

include/asm-generic/atomic-long.h: In function ‘pax_refcount_needs_these_functions’:

include/asm-generic/atomic-long.h:224:2: erreur: implicit declaration of function ‘atomic_long_add_unchecked’ [-Werror=implicit-function-declaration]

  atomic_long_add_unchecked(0, (atomic_long_unchecked_t *)NULL);

  ^

include/asm-generic/atomic-long.h:225:2: erreur: implicit declaration of function ‘atomic_long_sub_unchecked’ [-Werror=implicit-function-declaration]

  atomic_long_sub_unchecked(0, (atomic_long_unchecked_t *)NULL);

  ^

include/asm-generic/atomic-long.h:226:2: erreur: implicit declaration of function ‘atomic_long_inc_unchecked’ [-Werror=implicit-function-declaration]

  atomic_long_inc_unchecked((atomic_long_unchecked_t *)NULL);

  ^

include/asm-generic/atomic-long.h:229:2: erreur: implicit declaration of function ‘atomic_long_dec_unchecked’ [-Werror=implicit-function-declaration]

  atomic_long_dec_unchecked((atomic_long_unchecked_t *)NULL);

  ^

In file included from include/linux/sched.h:37:0,

                 from arch/arm/kernel/asm-offsets.c:14:

include/linux/signal.h: In function ‘allow_signal’:

include/linux/signal.h:306:25: erreur: ‘__force_user’ undeclared (first use in this function)

  kernel_sigaction(sig, (__force_user __sighandler_t)2);

                         ^

include/linux/signal.h:306:25: note: each undeclared identifier is reported only once for each function it appears in

include/linux/signal.h:306:38: erreur: expected ‘)’ before ‘__sighandler_t’

  kernel_sigaction(sig, (__force_user __sighandler_t)2);

                                      ^

include/linux/signal.h:306:53: erreur: expected ‘)’ before numeric constant

  kernel_sigaction(sig, (__force_user __sighandler_t)2);

                                                     ^

In file included from arch/arm/kernel/asm-offsets.c:14:0:

include/linux/sched.h: Hors de toute fonction :

include/linux/sched.h:1864:23: erreur: duplicate member ‘thread’

  struct thread_struct thread;

                       ^

include/linux/sched.h: In function ‘current_is_ptracer’:

include/linux/sched.h:2354:27: erreur: ‘struct task_struct’ has no member named ‘exec_id’

    *exec_id = task->parent->exec_id;

                           ^

In file included from include/linux/mm.h:910:0,

                 from arch/arm/kernel/asm-offsets.c:15:

include/linux/vmstat.h: In function ‘zone_page_state_add’:

include/linux/vmstat.h:116:21: attention : passing argument 2 of ‘atomic_long_add’ from incompatible pointer type

  atomic_long_add(x, &zone->vm_stat[item]);

                     ^

In file included from include/linux/atomic.h:577:0,

                 from include/linux/spinlock.h:417,

                 from include/linux/seqlock.h:35,

                 from include/linux/time.h:5,

                 from include/uapi/linux/timex.h:56,

                 from include/linux/timex.h:56,

                 from include/linux/sched.h:19,

                 from arch/arm/kernel/asm-offsets.c:14:

include/asm-generic/atomic-long.h:133:1: note: expected ‘struct atomic_long_t *’ but argument is of type ‘struct atomic_long_unchecked_t *’

 atomic_long_##op(long i, atomic_long_t *l)    \

 ^

include/asm-generic/atomic-long.h:140:1: note: in expansion of macro ‘ATOMIC_LONG_OP’

 ATOMIC_LONG_OP(add)

 ^

cc1: some warnings being treated as errors

Kbuild:80 : la recette pour la cible « arch/arm/kernel/asm-offsets.s » a échouée

make[1]: *** [arch/arm/kernel/asm-offsets.s] Erreur 1

Makefile:1011 : la recette pour la cible « prepare0 » a échouée

make: *** [prepare0] Erreur 2

```

 :Question:  Petite question ? Penses tu que le fait d'utiliser ce profile et d'avoir recompiler le système et la toolchain (glibc, gcc...) avec les flags "hardened" activés, sécurise plus mon système contre d'éventuelles corruptions ou attaques ?

----------

## El_Goretto

 *jaypeche wrote:*   

> Bonjour El'go,
> 
>  Petite question ? Penses tu que le fait d'utiliser ce profile et d'avoir recompiler le système et la toolchain (glibc, gcc...) avec les flags "hardened" activés, sécurise plus mon système contre d'éventuelles corruptions ou attaques ?

 

Alors forcer un patch, bon déjà  :Smile:  Mais un patch noyau, fiouuu, c'est plutôt couillu  :Wink: 

Sinon, le profil hardened te permet de couvrir ce qui se fait côté "userland", et les patchs grsec couvrent ce qui peut se faire côté noyau. C'est une question de périmètre: tu vois le verre à moitié vide (plutôt mon point de vue) ou à moitié plein, pour résumer  :Smile: 

----------

## jaypeche

Salut El'Go,

Merçi pour ta réponse !

Effectivement, patcher à l'arrache un kernel, c'est pas génial du tout, mais ça reste expérimental et ne maitrisant pas les choses comme toi ou Xavier, ben je tente un peu ce qui est dans mes cordes.

J'ai choisi un profile hardened car c'est toujours ce que je fais quand je mets une machine Gentoo accessible sur le Net. Je connais bien la politique de sécurité de Gentoo et je lui fais confiance !

Je comprends bien ce que tu me dis, les flags hardened me permettent donc d'avoir un espace utilisateur plus secure mais pour l'espace noyau on repassera car le kernel raspberry n'est pas supporté par l'équipe gentoo en terme de sécurité :

 *Quote:*   

> 
> 
>  * raspberrypi-sources is UNSUPPORTED by Gentoo Security.
> 
>  * This means that it is likely to be vulnerable to recent security issues.
> ...

 

Je cherchais donc une solution pour rendre mon système mieux sécurisé, bien que je n'ai encore jamais vu de corruption de serveur avec une config hardened+iptables+++. Je vois passer un bon nombre d'attaques dans les logs, particulièrement SSH ! Merçi hardened, config par défaut des services, et merçi fail2ban qui est un outil précieux.

Ma raspberrypi serveur sert principalement pour Apache, je regrette juste de ne pas pouvoir sécurisé le noyau rpi, j'attends un peu mais je pense passer ce topic en (abandon).

Peut être devrais je me mettre à du selinux que je ne maitrise pas ou autre chose. Pour l'usage que j'en fais, je ne vais pas activer le mode paranoîde   :Confused: 

 :Question:  Auriez vous des suggestions, pour sécuriser un serveur LAMP sur cette plateforme ?

----------

## El_Goretto

Malheureusement, pas de solution miracle pour du LAMP.

J'ai même tendance à considérer qu'une machine avec une appli PHP exposée sur le net doit s'attendre un jour ou l'autre à se faire pwned... Donc mettre en place tes propres procédures rigoureuses de surveillance et de backup des données me semble une très bonne chose à faire, et te permettra de dormir sereinement  :Smile: 

---

edit: si tu as du nginx (à la place d'Apache), regarde du côté de naxsi. Je n'ai jamais eu le temps de tester correctement le bestiau (juste posé, lu la doc, pas compris la doc, reporté à plus tard, repeat...  :Smile: ) mais ça peut être sympa.

----------

## jaypeche

J'ai cependant ajouter le dernier patch grsec pour iptables ! On peut ainsi avoir une solution netfilter robuste et fiable http://ftp.pingwho.org/pub/gentoo/ftp/overlay/net-firewall/iptables/files/

 :Idea: 

----------

## HacKurx

Bonjour,

Je viens d’acquérir un Pi 3B+ et étant un ancien utilisateur de grsecurity, j'ai porté et upgradé sur le raspberry pi la dernière version publique du patch.

Pour l'utiliser,  veuillez compiler le noyau en suivant la documentation officielle :

https://www.raspberrypi.org/documentation/linux/kernel/building.md

Mais en utilisant ma branche git comme source :

https://github.com/HacKurx/linux-rpi_unofficial_grsec

Un example de config est disponible pour les Raspberry Pi 2, Pi 3, Pi 3+. Le résultat de paxtest est le suivant :

```
Distributor ID:   Raspbian

Description:   Raspbian GNU/Linux 9.6 (stretch)

Release:   9.6

Codename:   stretch

Test results:

Executable anonymous mapping             : Killed

Executable bss                           : Killed

Executable data                          : Killed

Executable heap                          : Killed

Executable stack                         : Killed

Executable shared library bss            : Killed

Executable shared library data           : Killed

Executable anonymous mapping (mprotect)  : Killed

Executable bss (mprotect)                : Killed

Executable data (mprotect)               : Killed

Executable heap (mprotect)               : Killed

Executable stack (mprotect)              : Killed

Executable shared library bss (mprotect) : Killed

Executable shared library data (mprotect): Killed

Writable text segments                   : Killed

Anonymous mapping randomization test     : 16 quality bits (guessed)

Heap randomization test (ET_EXEC)        : 22 quality bits (guessed)

Heap randomization test (PIE)            : 24 quality bits (guessed)

Main executable randomization (ET_EXEC)  : No randomization

Main executable randomization (PIE)      : 16 quality bits (guessed)

Shared library randomization test        : 16 quality bits (guessed)

VDSO randomization test                  : ./getvdso: Success

Stack randomization test (SEGMEXEC)      : 24 quality bits (guessed)

Stack randomization test (PAGEEXEC)      : 24 quality bits (guessed)

Arg/env randomization test (SEGMEXEC)    : 28 quality bits (guessed)

Arg/env randomization test (PAGEEXEC)    : 28 quality bits (guessed)

Offset to library randomisation (ET_EXEC): 16 quality bits (guessed)

Offset to library randomisation (ET_DYN) : 18 quality bits (guessed)

Randomization under memory exhaustion @~0: 16 bits (guessed)

Randomization under memory exhaustion @0 : No randomization

Return to function (strcpy)              : paxtest: return address contains a NULL byte.

Return to function (memcpy)              : Vulnerable

Return to function (strcpy, PIE)         : paxtest: return address contains a NULL byte.

Return to function (memcpy, PIE)         : Vulnerable
```

N'hésitez pas à me contacter par e-mail si-besoin.

Loic

----------

## El_Goretto

@HacKurx: impressionnant. Ça fait un sacré portfolio à emmener en entretien d'embauche  :Smile: 

----------

