Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extend SELinux memory protections to have parity with PaX MPROTECT #52

Open
thestinger opened this issue Aug 15, 2017 · 8 comments
Open

Comments

@thestinger
Copy link
Member

thestinger commented Aug 15, 2017

For example, PaX MPROTECT prevents relro sections from becoming writable again.

@sempervictus
Copy link

Does the SARA RFP meet this req? New LSM specifically targeting this aspect (and i think some level of device filtering).

@thestinger
Copy link
Member Author

Yes, but it's likely not flexible enough to use a different policy for distinct Android apps. PaX wasn't flexible enough to handle that and we had to patch in a new exception mode.

@sempervictus
Copy link

Thanks for the disambiguation. You don't happen to have that exception mode patch or commit somewhere do you?

@thestinger
Copy link
Member Author

Yes, I still have it along with the userspace changes that were paired with it. We're using SELinux for this now though, which is why the issue is filed about improving SELinux to have parity with PaX MPROTECT or to go beyond it.

From 2db7c8adfd0e57efb3554beb6ad424a144d1c2f7 Mon Sep 17 00:00:00 2001
From: Daniel Micay <danielmicay@gmail.com>
Date: Fri, 22 May 2015 18:17:24 -0400
Subject: [PATCH] implement PaX exception AIDs

---
 fs/binfmt_elf.c             | 34 ++++++++++++++++++++++++++++++++++
 include/linux/android_aid.h |  4 ++++
 include/linux/xattr.h       |  2 ++
 3 files changed, 40 insertions(+)

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 03972f12dd5..43723df6c65 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -9,6 +9,7 @@
  * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
  */
 
+#include <linux/android_aid.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
@@ -879,6 +880,37 @@ static long pax_parse_pax_flags(const struct elfhdr * const elf_ex, const struct
 }
 #endif
 
+static bool pax_has_aids_xattr(struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+
+	if (inode_permission(inode, MAY_EXEC))
+		return false;
+
+	if (inode->i_op->getxattr)
+		return inode->i_op->getxattr(dentry, XATTR_NAME_PAX_AIDS, NULL, 0) >= 0;
+
+	return false;
+}
+
+static void pax_handle_aids(struct file * const file)
+{
+	if (!pax_has_aids_xattr(file->f_path.dentry))
+		return;
+#ifdef CONFIG_PAX_PAGEEXEC
+	if (in_group_p(AID_PAX_NO_PAGEEXEC))
+		current->mm->pax_flags &= ~MF_PAX_PAGEEXEC;
+#endif
+#ifdef CONFIG_PAX_MPROTECT
+	if (in_group_p(AID_PAX_NO_MPROTECT))
+		current->mm->pax_flags &= ~MF_PAX_MPROTECT;
+#endif
+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
+	if (in_group_p(AID_PAX_NO_RANDMMAP))
+		current->mm->pax_flags &= ~MF_PAX_RANDMMAP;
+#endif
+}
+
 /*
  * These are the functions used to load ELF style executables and shared
  * libraries.  There is no binary dependent code anywhere else.
@@ -1094,6 +1126,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 	}
 #endif
 
+	pax_handle_aids(bprm->file);
+
 #ifdef CONFIG_PAX_HAVE_ACL_FLAGS
 	pax_set_initial_flags(bprm);
 #elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
diff --git a/include/linux/android_aid.h b/include/linux/android_aid.h
index 0f904b3ba7f..ea96d1c9ceb 100644
--- a/include/linux/android_aid.h
+++ b/include/linux/android_aid.h
@@ -25,4 +25,8 @@
 #define AID_NET_BW_STATS 3006  /* read bandwidth statistics */
 #define AID_NET_BW_ACCT  3007  /* change bandwidth statistics accounting */
 
