From 50bac308305b53747b4830b27c69883aa16cc338 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 3e624bc..d86a774 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.
@@ -1095,6 +1127,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 0f904b3..fa4e4db 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 3013  /* disable PaX's PAGEEXEC feature */
+#define AID_PAX_NO_MPROTECT 3014  /* disable PaX's MPROTECT feature */
+#define AID_PAX_NO_RANDMMAP 3015  /* disable PaX's RANDMMAP feature */
+
 #endif
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index cf5f26c..9501bb8 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__
 
