
Date: Mon, 19 Dec 2011 10:26:47 +0900
Subject: [PATCH 1/9] add PaX linux staff from linux-2.6.27.

[defs.h]

Add rx and rw module members in offset_table and load_module structure.
Define PAX() and apply this condition in IN_MODULE() and IN_MODULE_INIT().
PaX module is scattered located in both RX and RW virtual address ranges.

[symbols.c: dump_offset_table()]

For dumping layout of struct module,
I felt specific purpose about last module_kallsyms_start entry,
add new entries in front of it.

[kernel.c: module_init()]

Because original key member's offsets about "struct module" are removed,
populate RX parts of PaX module's corresponding offsets into them.
This can be seem less annoying from current implementation such like
reading kallsyms, fixed is_module_adress() selection.

[notes]

The PAX() condition will be attached in the original palaces where
need to be distinct module object's member name or value treatments
but these must be small set, not make beyond necessity.

[constraints]

 Don't support older PaX kernel features than 2.6.27
 Don't consider hidden virtual address by CONFIG_PAX_KERNEXEC

Signed-off-by: Toshikazu Nakayama <nakayama.ts@ncos.nec.co.jp>
---
 defs.h    |   40 ++++++++++++++++++++++++++++++++++++++--
 kernel.c  |   39 +++++++++++++++++++++++++++++++++++++++
 symbols.c |   17 +++++++++++++++++
 3 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/defs.h b/defs.h
index 381e8c2..4470710 100755
--- a/defs.h
+++ b/defs.h
@@ -1617,6 +1617,14 @@ struct offset_table {                    /* stash of commonly-used offsets */
 	long user_regs_struct_r15;
 	long sched_entity_cfs_rq;
 	long sched_entity_my_q;
+	long module_module_core_rx;
+	long module_core_size_rx;
+	long module_module_init_rx;
+	long module_init_size_rx;
+	long module_module_core_rw;
+	long module_core_size_rw;
+	long module_module_init_rw;
+	long module_init_size_rw;
 };
 
 struct size_table {         /* stash of commonly-used sizes */
@@ -2160,14 +2168,42 @@ struct load_module {
 	struct syment *mod_init_symend;
 	ulong mod_percpu;
 	ulong mod_percpu_size;
+	ulong module_core_rx;
+	uint core_size_rx;
+	ulong module_init_rx;
+	uint init_size_rx;
+	ulong module_core_rw;
+	uint core_size_rw;
+	ulong module_init_rw;
+	uint init_size_rw;
 };
 
-#define IN_MODULE(A,L) \
+#define IN_MODULE_GENERIC(A,L) \
  (((ulong)(A) >= (L)->mod_base) && ((ulong)(A) < ((L)->mod_base+(L)->mod_size)))
 
-#define IN_MODULE_INIT(A,L) \
+#define IN_MODULE_INIT_GENERIC(A,L) \
  (((ulong)(A) >= (L)->mod_init_module_ptr) && ((ulong)(A) < ((L)->mod_init_module_ptr+(L)->mod_init_size)))
 
+#define PAX()	((THIS_KERNEL_VERSION >= LINUX(2,6,27)) && \
+		  VALID_MEMBER(module_module_core_rx))
+#define IN_MODULE_PAX(A,L) \
+ (((ulong)(A) >= (L)->module_core_rx) && \
+  ((ulong)(A) < ((L)->module_core_rx+(L->core_size_rx))) || \
+  ((ulong)(A) >= (L)->module_core_rw) && \
+  ((ulong)(A) < ((L)->module_core_rw+(L->core_size_rw))))
+
+#define IN_MODULE_INIT_PAX(A,L) \
+ (((ulong)(A) >= (L)->module_init_rx) && \
+  ((ulong)(A) < ((L)->module_init_rx+(L->init_size_rx))) || \
+  ((ulong)(A) >= (L)->module_init_rw) && \
+  ((ulong)(A) < ((L)->module_init_rw+(L->init_size_rw))))
+
+#define IN_MODULE(A,L) \
+	(!PAX() ? IN_MODULE_GENERIC(A,L) : IN_MODULE_PAX(A,L))
+
+#define IN_MODULE_INIT(A,L) \
+	((!PAX()) ? IN_MODULE_INIT_GENERIC(A,L) : IN_MODULE_INIT_PAX(A,L))
+
 #define IN_MODULE_PERCPU(A,L) \
  (((ulong)(A) >= (L)->mod_percpu) && ((ulong)(A) < ((L)->mod_percpu+(L)->mod_percpu_size)))
 