+#define AID_PAX_NO_PAGEEXEC 3010  /* disable PaX's PAGEEXEC feature */
+#define AID_PAX_NO_MPROTECT 3011  /* disable PaX's MPROTECT feature */
+#define AID_PAX_NO_RANDMMAP 3012  /* disable PaX's RANDMMAP feature */
+
 #endif
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index cf5f26caa99..9501bb8c51e 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -60,7 +60,9 @@
 /* User namespace */
 #define XATTR_PAX_PREFIX XATTR_USER_PREFIX "pax."
 #define XATTR_PAX_FLAGS_SUFFIX "flags"
+#define XATTR_PAX_AIDS_SUFFIX "aids"
 #define XATTR_NAME_PAX_FLAGS XATTR_PAX_PREFIX XATTR_PAX_FLAGS_SUFFIX
+#define XATTR_NAME_PAX_AIDS XATTR_PAX_PREFIX XATTR_PAX_AIDS_SUFFIX
 
 #ifdef  __KERNEL__

@thestinger
Copy link
Member Author

And FWIW, 100% of the blame Google for the naming of Android IDs (AIDs) is on Google. :P

@sempervictus
Copy link

sempervictus commented Oct 8, 2017 via email

@thestinger
Copy link
Member Author

The way it works with this AIDs patch is that we used standard Android permissions for this. Android has the option of mapping a permission to a GID which is how the socket permissions work (similar to the grsecurity socket permissions) which is one of the few remaining out-of-tree patches for Android itself (as opposed to mobile SoC supported needed with or without Android).

@thestinger
Copy link
Member Author

This code does require marking executables where the GIDs should enable the exceptions because we only wanted it to apply to app_process but it doesn't have to be done that way.