diff --git a/kernel.c b/kernel.c
index 2375911..a06f398 100755
--- a/kernel.c
+++ b/kernel.c
@@ -2754,6 +2754,45 @@ module_init(void)
 		MEMBER_OFFSET_INIT(module_init_text_size, "module", 
 			"init_text_size");
 		MEMBER_OFFSET_INIT(module_percpu, "module", "percpu");
+		MEMBER_OFFSET_INIT(module_module_core_rx, "module",
+				   "module_core_rx");
+		MEMBER_OFFSET_INIT(module_core_size_rx, "module",
+				   "core_size_rx");
+		MEMBER_OFFSET_INIT(module_module_init_rx, "module",
+				   "module_init_rx");
+		MEMBER_OFFSET_INIT(module_init_size_rx, "module",
+				   "init_size_rx");
+		MEMBER_OFFSET_INIT(module_module_core_rw, "module",
+				   "module_core_rw");
+		MEMBER_OFFSET_INIT(module_core_size_rw, "module",
+				   "core_size_rw");
+		MEMBER_OFFSET_INIT(module_module_init_rw, "module",
+				   "module_init_rw");
+		MEMBER_OFFSET_INIT(module_init_size_rw, "module",
+				   "init_size_rw");
+		if (PAX()) {
+			/*
+			 * PaX shall populate RX offsets into original ones.
+			 * This decision can work out PaX with less impact for
+			 * existing routines.
+			 *
+			 * Since PaX module dose not own text size,
+			 * these values should be sharpen by section attributes
+			 * while loading them from object file.
+			 */
+			MEMBER_OFFSET_INIT(module_module_core, "module",
+					   "module_core_rx");
+			MEMBER_OFFSET_INIT(module_core_size, "module",
+					   "core_size_rx");
+			MEMBER_OFFSET_INIT(module_core_text_size, "module",
+					   "core_size_rx");
+			MEMBER_OFFSET_INIT(module_module_init, "module",
+					   "module_init_rx");
+			MEMBER_OFFSET_INIT(module_init_size, "module",
+					   "init_size_rx");
+			MEMBER_OFFSET_INIT(module_init_text_size, "module",
+					   "init_size_rx");
+		}
 
 		/*
 		 *  Make sure to pick the kernel "modules" list_head symbol,
diff --git a/symbols.c b/symbols.c
index 6a9040b..477e423 100755
--- a/symbols.c
+++ b/symbols.c
@@ -7638,6 +7638,23 @@ dump_offset_table(char *spec, ulong makestruct)
 	fprintf(fp, "         module_attribute_attr: %ld\n",
         	OFFSET(module_attribute_attr));
 
+	fprintf(fp, "         module_module_core_rx: %ld\n",
+		OFFSET(module_module_core_rx));
+	fprintf(fp, "           module_core_size_rx: %ld\n",
+		OFFSET(module_core_size_rx));
+	fprintf(fp, "         module_module_init_rx: %ld\n",
+		OFFSET(module_module_init_rx));
+	fprintf(fp, "           module_init_size_rx: %ld\n",
+		OFFSET(module_init_size_rx));
+	fprintf(fp, "         module_module_core_rw: %ld\n",
+		OFFSET(module_module_core_rw));
+	fprintf(fp, "           module_core_size_rw: %ld\n",
+		OFFSET(module_core_size_rw));
+	fprintf(fp, "         module_module_init_rw: %ld\n",
+		OFFSET(module_module_init_rw));
+	fprintf(fp, "           module_init_size_rw: %ld\n",
+		OFFSET(module_init_size_rw));
+
         fprintf(fp, "         module_kallsyms_start: %ld\n",
         	OFFSET(module_kallsyms_start));
         fprintf(fp, "      kallsyms_header_sections: %ld\n",
-- 
1.7.8.163.g9859a