randomhydrosol pushed a commit to randomhydrosol/linux-hardened that referenced this issue Nov 9, 2018
Increase kasan instrumented kernel stack size from 32k to 64k. Other
architectures seems to get away with just doubling kernel stack size under
kasan, but on s390 this appears to be not enough due to bigger frame size.
The particular pain point is kasan inlined checks (CONFIG_KASAN_INLINE
vs CONFIG_KASAN_OUTLINE). With inlined checks one particular case hitting
stack overflow is fs sync on xfs filesystem:

 #0 [9a0681e8]  704 bytes  check_usage at 34b1fc
 GrapheneOS#1 [9a0684a8]  432 bytes  check_usage at 34c710
 GrapheneOS#2 [9a068658]  1048 bytes  validate_chain at 35044a
 GrapheneOS#3 [9a068a70]  312 bytes  __lock_acquire at 3559fe
 GrapheneOS#4 [9a068ba8]  440 bytes  lock_acquire at 3576ee
 GrapheneOS#5 [9a068d60]  104 bytes  _raw_spin_lock at 21b44e0
 GrapheneOS#6 [9a068dc8]  1992 bytes  enqueue_entity at 2dbf72
 GrapheneOS#7 [9a069590]  1496 bytes  enqueue_task_fair at 2df5f0
 GrapheneOS#8 [9a069b68]  64 bytes  ttwu_do_activate at 28f438
 GrapheneOS#9 [9a069ba8]  552 bytes  try_to_wake_up at 298c4c
 GrapheneOS#10 [9a069dd0]  168 bytes  wake_up_worker at 23f97c
 GrapheneOS#11 [9a069e78]  200 bytes  insert_work at 23fc2e
 GrapheneOS#12 [9a069f40]  648 bytes  __queue_work at 2487c0
 GrapheneOS#13 [9a06a1c8]  200 bytes  __queue_delayed_work at 24db28
 GrapheneOS#14 [9a06a290]  248 bytes  mod_delayed_work_on at 24de84
 GrapheneOS#15 [9a06a388]  24 bytes  kblockd_mod_delayed_work_on at 153e2a0
 GrapheneOS#16 [9a06a3a0]  288 bytes  __blk_mq_delay_run_hw_queue at 158168c
 GrapheneOS#17 [9a06a4c0]  192 bytes  blk_mq_run_hw_queue at 1581a3c
 GrapheneOS#18 [9a06a580]  184 bytes  blk_mq_sched_insert_requests at 15a2192
 GrapheneOS#19 [9a06a638]  1024 bytes  blk_mq_flush_plug_list at 1590f3a
 GrapheneOS#20 [9a06aa38]  704 bytes  blk_flush_plug_list at 1555028
 GrapheneOS#21 [9a06acf8]  320 bytes  schedule at 219e476
 GrapheneOS#22 [9a06ae38]  760 bytes  schedule_timeout at 21b0aac
 GrapheneOS#23 [9a06b130]  408 bytes  wait_for_common at 21a1706
 GrapheneOS#24 [9a06b2c8]  360 bytes  xfs_buf_iowait at fa1540
 GrapheneOS#25 [9a06b430]  256 bytes  __xfs_buf_submit at fadae6
 GrapheneOS#26 [9a06b530]  264 bytes  xfs_buf_read_map at fae3f6
 GrapheneOS#27 [9a06b638]  656 bytes  xfs_trans_read_buf_map at 10ac9a8
 GrapheneOS#28 [9a06b8c8]  304 bytes  xfs_btree_kill_root at e72426
 GrapheneOS#29 [9a06b9f8]  288 bytes  xfs_btree_lookup_get_block at e7bc5e
 GrapheneOS#30 [9a06bb18]  624 bytes  xfs_btree_lookup at e7e1a6
 GrapheneOS#31 [9a06bd88]  2664 bytes  xfs_alloc_ag_vextent_near at dfa070
 GrapheneOS#32 [9a06c7f0]  144 bytes  xfs_alloc_ag_vextent at dff3ca
 GrapheneOS#33 [9a06c880]  1128 bytes  xfs_alloc_vextent at e05fce
 GrapheneOS#34 [9a06cce8]  584 bytes  xfs_bmap_btalloc at e58342
 GrapheneOS#35 [9a06cf30]  1336 bytes  xfs_bmapi_write at e618de
 GrapheneOS#36 [9a06d468]  776 bytes  xfs_iomap_write_allocate at ff678e
 GrapheneOS#37 [9a06d770]  720 bytes  xfs_map_blocks at f82af8
 GrapheneOS#38 [9a06da40]  928 bytes  xfs_writepage_map at f83cd6
 GrapheneOS#39 [9a06dde0]  320 bytes  xfs_do_writepage at f85872
 GrapheneOS#40 [9a06df20]  1320 bytes  write_cache_pages at 73dfe8
 GrapheneOS#41 [9a06e448]  208 bytes  xfs_vm_writepages at f7f892
 GrapheneOS#42 [9a06e518]  88 bytes  do_writepages at 73fe6a
 GrapheneOS#43 [9a06e570]  872 bytes  __writeback_single_inode at a20cb6
 GrapheneOS#44 [9a06e8d8]  664 bytes  writeback_sb_inodes at a23be2
 GrapheneOS#45 [9a06eb70]  296 bytes  __writeback_inodes_wb at a242e0
 GrapheneOS#46 [9a06ec98]  928 bytes  wb_writeback at a2500e
 GrapheneOS#47 [9a06f038]  848 bytes  wb_do_writeback at a260ae
 GrapheneOS#48 [9a06f388]  536 bytes  wb_workfn at a28228
 GrapheneOS#49 [9a06f5a0]  1088 bytes  process_one_work at 24a234
 GrapheneOS#50 [9a06f9e0]  1120 bytes  worker_thread at 24ba26
 GrapheneOS#51 [9a06fe40]  104 bytes  kthread at 26545a
 GrapheneOS#52 [9a06fea8]             kernel_thread_starter at 21b6b62

To be able to increase the stack size to 64k reuse LLILL instruction
in __switch_to function to load 64k - STACK_FRAME_OVERHEAD - __PT_SIZE
(65192) value as unsigned.

Reported-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants