Stacking LSM proof-of-concept

From: John Richard Moser (nigelenki@private)
Date: Thu Jan 27 2005 - 20:20:03 PST


I've been academically examining (== ripping off) LSM and GrSecurity for
the past few days, and managed to implement an LSM infrastructure that
does full transparent stacking and allows about 5-10 hooks (I'm not
counting) to implement part of GrSecurity (very little).

This patch has been tested with 3 dummy modules to do transparent
stacking.  The dummy modules produce unique output with
printk(KERN_INFO) when you cat /proc/self/maps.  There's also a kernsec
module to implement GrSecurity linking restrictions and partial /proc
restrictions, which I wrote to learn how those work.

Here's the patch.  I'm not on the list so CC me replies.  Any comments?
 It's just an academic toy, not a patch to LSM or anything; but I'd like
to know how I did.  I designed the stacking myself in 5 minutes,
implemented in 10, then spent all day fixing an obscure bug (I treated
the doubly linked list as singly linked when registering, and doubly
when unregistering).  It's nothing major.

-- 
All content of all messages exchanged herein are left in the
Public Domain, unless otherwise explicitly stated.



diff -urNp linux-2.6.10/arch/alpha/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/alpha/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/alpha/kernel/vmlinux.lds.S	2004-12-24 16:34:57.000000000 -0500
+++ linux-2.6.10-grs/arch/alpha/kernel/vmlinux.lds.S	2005-01-25 18:47:17.650995000 -0500
@@ -73,6 +73,7 @@ SECTIONS
 
   . = ALIGN(8);
   SECURITY_INIT
+  GRSECURITY_INIT
 
   . = ALIGN(64);
   __per_cpu_start = .;
diff -urNp linux-2.6.10/arch/cris/arch-v10/vmlinux.lds.S linux-2.6.10-grs/arch/cris/arch-v10/vmlinux.lds.S
--- linux-2.6.10/arch/cris/arch-v10/vmlinux.lds.S	2004-12-24 16:34:32.000000000 -0500
+++ linux-2.6.10-grs/arch/cris/arch-v10/vmlinux.lds.S	2005-01-25 18:47:17.650995000 -0500
@@ -83,6 +83,7 @@ SECTIONS
 		__con_initcall_end = .;
 	}	
 	SECURITY_INIT
+  GRSECURITY_INIT
 		
 	.init.ramfs : {
 		__initramfs_start = .;
diff -urNp linux-2.6.10/arch/h8300/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/h8300/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/h8300/kernel/vmlinux.lds.S	2004-12-24 16:35:00.000000000 -0500
+++ linux-2.6.10-grs/arch/h8300/kernel/vmlinux.lds.S	2005-01-25 18:47:17.651995000 -0500
@@ -88,6 +88,7 @@ SECTIONS
 	RODATA
 #if defined(CONFIG_ROMKERNEL)
 	SECURITY_INIT
+  GRSECURITY_INIT
 #endif
 	ROEND = .; 
 #if defined(CONFIG_ROMKERNEL)
@@ -142,6 +143,7 @@ SECTIONS
 	}
 #if defined(CONFIG_RAMKERNEL)
 	SECURITY_INIT
+  GRSECURITY_INIT
 #endif
 	__begin_data = LOADADDR(.data);
         .bss : 
diff -urNp linux-2.6.10/arch/i386/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/i386/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/i386/kernel/vmlinux.lds.S	2004-12-24 16:35:50.000000000 -0500
+++ linux-2.6.10-grs/arch/i386/kernel/vmlinux.lds.S	2005-01-25 18:47:17.651995000 -0500
@@ -83,6 +83,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   . = ALIGN(4);
   __alt_instructions = .;
   .altinstructions : { *(.altinstructions) } 
diff -urNp linux-2.6.10/arch/m32r/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/m32r/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/m32r/kernel/vmlinux.lds.S	2004-12-24 16:34:26.000000000 -0500
+++ linux-2.6.10-grs/arch/m32r/kernel/vmlinux.lds.S	2005-01-25 18:47:17.651995000 -0500
@@ -97,6 +97,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   . = ALIGN(4);
   __alt_instructions = .;
   .altinstructions : { *(.altinstructions) }
diff -urNp linux-2.6.10/arch/mips/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/mips/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/mips/kernel/vmlinux.lds.S	2004-12-24 16:34:30.000000000 -0500
+++ linux-2.6.10-grs/arch/mips/kernel/vmlinux.lds.S	2005-01-25 18:47:17.652994000 -0500
@@ -118,6 +118,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   . = ALIGN(4096);
   __initramfs_start = .;
   .init.ramfs : { *(.init.ramfs) }
diff -urNp linux-2.6.10/arch/parisc/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/parisc/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/parisc/kernel/vmlinux.lds.S	2004-12-24 16:34:26.000000000 -0500
+++ linux-2.6.10-grs/arch/parisc/kernel/vmlinux.lds.S	2005-01-25 18:47:17.653994000 -0500
@@ -146,6 +146,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   /* alternate instruction replacement.  This is a mechanism x86 uses
    * to detect the CPU type and replace generic instruction sequences
    * with CPU specific ones.  We don't currently do this in PA, but
diff -urNp linux-2.6.10/arch/ppc/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/ppc/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/ppc/kernel/vmlinux.lds.S	2004-12-24 16:35:50.000000000 -0500
+++ linux-2.6.10-grs/arch/ppc/kernel/vmlinux.lds.S	2005-01-25 18:47:17.653994000 -0500
@@ -120,6 +120,7 @@ SECTIONS
   __con_initcall_end = .;
 
   SECURITY_INIT
+  GRSECURITY_INIT
 
   __start___ftr_fixup = .;
   __ftr_fixup : { *(__ftr_fixup) }
diff -urNp linux-2.6.10/arch/ppc64/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/ppc64/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/ppc64/kernel/vmlinux.lds.S	2004-12-24 16:35:23.000000000 -0500
+++ linux-2.6.10-grs/arch/ppc64/kernel/vmlinux.lds.S	2005-01-25 18:47:17.654994000 -0500
@@ -81,6 +81,7 @@ SECTIONS
 	}
 
   SECURITY_INIT
+  GRSECURITY_INIT
 
   . = ALIGN(4096);
   .init.ramfs : {
diff -urNp linux-2.6.10/arch/s390/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/s390/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/s390/kernel/vmlinux.lds.S	2004-12-24 16:34:31.000000000 -0500
+++ linux-2.6.10-grs/arch/s390/kernel/vmlinux.lds.S	2005-01-25 18:47:17.654994000 -0500
@@ -94,6 +94,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   . = ALIGN(256);
   __initramfs_start = .;
   .init.ramfs : { *(.init.initramfs) }
diff -urNp linux-2.6.10/arch/sh/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/sh/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/sh/kernel/vmlinux.lds.S	2004-12-24 16:34:58.000000000 -0500
+++ linux-2.6.10-grs/arch/sh/kernel/vmlinux.lds.S	2005-01-25 18:47:17.654994000 -0500
@@ -91,6 +91,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   __initramfs_start = .;
   .init.ramfs : { *(.init.ramfs) }
   __initramfs_end = .;
diff -urNp linux-2.6.10/arch/sh64/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/sh64/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/sh64/kernel/vmlinux.lds.S	2004-12-24 16:34:01.000000000 -0500
+++ linux-2.6.10-grs/arch/sh64/kernel/vmlinux.lds.S	2005-01-25 18:47:17.655994000 -0500
@@ -122,6 +122,7 @@ SECTIONS
   .con_initcall.init : C_PHYS(.con_initcall.init) { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   __initramfs_start = .;
   .init.ramfs : C_PHYS(.init.ramfs) { *(.init.ramfs) }
   __initramfs_end = .;
diff -urNp linux-2.6.10/arch/sparc/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/sparc/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/sparc/kernel/vmlinux.lds.S	2004-12-24 16:33:51.000000000 -0500
+++ linux-2.6.10-grs/arch/sparc/kernel/vmlinux.lds.S	2005-01-25 18:47:17.655994000 -0500
@@ -62,6 +62,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   . = ALIGN(4096);
   __initramfs_start = .;
   .init.ramfs : { *(.init.ramfs) }
diff -urNp linux-2.6.10/arch/sparc64/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/sparc64/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/sparc64/kernel/vmlinux.lds.S	2004-12-24 16:35:25.000000000 -0500
+++ linux-2.6.10-grs/arch/sparc64/kernel/vmlinux.lds.S	2005-01-25 18:47:17.656994000 -0500
@@ -68,6 +68,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   . = ALIGN(8192); 
   __initramfs_start = .;
   .init.ramfs : { *(.init.ramfs) }
diff -urNp linux-2.6.10/arch/x86_64/kernel/vmlinux.lds.S linux-2.6.10-grs/arch/x86_64/kernel/vmlinux.lds.S
--- linux-2.6.10/arch/x86_64/kernel/vmlinux.lds.S	2004-12-24 16:33:50.000000000 -0500
+++ linux-2.6.10-grs/arch/x86_64/kernel/vmlinux.lds.S	2005-01-25 18:47:17.656994000 -0500
@@ -108,6 +108,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  GRSECURITY_INIT
   . = ALIGN(8);
   __alt_instructions = .;
   .altinstructions : { *(.altinstructions) } 
diff -urNp linux-2.6.10/drivers/char/keyboard.c linux-2.6.10-grs/drivers/char/keyboard.c
--- linux-2.6.10/drivers/char/keyboard.c	2004-12-24 16:35:50.000000000 -0500
+++ linux-2.6.10-grs/drivers/char/keyboard.c	2005-01-25 20:46:06.348314000 -0500
@@ -40,6 +40,7 @@
 #include <linux/vt_kern.h>
 #include <linux/sysrq.h>
 #include <linux/input.h>
+#include <linux/grsecurity.h>
 
 static void kbd_disconnect(struct input_handle *handle);
 extern void ctrl_alt_del(void);
@@ -82,16 +83,9 @@ typedef void (k_handler_fn)(struct vc_da
 static k_handler_fn K_HANDLERS;
 static k_handler_fn *k_handler[16] = { K_HANDLERS };
 
-#define FN_HANDLERS\
-	fn_null, 	fn_enter,	fn_show_ptregs,	fn_show_mem,\
-	fn_show_state,	fn_send_intr, 	fn_lastcons, 	fn_caps_toggle,\
-	fn_num,		fn_hold, 	fn_scroll_forw,	fn_scroll_back,\
-	fn_boot_it, 	fn_caps_on, 	fn_compose,	fn_SAK,\
-	fn_dec_console, fn_inc_console, fn_spawn_con, 	fn_bare_num
-
 typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs);
-static fn_handler_fn FN_HANDLERS;
-static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
+static fn_handler_fn _KBD_FN_HANDLERS;
+static fn_handler_fn *fn_handler[] = { _KBD_FN_HANDLERS };
 
 /*
  * Variables exported for vt_ioctl.c
@@ -605,6 +599,10 @@ static void k_spec(struct vc_data *vc, u
 	     kbd->kbdmode == VC_MEDIUMRAW) && 
 	     value != KVAL(K_SAK))
 		return;		/* SAK is allowed even in raw mode */
+#ifdef CONFIG_GRSECURITY
+	if (gr_keyboard_handler(value))
+		return;
+#endif
 	fn_handler[value](vc, regs);
 }
 
diff -urNp linux-2.6.10/drivers/pci/proc.c linux-2.6.10-grs/drivers/pci/proc.c
--- linux-2.6.10/drivers/pci/proc.c	2004-12-24 16:34:58.000000000 -0500
+++ linux-2.6.10-grs/drivers/pci/proc.c	2005-01-25 21:01:26.312458000 -0500
@@ -12,6 +12,9 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/smp_lock.h>
+#ifdef CONFIG_GRSECURITY
+# include <linux/grsecurity.h>
+#endif
 
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
@@ -565,7 +568,19 @@ static struct file_operations proc_pci_o
 
 static void legacy_proc_init(void)
 {
-	struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
+	struct proc_dir_entry * entry = NULL;
+#ifdef CONFIG_GRSECURITY
+	int error;
+	error = gr_proc_pci_legacy_init(&entry);
+	/*
+	 * If this returns 0, we generate the entry as normal.
+	 * If it returns non-zero, we assume entry was or will not be
+	 * generated
+	 */
+	if (!error)
+#else
+	entry = create_proc_entry("pci", 0, NULL);
+#endif
 	if (entry)
 		entry->proc_fops = &proc_pci_operations;
 }
@@ -592,8 +607,17 @@ static struct file_operations proc_bus_p
 
 static int __init pci_proc_init(void)
 {
-	struct proc_dir_entry *entry;
+	struct proc_dir_entry *entry = NULL;
 	struct pci_dev *dev = NULL;
+#ifdef CONFIG_GRSECURITY
+	int error;
+	/*
+	 * Same deal as gr_proc_pci_legacy_init()
+	 * a 0 here means "Make your own", otherwise it's filled for us.
+	 */
+	error = gr_proc_pci_init(&proc_bus_pci_dir);
+	if (!error)
+#endif
 	proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
 	entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
 	if (entry)
diff -urNp linux-2.6.10/fs/namei.c linux-2.6.10-grs/fs/namei.c
--- linux-2.6.10/fs/namei.c	2004-12-24 16:34:30.000000000 -0500
+++ linux-2.6.10-grs/fs/namei.c	2005-01-25 21:39:42.065019000 -0500
@@ -28,6 +28,9 @@
 #include <linux/syscalls.h>
 #include <linux/mount.h>
 #include <linux/audit.h>
+#ifdef CONFIG_GRSECURITY
+# include <linux/grsecurity.h>
+#endif
 #include <asm/namei.h>
 #include <asm/uaccess.h>
 
@@ -497,6 +500,9 @@ static inline int do_follow_link(struct 
 	BUG_ON(nd->depth >= MAX_NESTED_LINKS);
 	cond_resched();
 	err = security_inode_follow_link(dentry, nd);
+#ifdef CONFIG_GRSECURITY
+	err = gr_inode_follow_link(dentry, nd);
+#endif
 	if (err)
 		goto loop;
 	current->link_count++;
@@ -581,20 +587,20 @@ int follow_down(struct vfsmount **mnt, s
 {
 	return __follow_down(mnt,dentry);
 }
- 
+
 static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
 {
 	while(1) {
 		struct vfsmount *parent;
 		struct dentry *old = *dentry;
 
-                read_lock(&current->fs->lock);
+		read_lock(&current->fs->lock);
 		if (*dentry == current->fs->root &&
-		    *mnt == current->fs->rootmnt) {
-                        read_unlock(&current->fs->lock);
+				*mnt == current->fs->rootmnt) {
+			read_unlock(&current->fs->lock);
 			break;
 		}
-                read_unlock(&current->fs->lock);
+		read_unlock(&current->fs->lock);
 		spin_lock(&dcache_lock);
 		if (*dentry != (*mnt)->mnt_root) {
 			*dentry = dget((*dentry)->d_parent);
@@ -630,7 +636,7 @@ struct path {
  *  It _is_ time-critical.
  */
 static int do_lookup(struct nameidata *nd, struct qstr *name,
-		     struct path *path)
+		struct path *path)
 {
 	struct vfsmount *mnt = nd->mnt;
 	struct dentry *dentry = __d_lookup(nd->dentry, name);
@@ -676,7 +682,7 @@ int fastcall link_path_walk(const char *
 	struct inode *inode;
 	int err;
 	unsigned int lookup_flags = nd->flags;
-	
+
 	while (*name=='/')
 		name++;
 	if (!*name)
@@ -696,7 +702,7 @@ int fastcall link_path_walk(const char *
 		if (err == -EAGAIN) { 
 			err = permission(inode, MAY_EXEC, nd);
 		}
- 		if (err)
+		if (err)
 			break;
 
 		this.name = name;
@@ -814,7 +820,7 @@ last_component:
 		follow_mount(&next.mnt, &next.dentry);
 		inode = next.dentry->d_inode;
 		if ((lookup_flags & LOOKUP_FOLLOW)
-		    && inode && inode->i_op && inode->i_op->follow_link) {
+				&& inode && inode->i_op && inode->i_op->follow_link) {
 			mntget(next.mnt);
 			err = do_follow_link(next.dentry, nd);
 			dput(next.dentry);
@@ -853,7 +859,7 @@ return_reval:
 		 * We may need to check the cached dentry for staleness.
 		 */
 		if (nd->dentry && nd->dentry->d_sb &&
-		    (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
+				(nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
 			err = -ESTALE;
 			/* Note: we do not d_invalidate() */
 			if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd))
@@ -969,10 +975,10 @@ int fastcall path_lookup(const char *nam
 	current->total_link_count = 0;
 	retval = link_path_walk(name, nd);
 	if (unlikely(current->audit_context
-		     && nd && nd->dentry && nd->dentry->d_inode))
+				&& nd && nd->dentry && nd->dentry->d_inode))
 		audit_inode(name,
-			    nd->dentry->d_inode->i_ino,
-			    nd->dentry->d_inode->i_rdev);
+				nd->dentry->d_inode->i_ino,
+				nd->dentry->d_inode->i_rdev);
 	return retval;
 }
 
@@ -1123,7 +1129,7 @@ static inline int may_delete(struct inod
 	if (IS_APPEND(dir))
 		return -EPERM;
 	if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
-	    IS_IMMUTABLE(victim->d_inode))
+			IS_IMMUTABLE(victim->d_inode))
 		return -EPERM;
 	if (isdir) {
 		if (!S_ISDIR(victim->d_inode->i_mode))
@@ -1148,7 +1154,7 @@ static inline int may_delete(struct inod
  *  4. We can't do it if dir is immutable (done in permission())
  */
 static inline int may_create(struct inode *dir, struct dentry *child,
-			     struct nameidata *nd)
+		struct nameidata *nd)
 {
 	if (child->d_inode)
 		return -EEXIST;
@@ -1169,10 +1175,10 @@ static inline int lookup_flags(unsigned 
 
 	if (f & O_NOFOLLOW)
 		retval &= ~LOOKUP_FOLLOW;
-	
+
 	if ((f & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
 		retval &= ~LOOKUP_FOLLOW;
-	
+
 	if (f & O_DIRECTORY)
 		retval |= LOOKUP_DIRECTORY;
 
@@ -1258,7 +1264,7 @@ int may_open(struct nameidata *nd, int a
 
 	if (S_ISLNK(inode->i_mode))
 		return -ELOOP;
-	
+
 	if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
 		return -EISDIR;
 
@@ -1272,7 +1278,7 @@ int may_open(struct nameidata *nd, int a
 	 * can write to them even if the filesystem is read-only.
 	 */
 	if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
-	    	flag &= ~O_TRUNC;
+		flag &= ~O_TRUNC;
 	} else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
 		if (nd->mnt->mnt_flags & MNT_NODEV)
 			return -EACCES;
@@ -1313,7 +1319,7 @@ int may_open(struct nameidata *nd, int a
 		error = locks_verify_locked(inode);
 		if (!error) {
 			DQUOT_INIT(inode);
-			
+
 			error = do_truncate(dentry, 0);
 		}
 		put_write_access(inode);
@@ -1584,21 +1590,21 @@ asmlinkage long sys_mknod(const char __u
 		mode &= ~current->fs->umask;
 	if (!IS_ERR(dentry)) {
 		switch (mode & S_IFMT) {
-		case 0: case S_IFREG:
-			error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
-			break;
-		case S_IFCHR: case S_IFBLK:
-			error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
-					new_decode_dev(dev));
-			break;
-		case S_IFIFO: case S_IFSOCK:
-			error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
-			break;
-		case S_IFDIR:
-			error = -EPERM;
-			break;
-		default:
-			error = -EINVAL;
+			case 0: case S_IFREG:
+				error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
+				break;
+			case S_IFCHR: case S_IFBLK:
+				error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
+						new_decode_dev(dev));
+				break;
+			case S_IFIFO: case S_IFSOCK:
+				error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
+				break;
+			case S_IFDIR:
+				error = -EPERM;
+				break;
+			default:
+				error = -EINVAL;
 		}
 		dput(dentry);
 	}
@@ -1685,14 +1691,14 @@ void dentry_unhash(struct dentry *dentry
 	dget(dentry);
 	spin_lock(&dcache_lock);
 	switch (atomic_read(&dentry->d_count)) {
-	default:
-		spin_unlock(&dcache_lock);
-		shrink_dcache_parent(dentry);
-		spin_lock(&dcache_lock);
-		if (atomic_read(&dentry->d_count) != 2)
-			break;
-	case 2:
-		__d_drop(dentry);
+		default:
+			spin_unlock(&dcache_lock);
+			shrink_dcache_parent(dentry);
+			spin_lock(&dcache_lock);
+			if (atomic_read(&dentry->d_count) != 2)
+				break;
+		case 2:
+			__d_drop(dentry);
 	}
 	spin_unlock(&dcache_lock);
 }
@@ -1837,7 +1843,7 @@ asmlinkage long sys_unlink(const char __
 		if (inode)
 			atomic_inc(&inode->i_count);
 		error = vfs_unlink(nd.dentry->d_inode, dentry);
-	exit2:
+exit2:
 		dput(dentry);
 	}
 	up(&nd.dentry->d_inode->i_sem);
@@ -1983,7 +1989,15 @@ asmlinkage long sys_link(const char __us
 	new_dentry = lookup_create(&nd, 0);
 	error = PTR_ERR(new_dentry);
 	if (!IS_ERR(new_dentry)) {
+#ifdef CONFIG_GRSECURITY
+		error = gr_inode_hardlink(new_dentry, &old_nd, &nd, to);
+		if (!error)
+#endif
 		error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+#ifdef CONFIG_GRSECURITY
+		if (!error)
+			gr_inode_handle_create(new_dentry, nd.mnt);
+#endif
 		dput(new_dentry);
 	}
 	up(&nd.dentry->d_inode->i_sem);
diff -urNp linux-2.6.10/fs/proc/array.c linux-2.6.10-grs/fs/proc/array.c
--- linux-2.6.10/fs/proc/array.c	2004-12-24 16:35:00.000000000 -0500
+++ linux-2.6.10-grs/fs/proc/array.c	2005-01-25 22:52:50.399890000 -0500
@@ -73,6 +73,9 @@
 #include <linux/highmem.h>
 #include <linux/file.h>
 #include <linux/times.h>
+#ifdef CONFIG_GRSECURITY
+# include <linux/grsecurity.h>
+#endif
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -303,6 +306,7 @@ int proc_pid_status(struct task_struct *
 static int do_task_stat(struct task_struct *task, char * buffer, int whole)
 {
 	unsigned long vsize, eip, esp, wchan = ~0UL;
+	unsigned long start_code, end_code, start_stack;
 	long priority, nice;
 	int tty_pgrp = -1, tty_nr = 0;
 	sigset_t sigign, sigcatch;
@@ -394,6 +398,37 @@ static int do_task_stat(struct task_stru
 	/* convert nsec -> ticks */
 	start_time = nsec_to_clock_t(start_time);
 
+	/*
+	 * This is to set up for grsecurity hooks
+	 */
+	if (mm) {
+		start_code = mm->start_code;
+		end_code = mm->end_code;
+		start_stack = mm->start_stack;
+	}
+	else
+		start_code = end_code = start_stack = 0;
+#ifdef CONFIG_GRSECURITY
+	/*
+	 * GrSecurity gets a crack at protecting this information.
+	 * No need to pass mm; we can use get_task_mm() if it's needed.
+	 *
+	 * If the gr_proc_task_stat() hooks return 0, they may have altered
+	 * one, some, or all of the passed pieces of data.  Each registered
+	 * module has a chance to knock some off this way.
+	 * 
+	 * If the gr_proc_task_stat() hooks return non-zero, then a NULL
+	 * string is returned.
+	 */
+	if (gr_proc_task_stat(&eip, &esp, &wchan,
+		       	&start_code, &end_code, &start_stack,
+			task)) {
+		buffer[0] = '\0';
+		res = 0;
+		goto out;
+	}
+			
+#endif
 	res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
 %lu %lu %lu %lu %lu %ld %ld %ld %ld %d %ld %llu %lu %ld %lu %lu %lu %lu %lu \
 %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu\n",
@@ -422,9 +457,9 @@ static int do_task_stat(struct task_stru
 		vsize,
 		mm ? mm->rss : 0, /* you might want to shift this left 3 */
 	        rsslim,
-		mm ? mm->start_code : 0,
-		mm ? mm->end_code : 0,
-		mm ? mm->start_stack : 0,
+		start_code,
+		end_code,
+		start_stack,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
@@ -442,6 +477,7 @@ static int do_task_stat(struct task_stru
 		task_cpu(task),
 		task->rt_priority,
 		task->policy);
+out:
 	if(mm)
 		mmput(mm);
 	return res;
diff -urNp linux-2.6.10/fs/proc/base.c linux-2.6.10-grs/fs/proc/base.c
--- linux-2.6.10/fs/proc/base.c	2004-12-24 16:35:00.000000000 -0500
+++ linux-2.6.10-grs/fs/proc/base.c	2005-01-26 16:06:14.283329000 -0500
@@ -31,6 +31,9 @@
 #include <linux/kallsyms.h>
 #include <linux/mount.h>
 #include <linux/security.h>
+#ifdef CONFIG_GRSECURITY
+# include <linux/grsecurity.h>
+#endif
 #include <linux/ptrace.h>
 
 /*
@@ -473,9 +476,22 @@ out:
 
 static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
-	if (generic_permission(inode, mask, NULL) != 0)
-		return -EACCES;
-	return proc_check_root(inode);
+	int ret;
+	if (generic_permission(inode, mask, NULL) != 0) {
+		ret = -EACCES;
+		goto out;
+	}
+	ret = proc_check_root(inode);
+#ifdef CONFIG_GRSECURITY
+	if (ret)
+		goto out;
+
+	/*you can proc_task(inode) from within the call*/
+	ret = gr_proc_permission(inode);
+#endif
+
+out:
+	return ret;
 }
 
 extern struct seq_operations proc_pid_maps_op;
@@ -961,6 +977,14 @@ static struct inode *proc_pid_make_inode
 		inode->i_uid = task->euid;
 		inode->i_gid = task->egid;
 	}
+#ifdef CONFIG_GRSECURITY
+	if (gr_proc_pid_make_inode(task, inode)) {
+		ei->task = NULL;
+		ei->type = 0;
+		put_task_struct(task);
+		goto out_unlock;
+	}
+#endif
 	security_task_to_inode(task, inode);
 
 out:
@@ -994,6 +1018,9 @@ static int pid_revalidate(struct dentry 
 			inode->i_uid = 0;
 			inode->i_gid = 0;
 		}
+#ifdef CONFIG_GRSECURITY
+		gr_proc_pid_revalidate(task, inode);
+#endif
 		security_task_to_inode(task, inode);
 		return 1;
 	}
@@ -1573,7 +1600,6 @@ struct dentry *proc_pid_lookup(struct in
 
 	inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
 
-
 	if (!inode) {
 		put_task_struct(task);
 		goto out;
@@ -1584,6 +1610,26 @@ struct dentry *proc_pid_lookup(struct in
 	inode->i_nlink = 3;
 	inode->i_flags|=S_IMMUTABLE;
 
+#ifdef CONFIG_GRSECURITY
+	/*
+	 * Allows us to hide a task or prevent users from viewing
+	 * other tasks, as well as modify inode.
+	 *
+	 * Remember to return 0 unless you're hiding this task!
+	 */
+	if (gr_proc_pid_lookup(task,inode)) {
+		struct proc_inode *ei;
+		ei = PROC_I(inode);
+		ei->task = NULL;
+		ei->type = 0;
+		ei->pde = NULL;
+		iput(inode);
+		inode = NULL;
+		put_task_struct(task);
+		goto out;
+	}
+#endif
+
 	dentry->d_op = &pid_base_dentry_operations;
 
 	died = 0;
@@ -1682,6 +1728,10 @@ static int get_tgid_list(int index, unsi
 		int tgid = p->pid;
 		if (!pid_alive(p))
 			continue;
+#ifdef CONFIG_GRSECURITY
+		if (gr_proc_get_tgid_list(p))
+			continue;
+#endif
 		if (--index >= 0)
 			continue;
 		tgids[nr_tgids] = tgid;
diff -urNp linux-2.6.10/fs/proc/generic.c linux-2.6.10-grs/fs/proc/generic.c
--- linux-2.6.10/fs/proc/generic.c	2004-12-24 16:35:40.000000000 -0500
+++ linux-2.6.10-grs/fs/proc/generic.c	2005-01-26 21:50:06.154068000 -0500
@@ -662,6 +662,26 @@ void free_proc_entry(struct proc_dir_ent
 }
 
 /*
+ * Find a proc entry
+ * Duplicated from remove_proc_entry()
+ */
+struct proc_dir_entry **get_proc_entry(const char *name, struct proc_dir_entry *parent) {
+	struct proc_dir_entry **p;
+	const char *fn = name;
+	int len;
+	if (!parent && xlate_proc_name(name, &parent, &fn) != 0)
+		goto out;
+	len = strlen(fn);
+	for (p = &parent->subdir; *p; p=&(*p)->next ) {
+		if (!proc_match(len, fn, *p))
+			continue;
+		return p;
+	}
+out:
+	return NULL;
+}
+
+/*
  * Remove a /proc entry and free it if it's not currently in use.
  * If it is in use, we set the 'deleted' flag.
  */
@@ -698,3 +718,7 @@ void remove_proc_entry(const char *name,
 out:
 	return;
 }
+
+EXPORT_SYMBOL(proc_mkdir_mode);
+EXPORT_SYMBOL(remove_proc_entry);
+EXPORT_SYMBOL(get_proc_entry);
diff -urNp linux-2.6.10/fs/proc/inode.c linux-2.6.10-grs/fs/proc/inode.c
--- linux-2.6.10/fs/proc/inode.c	2004-12-24 16:35:28.000000000 -0500
+++ linux-2.6.10-grs/fs/proc/inode.c	2005-01-26 16:31:31.652654000 -0500
@@ -16,6 +16,9 @@
 #include <linux/module.h>
 #include <linux/parser.h>
 #include <linux/smp_lock.h>
+#ifdef CONFIG_GRSECURITY
+# include <linux/grsecurity.h>
+#endif
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -222,6 +225,13 @@ struct inode *proc_get_inode(struct supe
 		if (de->proc_fops)
 			inode->i_fop = de->proc_fops;
 	}
+#ifdef CONFIG_GRSECURITY
+	/*
+	 * XXX
+	 *   Do we want to goto out_fail if not zero?
+	 */
+	gr_proc_get_inode(inode, de);
+#endif
 
 out:
 	return inode;
diff -urNp linux-2.6.10/fs/proc/proc_misc.c linux-2.6.10-grs/fs/proc/proc_misc.c
--- linux-2.6.10/fs/proc/proc_misc.c	2004-12-24 16:34:00.000000000 -0500
+++ linux-2.6.10-grs/fs/proc/proc_misc.c	2005-01-26 20:03:46.733690000 -0500
@@ -647,4 +647,11 @@ void __init proc_misc_init(void)
 			entry->proc_fops = &ppc_htab_operations;
 	}
 #endif
+#ifdef CONFIG_GRSECURITY
+	/*
+	 * The GrSecurity framework gets passed proc_root so it can try to
+	 * remove or alter some entries.
+	 */
+	//gr_proc_misc_init(&proc_root);
+#endif
 }
diff -urNp linux-2.6.10/fs/proc/task_mmu.c linux-2.6.10-grs/fs/proc/task_mmu.c
--- linux-2.6.10/fs/proc/task_mmu.c	2004-12-24 16:34:01.000000000 -0500
+++ linux-2.6.10-grs/fs/proc/task_mmu.c	2005-01-25 22:52:22.907070000 -0500
@@ -1,8 +1,12 @@
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/seq_file.h>
 #include <asm/elf.h>
 #include <asm/uaccess.h>
+#ifdef CONFIG_GRSECURITY
+# include <linux/grsecurity.h>
+#endif
 
 char *task_mem(struct mm_struct *mm, char *buffer)
 {
@@ -53,6 +57,7 @@ static int show_map(struct seq_file *m, 
 	unsigned long ino = 0;
 	dev_t dev = 0;
 	int len;
+	unsigned long vm_start, vm_end, pg_off, dev_mj, dev_mn;
 
 	if (file) {
 		struct inode *inode = map->vm_file->f_dentry->d_inode;
@@ -60,15 +65,41 @@ static int show_map(struct seq_file *m, 
 		ino = inode->i_ino;
 	}
 
+	vm_start = map->vm_start;
+	vm_end = map->vm_end;
+	pg_off = map->vm_pgoff << PAGE_SHIFT;
+	dev_mj = MAJOR(dev);
+	dev_mn = MINOR(dev);
+#ifdef CONFIG_GRSECURITY
+	{
+		int error;
+	/*
+	 * Same deal as do_task_stat() in array.c
+	 * We get a crack at nulling these things out.
+	 *
+	 * Getting non-null back means we return from here.
+	 *
+	 * Getting ENOMSG is a special case:  we return silently from here,
+	 * i.e. without an error but without doing anything, for ENOMSG.
+	 */
+		error = gr_proc_show_map(&vm_start, &vm_end, &pg_off,
+			&dev_mj, &dev_mn, &ino, m);
+		if (error) {
+			if (error == -ENOMSG)
+				return 0;
+			return error;
+		}
+	}
+#endif
 	seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
-			map->vm_start,
-			map->vm_end,
+			vm_start,
+			vm_end,
 			flags & VM_READ ? 'r' : '-',
 			flags & VM_WRITE ? 'w' : '-',
 			flags & VM_EXEC ? 'x' : '-',
 			flags & VM_MAYSHARE ? 's' : 'p',
-			map->vm_pgoff << PAGE_SHIFT,
-			MAJOR(dev), MINOR(dev), ino, &len);
+			pg_off,
+			(unsigned int)dev_mj, (unsigned int)dev_mn, ino, &len);
 
 	if (map->vm_file) {
 		len = 25 + sizeof(void*) * 6 - len;
diff -urNp linux-2.6.10/include/asm-generic/vmlinux.lds.h linux-2.6.10-grs/include/asm-generic/vmlinux.lds.h
--- linux-2.6.10/include/asm-generic/vmlinux.lds.h	2004-12-24 16:33:50.000000000 -0500
+++ linux-2.6.10-grs/include/asm-generic/vmlinux.lds.h	2005-01-25 18:47:17.662993000 -0500
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #ifndef LOAD_OFFSET
 #define LOAD_OFFSET 0
 #endif
@@ -79,6 +80,17 @@
 		VMLINUX_SYMBOL(__security_initcall_end) = .;		\
 	}
 
+#ifdef CONFIG_GRSECURITY
+#define GRSECURITY_INIT							\
+	.grsecurity_initcall.init : {					\
+		VMLINUX_SYMBOL(__grsecurity_initcall_start) = .;		\
+		*(.grsecurity_initcall.init) 				\
+		VMLINUX_SYMBOL(__grsecurity_initcall_end) = .;		\
+	}
+#else
+#define GRSECURITY_INIT
+#endif
+
 #define SCHED_TEXT							\
 		VMLINUX_SYMBOL(__sched_text_start) = .;			\
 		*(.sched.text)						\
diff -urNp linux-2.6.10/include/linux/grsecurity.h linux-2.6.10-grs/include/linux/grsecurity.h
--- linux-2.6.10/include/linux/grsecurity.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/include/linux/grsecurity.h	2005-01-26 16:25:10.400613000 -0500
@@ -0,0 +1,272 @@
+/*
+ * Linux GrSecurity plug
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ * Copyright (C) 2005 Brad Spengler
+ *
+ * Derived from security.h which is:
+ *  Copyright (C) 2001 WireX Communications, Inc <chrisat_private>
+ *  Copyright (C) 2001 Greg Kroah-Hartman <gregat_private>
+ *  Copyright (C) 2001 Networks Associates Technology, Inc <ssmalleyat_private>
+ *  Copyright (C) 2001 James Morris <jmorrisat_private>
+ *  Copyright (C) 2001 Silicon Graphics, Inc. (Trust Technology Group)
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	Due to this file being licensed under the GPL there is controversy over
+ *	whether this permits you to write a module that #includes this file
+ *	without placing your module under the GPL.  Please consult a lawyer for
+ *	advice before doing this.
+ *
+ */
+
+#ifndef __LINUX_GRSECURITY_H
+#define __LINUX_GRSECURITY_H
+
+#ifdef CONFIG_GRSECURITY
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/binfmts.h>
+#include <linux/signal.h>
+#include <linux/resource.h>
+#include <linux/sem.h>
+#include <linux/shm.h>
+#include <linux/msg.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+
+#define GRSECURITY_FRAMEWORK_VERSION	"2.0.0"
+
+struct grsecurity_operations;
+/* global variables */
+extern struct grsecurity_operations *grsecurity_ops;
+extern rwlock_t gr_ops_lock;
+
+int __init grsecurity_init(void);
+int register_grsecurity(struct grsecurity_operations *ops);
+int unregister_grsecurity(struct grsecurity_operations *ops);
+
+/**
+ * struct grsecurity_operations - main grsecurity structure
+ *
+ * --GrSecurity hooks for program execution operations--
+ *
+ * 
+ * --GrSecurity hooks for keyboard operations--
+ *
+ * @keyboard_handler:
+ * 	Check permissions for k_spec()
+ * 	@value contains the index of the function to call from k_spec()
+ *
+ * --GrSecurity hooks for /proc--
+ *
+ * @proc_permission:
+ * 	Permission check to access an inode in /proc
+ * 	@inode is the inode
+ * 	Return value of 0 allows this
+ * 	Return value of non-zero denies this access
+ * @proc_pid_make_inode:
+ * 	Handle creation in pid_make_inode().
+ * 	@task is the task
+ * 	@inode is the created inode
+ * 	Return value is ignored at the hooks, but a non-zero return value
+ * 	 tells the GrSecurity framework to STOP processing other modules.
+ * @proc_pid_revalidate:
+ * 	Handle revalidation in pid_revalidate().
+ * 	@task is the task
+ * 	@inode is the inode
+ * 	Return value of 0 tells the system to handle as normal.
+ * 	Return value of non-zero tells the GrSecurity framework to STOP
+ * 	 processing other modules, and prevents the normal inode->i_{uid,gid}
+ * 	 changes from being made.
+ * @proc_pid_lookup:
+ * 	Handle look-up of tasks in /proc, and allow hiding of the task and
+ * 	 altering of the inode in /proc.
+ * 	@task is the task to be validated.
+ * 	@inode is the inode that will appear in /proc
+ * 	Return value of 0 leaves the task visible.
+ * 	Return value of non-zero hides the task.
+ * @proc_get_tgid_list:
+ * 	Handle get_tgid_list() in fs/proc/base.c
+ * 	@task is the task that information is being requested for
+ * 	Return value of 0 allows this task to be processed
+ * 	Return value of non-zero hides information about this task
+ * @proc_get_inode:
+ * 	Handles getting an inode entry, allowing attributes of the inode
+ * 	to be changed.
+ * 	@inode is the inode
+ * 	@de is the directory entry
+ * 	Return value of 0 allows the inode (modified or not) to be visible
+ * 	Return value of non-zero does nothing; in the future, the inode will
+ * 	 be hidden.
+ * @proc_task_stat:
+ * 	Handle /proc task stat information, replacing anything you want to
+ * 	 obscure.  The hooks will prevent you from re-adding any information
+ * 	 another module set to NULL; but there should be enough information
+ * 	 in @task to regenerate that data, so rely on @task rather than the
+ * 	 other passed data.
+ * 	@eip is eip
+ * 	@esp is esp
+ *	@wchan is wchan
+ *	@start_code is start_code
+ *	@end_code is end_code
+ *	@start_stack is start_stack
+ *	@task is the task passed to do_task_stat()
+ *	Returns 0 whether or not any of the passed fields have been altered.
+ *	Returns an error to indicate that do_task_stat() should just return
+ *	 NULL without revealing information.
+ * @proc_show_map:
+ * 	Handle /proc/<pid>/maps file for map showing.  Again, use @m to get
+ * 	 at the data we pass pointers to; other modules may NULL these and
+ * 	 that will be protected even if your module de-NULLs them.
+ *	@vm_start is the vm_start
+ *	@vm_end is vm_end,
+ *	@vm_pgoff
+ *	@dev_mj is the major for the device of file-backed mappings
+ *	@dev_mn is the minor for the device of file-backed mappings
+ *	@ino is the inode for file-backed mappings
+ *	@m is the struct seq_file passed to show_map()
+ *	Returns 0 whether or not any of the passed fields have been altered
+ *	Returns an error to refuse the show_map()
+ *	Returns ENOMSG to skip showing anything, yet return from show_map()
+ *	 with no error.
+ * @proc_pci_legacy_init:
+ * 	Handle PCI legacy_proc_init()
+ * 	@entry is a pointer to a pointer to a proc_dir_entry structure.
+ * 	Returns 0 if nothing.
+ * 	Returns 1 and optionally fills entry if this module is handling or
+ * 	 forbidding the creation of a /proc entry
+ * @proc_pci_init:
+ * 	Handle PCI pci_proc_init()
+ * 	@proc_bus_pci_dir is a pointer to proc_bus_pci_dir in
+ * 	 drivers/pci/proc.c
+ * 	Returns 0 if nothing.
+ * 	Returns 1 and fills proc_bus_pci_dir if the module affects this.
+ *  
+ * --GrSecurity hooks for inode operations--
+ * 
+ * @inode_follow_link:
+ * 	Check permission to following a symlink.
+ *	@dentry contains the dentry structure for the link.
+ *	@nd contains the nameidata structure for the parent directory.
+ *	Return 0 if permission is granted.
+ * @inode_hardlink:
+ * 	Check permission to create a hardlink.
+ * 	@new_dentry contains the newly created dentry
+ * 	@old_nd contains the nameidata structure for the target of the hardlink
+ * 	@nd contains the nameidata structure for the parent
+ * 	@to contains the path to hardlink into
+ * 	Return 0 if permission is granted.
+ * @inode_handle_create:
+ * 	Handle the creation of a new inode, i.e. for ACL systems to track new
+ * 	 inodes.
+ * 	@new_dentry is the newly created dentry
+ * 	@mnt is the vfsmount for the nameidata for the parent
+ * 	No return value
+ */
+
+struct grsecurity_operations {
+	/*doubly linked list*/
+	struct grsecurity_operations
+				*next;
+	struct grsecurity_operations
+				*prev;
+	/*end back and forward pointers*/
+	/*KEYBOARD FUNCTIONS*/
+	int (*keyboard_handler) (const int value);
+	/*--PROC FUNCTIONS--*/
+	int (*proc_permission) (const struct inode *inode);
+	int (*proc_pid_make_inode) (const struct task_struct *task,
+			struct inode *inode);
+	int (*proc_pid_revalidate) (const struct task_struct *task,
+			struct inode *inode);
+	int (*proc_pid_lookup) (const struct task_struct *task,
+			struct inode *inode);
+	int (*proc_get_tgid_list) (const struct task_struct *task);
+	int (*proc_get_inode) (struct inode *inode,
+		const struct proc_dir_entry *de);
+	int (*proc_task_stat) (unsigned long *eip,
+		unsigned long *esp,
+		unsigned long *wchan,
+		unsigned long *start_code,
+		unsigned long *end_code,
+		unsigned long *start_stack,
+		struct task_struct *task);
+	int (*proc_show_map) (unsigned long *vm_start,
+		unsigned long *vm_end,
+		unsigned long *vm_pgoff,
+		unsigned long *dev_mj,
+		unsigned long *dev_mn,
+		unsigned long *ino,
+		struct seq_file *m);
+	int (*proc_pci_legacy_init) (const struct proc_dir_entry **entry);
+	int (*proc_pci_init) (struct proc_dir_entry **proc_bus_pci_dir);
+	/*--INODE FUNCTIONS--*/
+	int (*inode_follow_link) (const struct dentry *dentry,
+			const struct nameidata *nd);
+	int (*inode_hardlink) (const struct dentry *new_dentry,
+			const struct nameidata *old_nd,
+			const struct nameidata *nd,
+			const char *to);
+	void (*inode_handle_create) (const struct dentry *new_dentry,
+			const struct vfsmount *mnt);
+
+};
+
+int gr_keyboard_handler(const int value);
+
+int gr_proc_permission(const struct inode *inode);
+
+int gr_proc_pid_make_inode(const struct task_struct *task,
+		struct inode *inode);
+
+int gr_proc_pid_revalidate(const struct task_struct *task,
+		struct inode *inode);
+
+int gr_proc_pid_lookup(const struct task_struct *task,
+		struct inode *inode);
+
+int gr_proc_get_tgid_list(const struct task_struct *task);
+
+int gr_proc_get_inode(struct inode *inode,
+		const struct proc_dir_entry *de);
+
+int gr_proc_task_stat(unsigned long *eip,
+		unsigned long *esp,
+		unsigned long *wchan,
+		unsigned long *start_code,
+		unsigned long *end_code,
+		unsigned long *start_stack,
+		struct task_struct *task);
+
+int gr_proc_show_map (unsigned long *vm_start,
+		unsigned long *vm_end,
+		unsigned long *vm_pgoff,
+		unsigned long *dev_mj,
+		unsigned long *dev_mn,
+		unsigned long *ino,
+		struct seq_file *m);
+
+int gr_proc_pci_legacy_init(const struct proc_dir_entry **entry);
+
+int gr_proc_pci_init(struct proc_dir_entry **proc_bus_pci_dir);
+
+int gr_inode_follow_link(const struct dentry *dentry,
+		const struct nameidata *nd);
+
+int gr_inode_hardlink (const struct dentry *new_dentry,
+			const struct nameidata *old_nd,
+			const struct nameidata *nd,
+			const char *to);
+
+void gr_inode_handle_create (const struct dentry *new_dentry,
+			const struct vfsmount *mnt);
+
+#endif /* CONFIG_GRSECURITY */
+
+#endif /* ! __LINUX_GRSECURITY_H */
+
diff -urNp linux-2.6.10/include/linux/init.h linux-2.6.10-grs/include/linux/init.h
--- linux-2.6.10/include/linux/init.h	2004-12-24 16:33:50.000000000 -0500
+++ linux-2.6.10-grs/include/linux/init.h	2005-01-25 18:47:17.663993000 -0500
@@ -66,6 +66,9 @@ typedef void (*exitcall_t)(void);
 
 extern initcall_t __con_initcall_start, __con_initcall_end;
 extern initcall_t __security_initcall_start, __security_initcall_end;
+#ifdef CONFIG_GRSECURITY
+extern initcall_t __grsecurity_initcall_start, __grsecurity_initcall_end;
+#endif
 
 /* Defined in init/main.c */
 extern char saved_command_line[];
@@ -107,6 +110,11 @@ extern char saved_command_line[];
 	static initcall_t __initcall_##fn \
 	__attribute_used__ __attribute__((__section__(".security_initcall.init"))) = fn
 
+#ifdef CONFIG_GRSECURITY
+#define grsecurity_initcall(fn) \
+	static initcall_t __grinitcall_##fn \
+	__attribute_used__ __attribute__((__section__(".grsecurity_initcall.init"))) = fn
+#endif
 struct obs_kernel_param {
 	const char *str;
 	int (*setup_func)(char *);
@@ -179,6 +187,9 @@ void __init parse_early_param(void);
 #define late_initcall(fn)		module_init(fn)
 
 #define security_initcall(fn)		module_init(fn)
+#ifdef CONFIG_GRSECURITY
+#define grsecurity_initcall(fn)		module_init(fn)
+#endif
 
 /* These macros create a dummy inline: gcc 2.9x does not count alias
  as usage, hence the `unused function' warning when __init functions
diff -urNp linux-2.6.10/include/linux/keyboard.h linux-2.6.10-grs/include/linux/keyboard.h
--- linux-2.6.10/include/linux/keyboard.h	2004-12-24 16:34:00.000000000 -0500
+++ linux-2.6.10-grs/include/linux/keyboard.h	2005-01-25 20:44:41.020286000 -0500
@@ -3,6 +3,13 @@
 
 #include <linux/wait.h>
 
+#define _KBD_FN_HANDLERS\
+	fn_null, 	fn_enter,	fn_show_ptregs,	fn_show_mem,\
+	fn_show_state,	fn_send_intr, 	fn_lastcons, 	fn_caps_toggle,\
+	fn_num,		fn_hold, 	fn_scroll_forw,	fn_scroll_back,\
+	fn_boot_it, 	fn_caps_on, 	fn_compose,	fn_SAK,\
+	fn_dec_console, fn_inc_console, fn_spawn_con, 	fn_bare_num
+
 #define KG_SHIFT	0
 #define KG_CTRL		2
 #define KG_ALT		3
diff -urNp linux-2.6.10/include/linux/proc_fs.h linux-2.6.10-grs/include/linux/proc_fs.h
--- linux-2.6.10/include/linux/proc_fs.h	2004-12-24 16:35:50.000000000 -0500
+++ linux-2.6.10-grs/include/linux/proc_fs.h	2005-01-26 21:23:44.367536000 -0500
@@ -100,6 +100,7 @@ char *task_mem(struct mm_struct *, char 
 extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
 						struct proc_dir_entry *parent);
 extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
+extern struct proc_dir_entry **get_proc_entry(const char *name, struct proc_dir_entry *parent);
 
 extern struct vfsmount *proc_mnt;
 extern int proc_fill_super(struct super_block *,void *,int);
diff -urNp linux-2.6.10/init/main.c linux-2.6.10-grs/init/main.c
--- linux-2.6.10/init/main.c	2004-12-24 16:34:01.000000000 -0500
+++ linux-2.6.10-grs/init/main.c	2005-01-25 20:55:10.851537000 -0500
@@ -34,6 +34,9 @@
 #include <linux/kmod.h>
 #include <linux/kernel_stat.h>
 #include <linux/security.h>
+#ifdef CONFIG_GRSECURITY
+# include <linux/grsecurity.h>
+#endif
 #include <linux/workqueue.h>
 #include <linux/profile.h>
 #include <linux/rcupdate.h>
@@ -565,6 +568,9 @@ asmlinkage void __init start_kernel(void
 	buffer_init();
 	unnamed_dev_init();
 	security_init();
+#ifdef CONFIG_GRSECURITY
+	grsecurity_init();
+#endif
 	vfs_caches_init(num_physpages);
 	radix_tree_init();
 	signals_init();
diff -urNp linux-2.6.10/security/grsecurity/dummy/gr_dummy1.c linux-2.6.10-grs/security/grsecurity/dummy/gr_dummy1.c
--- linux-2.6.10/security/grsecurity/dummy/gr_dummy1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/dummy/gr_dummy1.c	2005-01-26 22:18:32.222836000 -0500
@@ -0,0 +1,66 @@
+/*
+ * These are dummy modules.
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ *
+ *   LICENSE:  GPLv2
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/grsecurity.h>
+
+#define DUMMY_NAME "GR_DUMMY_MODULE_1"
+
+
+static int dummy_proc_show_map (unsigned long *vm_start,
+		unsigned long *vm_end,
+		unsigned long *vm_pgoff,
+		unsigned long *dev_mj,
+		unsigned long *dev_mn,
+		unsigned long *ino,
+		struct seq_file *m) {
+	printk(KERN_INFO "***GrSecurity stacking test in " DUMMY_NAME "***\n");
+	return 0;
+}
+
+static 
+struct grsecurity_operations sec_ops = {
+	.proc_show_map =		dummy_proc_show_map,
+};
+
+static int __init
+dummy_m_init(void)
+{
+        /* register ourselves with the security framework */
+	if (register_grsecurity (&sec_ops)) {
+		printk (KERN_INFO
+			"    Failure registering " DUMMY_NAME
+			" module with the kernel\n");
+		return -EINVAL;
+	}
+
+	printk (KERN_INFO "    " DUMMY_NAME " module initialized.\n");
+	
+	return 0;
+}
+
+static void __exit
+dummy_m_exit(void)
+{
+	/* remove ourselves from the security framework */
+	if (unregister_grsecurity (&sec_ops)) {
+		printk (KERN_INFO "Failure unregistering " DUMMY_NAME
+				" module with the kernel\n");
+	}
+	
+	printk (KERN_INFO DUMMY_NAME " Plug module removed\n");
+}
+
+grsecurity_initcall(dummy_m_init);
+module_exit(dummy_m_exit);
+
+MODULE_AUTHOR("John Moser");
+MODULE_DESCRIPTION(DUMMY_NAME " module");
+MODULE_LICENSE("GPL");
diff -urNp linux-2.6.10/security/grsecurity/dummy/gr_dummy2.c linux-2.6.10-grs/security/grsecurity/dummy/gr_dummy2.c
--- linux-2.6.10/security/grsecurity/dummy/gr_dummy2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/dummy/gr_dummy2.c	2005-01-26 22:18:42.047343000 -0500
@@ -0,0 +1,66 @@
+/*
+ * These are dummy modules.
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ *
+ *   LICENSE:  GPLv2
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/grsecurity.h>
+
+#define DUMMY_NAME "GR_DUMMY_MODULE_2"
+
+
+static int dummy_proc_show_map (unsigned long *vm_start,
+		unsigned long *vm_end,
+		unsigned long *vm_pgoff,
+		unsigned long *dev_mj,
+		unsigned long *dev_mn,
+		unsigned long *ino,
+		struct seq_file *m) {
+	printk(KERN_INFO "***GrSecurity stacking test in " DUMMY_NAME "***\n");
+	return 0;
+}
+
+static 
+struct grsecurity_operations sec_ops = {
+	.proc_show_map =		dummy_proc_show_map,
+};
+
+static int __init
+dummy_m_init(void)
+{
+        /* register ourselves with the security framework */
+	if (register_grsecurity (&sec_ops)) {
+		printk (KERN_INFO
+			"    Failure registering " DUMMY_NAME
+			" module with the kernel\n");
+		return -EINVAL;
+	}
+
+	printk (KERN_INFO "    " DUMMY_NAME " module initialized.\n");
+	
+	return 0;
+}
+
+static void __exit
+dummy_m_exit(void)
+{
+	/* remove ourselves from the security framework */
+	if (unregister_grsecurity (&sec_ops)) {
+		printk (KERN_INFO "Failure unregistering " DUMMY_NAME
+				" module with the kernel\n");
+	}
+	
+	printk (KERN_INFO DUMMY_NAME " Plug module removed\n");
+}
+
+grsecurity_initcall(dummy_m_init);
+module_exit(dummy_m_exit);
+
+MODULE_AUTHOR("John Moser");
+MODULE_DESCRIPTION(DUMMY_NAME " module");
+MODULE_LICENSE("GPL");
diff -urNp linux-2.6.10/security/grsecurity/dummy/gr_dummy3.c linux-2.6.10-grs/security/grsecurity/dummy/gr_dummy3.c
--- linux-2.6.10/security/grsecurity/dummy/gr_dummy3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/dummy/gr_dummy3.c	2005-01-26 22:18:53.915538000 -0500
@@ -0,0 +1,66 @@
+/*
+ * These are dummy modules.
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ *
+ *   LICENSE:  GPLv2
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/grsecurity.h>
+
+#define DUMMY_NAME "GR_DUMMY_MODULE_3"
+
+
+static int dummy_proc_show_map (unsigned long *vm_start,
+		unsigned long *vm_end,
+		unsigned long *vm_pgoff,
+		unsigned long *dev_mj,
+		unsigned long *dev_mn,
+		unsigned long *ino,
+		struct seq_file *m) {
+	printk(KERN_INFO "***GrSecurity stacking test in " DUMMY_NAME "***\n");
+	return 0;
+}
+
+static 
+struct grsecurity_operations sec_ops = {
+	.proc_show_map =		dummy_proc_show_map,
+};
+
+static int __init
+dummy_m_init(void)
+{
+        /* register ourselves with the security framework */
+	if (register_grsecurity (&sec_ops)) {
+		printk (KERN_INFO
+			"    Failure registering " DUMMY_NAME
+			" module with the kernel\n");
+		return -EINVAL;
+	}
+
+	printk (KERN_INFO "    " DUMMY_NAME " module initialized.\n");
+	
+	return 0;
+}
+
+static void __exit
+dummy_m_exit(void)
+{
+	/* remove ourselves from the security framework */
+	if (unregister_grsecurity (&sec_ops)) {
+		printk (KERN_INFO "Failure unregistering " DUMMY_NAME
+				" module with the kernel\n");
+	}
+	
+	printk (KERN_INFO DUMMY_NAME " Plug module removed\n");
+}
+
+grsecurity_initcall(dummy_m_init);
+module_exit(dummy_m_exit);
+
+MODULE_AUTHOR("John Moser");
+MODULE_DESCRIPTION(DUMMY_NAME " module");
+MODULE_LICENSE("GPL");
diff -urNp linux-2.6.10/security/grsecurity/dummy/Kconfig linux-2.6.10-grs/security/grsecurity/dummy/Kconfig
--- linux-2.6.10/security/grsecurity/dummy/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/dummy/Kconfig	2005-01-26 22:15:42.878580000 -0500
@@ -0,0 +1,16 @@
+#
+# GrSecurity Dummy Module stuff
+#
+
+config GRSECURITY_DUMMY_TESTS
+	tristate "Enable Dummy Test Modules"
+	depends on GRSECURITY
+	help
+	  This option causes three test modules to be built, or built in,
+	  to test stacking.  This is only for testing. These modules are
+	  called gr_dummy1, gr_dummy2, and gr_dummy3.
+
+	  When loaded, the dummy modules printk() at each mapping output,
+	  so they can be tested by catting /proc/self/maps and checking
+	  dmesg.  This can produce a lot of output, so use these only for
+	  testing and debugging.
diff -urNp linux-2.6.10/security/grsecurity/dummy/Makefile linux-2.6.10-grs/security/grsecurity/dummy/Makefile
--- linux-2.6.10/security/grsecurity/dummy/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/dummy/Makefile	2005-01-26 22:16:19.672987000 -0500
@@ -0,0 +1,9 @@
+#
+# Makefile for the grsecurity dummy tests
+#
+
+
+
+obj-$(CONFIG_GRSECURITY_DUMMY_TESTS)		= gr_dummy1.o gr_dummy2.o gr_dummy3.o
+
+
diff -urNp linux-2.6.10/security/grsecurity/grfunctions.c linux-2.6.10-grs/security/grsecurity/grfunctions.c
--- linux-2.6.10/security/grsecurity/grfunctions.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/grfunctions.c	2005-01-26 21:02:18.609457000 -0500
@@ -0,0 +1,302 @@
+/*
+ * GrSecurity Plug functions
+ *
+ * Derived from GrSecurity and mimicing the LSM code
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ * Copyright (C) 2001-2005 Brad Spengler
+ *
+ * Derived partially from security.c which is:
+ *  Copyright (C) 2001 WireX Communications, Inc <chrisat_private>
+ *  Copyright (C) 2001-2002 Greg Kroah-Hartman <gregat_private>
+ *  Copyright (C) 2001 Networks Associates Technology, Inc <ssmalleyat_private>
+ * 
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ */
+
+/*
+ * GrSecurity modules self-stack in the following way:
+ *
+ *   error = 0;
+ *   for (i = grsecurity_ops; i; i = i->next) {
+ *   	error = i->requested_operation(data);
+ *   	if (error)
+ *   		break;
+ *   }
+ *   return error;
+ *
+ * So we need no dummy module or anything.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <linux/grsecurity.h>
+
+/*
+ * if grsecurity_ops is null, this will simply fall through
+ * with no error.  Otherwise it'll check each registered module
+ * and return an error if one denies access.
+ *
+ * This occurs in a gr_ops_lock read_lock()
+ *
+ * We need C99 variadic macros to do this
+ */
+#define _GRSECURITY_CHECK(function,...) \
+do {\
+	struct grsecurity_operations *ops; \
+	int e = 0; \
+	read_lock(&gr_ops_lock); \
+	for (ops = grsecurity_ops; ops; ops = ops->next) { \
+		if (ops->function) \
+			e = ops->function ( __VA_ARGS__ ) ; \
+		if (e) \
+			break; \
+	} \
+	read_unlock(&gr_ops_lock); \
+	return e; \
+} while(0)
+
+/*
+ * if grsecurity_ops is null, this will simply fall through
+ * with no error.  Otherwise it'll check each registered module
+ * and try to do what's there for this.
+ *
+ * This occurs in a gr_ops_lock read_lock()
+ *
+ * We need C99 variadic macros to do this
+ */
+#define _GRSECURITY_DO(function,...) \
+do {\
+	struct grsecurity_operations *ops; \
+	read_lock(&gr_ops_lock); \
+	for (ops = grsecurity_ops; ops; ops = ops->next) { \
+		if ( ops->function ) \
+			ops->function ( __VA_ARGS__ ) ; \
+	} \
+	read_unlock(&gr_ops_lock); \
+} while(0)
+
+/*
+ * --KEYBOARD_FUNCTIONS--
+ */
+int gr_keyboard_handler(const int value) {
+	_GRSECURITY_CHECK(keyboard_handler,
+			value);
+}
+EXPORT_SYMBOL_GPL(gr_keyboard_handler);
+
+/*
+ * --PROC FUNCTIONS--
+ */
+int gr_proc_permission(const struct inode *inode) {
+	_GRSECURITY_CHECK(proc_permission,
+			inode);
+}
+EXPORT_SYMBOL_GPL(gr_proc_permission);
+
+int gr_proc_pid_make_inode(const struct task_struct *task,
+		struct inode *inode) {
+	_GRSECURITY_CHECK(proc_pid_make_inode,
+			task, inode);
+}
+EXPORT_SYMBOL_GPL(gr_proc_pid_make_inode);
+
+int gr_proc_pid_revalidate(const struct task_struct *task,
+		struct inode *inode) {
+	_GRSECURITY_CHECK(proc_pid_revalidate,
+			task, inode);
+}
+EXPORT_SYMBOL_GPL(gr_proc_pid_revalidate);
+
+int gr_proc_pid_lookup(const struct task_struct *task,
+		struct inode *inode) {
+	_GRSECURITY_CHECK(proc_pid_lookup,
+			task, inode);
+}
+EXPORT_SYMBOL_GPL(gr_proc_pid_lookup);
+
+int gr_proc_get_tgid_list(const struct task_struct *task) {
+	_GRSECURITY_CHECK(proc_get_tgid_list,
+			task);
+}
+EXPORT_SYMBOL_GPL(gr_proc_get_tgid_list);
+
+int gr_proc_get_inode(struct inode *inode,
+		const struct proc_dir_entry *de) {
+	_GRSECURITY_CHECK(proc_get_inode,
+			inode, de);
+}
+EXPORT_SYMBOL_GPL(gr_proc_get_inode);
+
+/*
+ * These next two are implemented special so that they don't allow a module to
+ * de-NULL variables and reveal information hidden by other modules.
+ */
+int gr_proc_task_stat(unsigned long *eip,
+		unsigned long *esp,
+		unsigned long *wchan,
+		unsigned long *start_code,
+		unsigned long *end_code,
+		unsigned long *start_stack,
+		struct task_struct *task) {
+	unsigned long my_eip, my_esp, my_wchan,
+		my_start_code, my_end_code, my_start_stack;
+	struct grsecurity_operations *ops;
+	int e = 0;
+	read_lock(&gr_ops_lock);
+	for (ops = grsecurity_ops; ops; ops = ops->next) {
+		if (ops->proc_task_stat) {
+			/*
+			 * Here's how we deter revealing of stomped
+			 * information.
+			 *
+			 * Normally, a module should assume passed vars to
+			 * contain valid data, and not touch them unless it
+			 * wants to obscure the data.
+			 *
+			 * There's enough information to add the data back
+			 * once another module obscures it.  To prevent this,
+			 * all values are stored before calling the module's
+			 * code.  Afterwards, anything null is transfered
+			 * back.
+			 */
+			my_eip = *eip;
+			my_esp = *esp;
+			my_wchan = *wchan;
+			my_start_code = *start_code;
+			my_end_code = *end_code;
+			my_start_stack = *start_stack;
+			/*here's the actual call*/
+			e = ops->proc_task_stat(eip, esp, wchan,
+				start_code, end_code, start_stack, task);
+			/*
+			 * And here's where we recheck and re-clear anything
+			 * that was put back after another module clears it
+			 */
+			*eip         = my_eip         ? *eip         : 0;
+			*esp         = my_esp         ? *esp         : 0;
+			*wchan       = my_wchan       ? *wchan       : 0;
+			*start_code  = my_start_code  ? *start_code  : 0;
+			*end_code    = my_end_code    ? *end_code    : 0;
+			*start_stack = my_start_stack ? *start_stack : 0;
+			/*and if it returned an error, we break*/
+			if (e)
+				break;
+		}
+	}
+	read_unlock(&gr_ops_lock);
+	return e;
+}
+EXPORT_SYMBOL_GPL(gr_proc_task_stat);
+
+int gr_proc_show_map (unsigned long *vm_start,
+		unsigned long *vm_end,
+		unsigned long *vm_pgoff,
+		unsigned long *dev_mj,
+		unsigned long *dev_mn,
+		unsigned long *ino,
+		struct seq_file *m) {
+	unsigned long my_vm_start, my_vm_end, my_vm_pgoff,
+		my_dev_mj, my_dev_mn, my_ino;
+	struct grsecurity_operations *ops;
+	int e = 0;
+	read_lock(&gr_ops_lock);
+	for (ops = grsecurity_ops; ops; ops = ops->next) {
+		if (ops->proc_show_map) {
+			/*
+			 * Info replacement tracking again
+			 */
+			my_vm_start = *vm_start;
+			my_vm_end = *vm_end;
+			my_vm_pgoff = *vm_pgoff;
+			my_dev_mj = *dev_mj;
+			my_dev_mn = *dev_mn;
+			my_ino = *ino;
+			/*here's the actual call*/
+			e = ops->proc_show_map(vm_start, vm_end, vm_pgoff,
+				dev_mj, dev_mn, ino, m);
+			/*
+			 * And here's where we recheck and re-clear anything
+			 * that was put back after another module clears it
+			 */
+			*vm_start    = my_vm_start    ? *vm_start    : 0;
+			*vm_end      = my_vm_end      ? *vm_end      : 0;
+			*vm_pgoff    = my_vm_pgoff    ? *vm_pgoff    : 0;
+			*dev_mj      = my_dev_mj      ? *dev_mj      : 0;
+			*dev_mn      = my_dev_mn      ? *dev_mn      : 0;
+			*ino         = my_ino         ? *ino         : 0;
+			/*and if it returned an error, we break*/
+			if (e)
+				break;
+		}
+	}
+	read_unlock(&gr_ops_lock);
+	return e;
+}
+EXPORT_SYMBOL_GPL(gr_proc_show_map);
+
+int gr_proc_pci_legacy_init(const struct proc_dir_entry **entry) {
+	_GRSECURITY_CHECK(proc_pci_legacy_init,
+			entry);
+}
+EXPORT_SYMBOL_GPL(gr_proc_pci_legacy_init);
+
+int gr_proc_pci_init(struct proc_dir_entry **proc_bus_pci_dir) {
+	_GRSECURITY_CHECK(proc_pci_init,
+			proc_bus_pci_dir);
+}
+EXPORT_SYMBOL_GPL(gr_proc_pci_init);
+
+/*
+ * --INODE FUNCTIONS--
+ */
+int gr_inode_follow_link(const struct dentry *dentry,
+		const struct nameidata *nd) {
+	_GRSECURITY_CHECK(inode_follow_link,
+			dentry, nd);
+}
+EXPORT_SYMBOL_GPL(gr_inode_follow_link);
+
+int gr_inode_hardlink (const struct dentry *new_dentry,
+			const struct nameidata *old_nd,
+			const struct nameidata *nd,
+			const char *to) {
+	_GRSECURITY_CHECK(inode_hardlink,
+			new_dentry, old_nd, nd, to);
+}
+EXPORT_SYMBOL_GPL(gr_inode_hardlink);
+
+void gr_inode_handle_create (const struct dentry *new_dentry,
+			const struct vfsmount *mnt) {
+	_GRSECURITY_DO(inode_handle_create,
+			new_dentry, mnt);
+}
+EXPORT_SYMBOL_GPL(gr_inode_handle_create);
+
+
+
+
+/**
+ * capable - calls the currently loaded security modules' capable() functions
+ *  with the specified capability
+ * @cap: the requested capability level.
+ *
+ * This function calls the currently loaded security modules' capable()
+ * functions with a pointer to the current task and the specified @cap value.
+ *
+ * This allows the security module to implement the capable function call
+ * however it chooses to.
+ */
+#if 0
+int capable(int cap)
+{
+	gr_capable(current, cap);
+}
+EXPORT_SYMBOL(capable);
+#endif
diff -urNp linux-2.6.10/security/grsecurity/grsecurity.c linux-2.6.10-grs/security/grsecurity/grsecurity.c
--- linux-2.6.10/security/grsecurity/grsecurity.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/grsecurity.c	2005-01-26 23:26:06.672660000 -0500
@@ -0,0 +1,184 @@
+/*
+ * GrSecurity plug functions
+ *
+ * Derived from GrSecurity and mimicing the LSM code
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ * Copyright (C) 2001-2005 Brad Spengler
+ *
+ * Derived partially from security.c which is:
+ *  Copyright (C) 2001 WireX Communications, Inc <chrisat_private>
+ *  Copyright (C) 2001-2002 Greg Kroah-Hartman <gregat_private>
+ *  Copyright (C) 2001 Networks Associates Technology, Inc <ssmalleyat_private>
+ * 
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ */
+
+/*
+ * GrSecurity modules self-stack in the following way:
+ *
+ *   error = 0;
+ *   for (i = grsecurity_ops; i; i = i->next) {
+ *   	error = i->requested_operation(data);
+ *   	if (error)
+ *   		break;
+ *   }
+ *   return error;
+ *
+ * So we need no dummy module or anything.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <linux/grsecurity.h>
+
+#define GRSECURITY_FRAMEWORK_VERSION	"2.0.0"
+
+struct grsecurity_operations *grsecurity_ops = NULL;	/* Initialized to NULL */
+/*
+ * Somewhat finegrained locking
+ *
+ * We use a read_lock() when we're executing a check, and a write_lock() when
+ * we're registering/unregistering a module.  Because registering and
+ * unregistering should be rare in production, we should usually just be in a
+ * read_lock(), which is non-blocking without a pending write_lock().
+ */
+rwlock_t gr_ops_lock = RW_LOCK_UNLOCKED;
+
+static inline int verify(struct grsecurity_operations *ops)
+{
+	/* verify the grsecurity_operations structure exists */
+	if (!ops)
+		return -EINVAL;
+	return 0;
+}
+
+/*
+ * This uses whatever is put into the __grsecurity_initcall section of vmlinuz
+ * to initialize any security modules supplying grsecurity_initcall(init_fcn)
+ * symbols.
+ */
+static void __init do_grsecurity_initcalls(void)
+{
+	initcall_t *call;
+	unsigned int i=0;
+	printk(KERN_INFO "  GrSecurity Frameworki" // v" GRSECURITY_FRAMEWORK_VERSION
+	       " initializing built-in modules...\n");
+	call = &__grsecurity_initcall_start;
+	while (call < &__grsecurity_initcall_end) {
+		(*call) ();
+		call++;
+		i++;
+	}
+	printk(KERN_INFO "  GrSecurity Framework" // v" GRSECURITY_FRAMEWORK_VERSION
+	       " initialized %u modules\n",i);
+}
+
+/**
+ * grsecurity_init - initializes the grsecurity framework
+ *
+ * This should be called early in the kernel initialization sequence.
+ */
+int __init grsecurity_init(void)
+{
+	
+	printk(KERN_INFO "GrSecurity Framework v" GRSECURITY_FRAMEWORK_VERSION
+	       " initialized\n");
+	do_grsecurity_initcalls();
+
+	return 0;
+}
+
+/**
+ * register_security - registers a grsecurity framework with the kernel
+ * @ops: a pointer to the struct grsecurity_options that is to be registered
+ *
+ * This function is to allow a grsecurity module to register itself with the
+ * kernel grsecurity subsystem.  Some rudimentary checking is done on the @ops
+ * value passed to this function.  A call to unregister_grsecurity() should be
+ * done to remove this grsecurity_options structure from the kernel.
+ */
+int register_grsecurity(struct grsecurity_operations *ops)
+{
+	if (verify(ops)) {
+		printk(KERN_DEBUG "%s could not verify "
+		       "grsecurity_operations structure.\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/*lock and load*/
+	write_lock(&gr_ops_lock);
+	/*The easy way:  Load at the top*/
+	if (grsecurity_ops) {
+		ops->next = grsecurity_ops;
+		ops->next->prev = ops;
+	}
+	ops->prev = NULL;
+	grsecurity_ops = ops;
+	write_unlock(&gr_ops_lock);
+
+	return 0;
+}
+
+/**
+ * unregister_grsecurity - unregisters a grsecurity framework with the kernel
+ * @ops: a pointer to the struct security_options that is to be registered
+ *
+ * This function removes a struct security_operations variable that had
+ * previously been registered with a successful call to register_security().
+ *
+ * If @ops does not match the valued previously passed to register_security()
+ * an error is returned.  Otherwise the default security options is set to the
+ * the dummy_security_ops structure, and 0 is returned.
+ */
+int unregister_grsecurity(struct grsecurity_operations *ops)
+{
+	struct grsecurity_operations *i = NULL;
+	if (!ops)
+		goto err;
+	printk(KERN_INFO "Unregistering a GR module...\n");
+	/*lock and unload*/
+	write_lock(&gr_ops_lock);
+	/*locate and destroy*/
+	for (i = grsecurity_ops; i; i = i->next) {
+		/*skip if this isn't ops*/
+		if (i != ops)
+			continue;
+		/*first, pinch*/
+		if (i->next)
+			i->next->prev  = i->prev;
+		if (i->prev)
+			i->prev->next  = i->next;
+		/*If this is the first module, it has to fix the head*/
+		if (i == grsecurity_ops)
+			grsecurity_ops = i->next;
+		/*now, leave, with non-NULL i*/
+		break;
+	}
+	write_unlock(&gr_ops_lock);
+	/*
+	 * if the above finished (or ops was null), we have a NULL i.  This
+	 *  means we failed to find the ops structure, so we give an error.
+	 */
+err:
+	if (!i) {
+		printk(KERN_INFO "%s: trying to unregister "
+		       "a grsecurity_opts structure that is not "
+		       "registered, failing.\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+EXPORT_SYMBOL_GPL(register_grsecurity);
+EXPORT_SYMBOL_GPL(unregister_grsecurity);
+//EXPORT_SYMBOL_GPL(grsecurity_ops);
+
diff -urNp linux-2.6.10/security/grsecurity/Kconfig linux-2.6.10-grs/security/grsecurity/Kconfig
--- linux-2.6.10/security/grsecurity/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/Kconfig	2005-01-26 22:16:38.793080000 -0500
@@ -0,0 +1,13 @@
+config GRSECURITY
+	bool "Enable GrSecurity derived hooks"
+	help
+	  This option enables a security framework derived from
+	  the GrSecurity project.  The framework is enough to
+	  implement GrSecurity.
+
+	  This framework uses reduced APIs to use less stack space.
+
+source security/grsecurity/dummy/Kconfig
+
+source security/grsecurity/kernsec/Kconfig
+
diff -urNp linux-2.6.10/security/grsecurity/kernsec/Kconfig linux-2.6.10-grs/security/grsecurity/kernsec/Kconfig
--- linux-2.6.10/security/grsecurity/kernsec/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/kernsec/Kconfig	2005-01-26 20:38:33.676426000 -0500
@@ -0,0 +1,120 @@
+#
+# GrSecurity KERNSEC stuff
+#
+
+menu "Kernel Security"
+	depends on GRSECURITY
+
+config GRSECURITY_KERNSEC
+	tristate "Enable GrSecurity derived kernel security"
+	depends on GRSECURITY
+	help
+	  This allows you to enable code taken from GrSecurity to
+	  enhance the security of the system.
+
+	  Careful testing is recommended in a production environment;
+	  but if nothing breaks, you should say Y to everything here.
+
+config GRKERNSEC_PROC
+	bool "/proc Restrictions"
+	depends on GRSECURITY_KERNSEC && PROC_FS
+	help
+	  Setting this allows you to select restrictions on the /proc
+	  filesystem to prevent information leaking.  It also controls
+	  the keyboard driver to prevent information leaking from
+	  magic sysrq keys.
+
+config GRKERNSEC_PROC_USER
+	bool "Restrict /proc to user"
+	depends on GRKERNSEC_PROC
+	help
+	  If you say Y here, users will only be able to view their own
+	  processes, except for root with CAP_SYS_ADMIN.  Users will also
+	  be restricted from viewing viewing network-related information,
+	  except for root with the CAP_NET_ADMIN capability.  Kernel
+	  symbol and module information is restricted to root with
+	  CAP_SYS_MODULE.
+
+config GRKERNSEC_PROC_GROUP_ACCESS
+	bool "Give group access to /proc"
+	depends on GRKERNSEC_PROC_USER
+	help
+	  This relaxes some /proc restrictions to allow a group to access
+	  the restricted /proc information--without any special caps.
+	  The group is set below.
+
+config GRKERNSEC_PROC_GID
+	int "Group"
+	depends on GRKERNSEC_PROC_GROUP_ACCESS
+	default 1000
+	help
+	  This is the group for GRKERNSEC_PROC_GROUP_ACCESS.
+
+config GRKERNSEC_PROC_GROUP_ACCESS_CAPS
+	bool "Require caps for /proc group access"
+	depends on GRKERNSEC_PROC_GROUP_ACCESS
+	help
+	  Saying Y here will cause /proc access for GRKERNSEC_PROC_GROUP
+	  to still require caps.  This means that the process must start
+	  as root and move to another user in the /proc group to have
+	  access.
+
+config GRKERNSEC_PROC_MEMMAP
+	bool "Remove addresses from /proc/<pid>/[maps|stat]"
+	depends on GRKERNSEC_PROC
+	help
+	  If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat
+	  files will give no information about the addresses of the
+	  mappings for a task, except to users with UID 0 and
+	  CAP_SYS_PTRACE.  This is useful for systems which deploy ASLR,
+	  such as that supplied by PaX, as it closes up an information
+	  leak to local attackers.
+
+	  Certain debugging systems may rely on this information, most
+	  notably those which report errors in Java JREs.  An option
+	  should be added with your ASLR system to disable the
+	  randomizations per-binary, and to disable this obscurity
+	  function for non-randomized tasks.
+
+config GRKERNSEC_LINK_RESTR
+	bool "Linking Restrictions"
+	depends on GRSECURITY_KERNSEC
+	help
+	  Setting this allows you to enable symlink and hardlink
+	  policy restrictions which can prevent race conditions in
+	  world-writable +t directories.
+
+config GRKERNSEC_SYMLINK_RESTR
+	bool "Symlink Restrictions"
+	depends on GRKERNSEC_LINK_RESTR
+	help
+	  This option adds a failure (EACCES) to dereference a
+	  symlink at the intersection of the following conditions:
+
+	   - The symlink is owned by a different user than the
+	     process
+	   - The symlink is not owned by the same user as the
+	     directory it is in
+	   - The directory the symlink is in is writable by
+	     "others"
+	   - The directory the symlink is in has the mode +t
+	     ("sticky")
+
+	  By combining this with 'Hardlink Restrictions' or an
+	  isolated /tmp directorly (such as with a tmpfs mounted
+	  on /tmp), race conditions in /tmp can be prevented.
+
+	  Even with an isolated /tmp, 'Hardlink Restrictions' are
+	  necessary to prevent races within /tmp.  More generally
+	  speaking, 'Symlink Restrictions' will not prevent races
+	  on the same file system.
+
+config GRKERNSEC_HARDLINK_RESTR
+	bool "Hardlink Restrictions"
+	depends on GRKERNSEC_LINK_RESTR
+	help
+	  This option adds a failure (EACCES) to make a hardlink
+	  to a file you don't own, unless you have CAP_FOWNER and
+	  are root.
+
+endmenu
diff -urNp linux-2.6.10/security/grsecurity/kernsec/kernsec.h linux-2.6.10-grs/security/grsecurity/kernsec/kernsec.h
--- linux-2.6.10/security/grsecurity/kernsec/kernsec.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/kernsec/kernsec.h	2005-01-26 16:28:04.557137000 -0500
@@ -0,0 +1,80 @@
+/*
+ * security/grsecurity/kernsec/kernsec.h
+ * GrSecurity KERNSEC header
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ * Copyright (C) 2005 Brad Spengler
+ *
+ *   LICENSE:  GPLv2
+ */
+#ifndef _KERNSEC__H_
+#define _KERNSEC__H_
+/*
+ * figure out what to delete from here
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/grsecurity.h>
+#include <linux/fs.h>
+#include <linux/namei.h>
+
+#define GRKS_MY_NAME "kernsec"
+#define GRKS_MY_FNAME "GrSecurity Kernel Security"
+
+#if defined(CONFIG_GRKERNSEC_PROC)
+int grks_keyboard_handler(const int value);
+
+int grks_proc_pci_legacy_init(const struct proc_dir_entry **entry);
+
+int grks_proc_pci_init(struct proc_dir_entry **proc_bus_pci_dir);
+
+int grks_proc_pid_make_inode(const struct task_struct *task,
+		struct inode *inode);
+
+int grks_proc_pid_revalidate(const struct task_struct *task,
+		struct inode *inode);
+
+int grks_proc_pid_lookup(const struct task_struct *task,
+		struct inode *inode);
+
+int grks_proc_get_tgid_list(const struct task_struct *task);
+
+int grks_proc_get_inode(struct inode *inode,
+		const struct proc_dir_entry *de);
+
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
+int grks_proc_task_stat(unsigned long *eip,
+		unsigned long *esp,
+		unsigned long *wchan,
+		unsigned long *start_code,
+		unsigned long *end_code,
+		unsigned long *start_stack,
+		struct task_struct *task);
+
+int grks_proc_show_map (unsigned long *vm_start,
+		unsigned long *vm_end,
+		unsigned long *vm_pgoff,
+		unsigned long *dev_mj,
+		unsigned long *dev_mn,
+		unsigned long *ino,
+		struct seq_file *m);
+#endif /*CONFIG_GRKERNSEC_PROC_MEMMAP*/
+#endif /*CONFIG_GRKERNSEC_PROC*/
+
+#ifdef CONFIG_GRKERNSEC_SYMLINK_RESTR
+int
+grks_follow_link(const struct dentry *dentry,
+		const struct nameidata *nd);
+#endif
+
+#if defined(CONFIG_GRKERNSEC_HARDLINK_RESTR)
+int
+grks_handle_hardlink (const struct dentry *new_dentry,
+		const struct nameidata *old_nd,
+		const struct nameidata *nd,
+		const char *to);
+#endif
+
+#endif /*_KERNSEC__H_*/
diff -urNp linux-2.6.10/security/grsecurity/kernsec/kernsec_main.c linux-2.6.10-grs/security/grsecurity/kernsec/kernsec_main.c
--- linux-2.6.10/security/grsecurity/kernsec/kernsec_main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/kernsec/kernsec_main.c	2005-01-26 21:52:37.932994000 -0500
@@ -0,0 +1,76 @@
+/*
+ * security/grsecurity/kernsec/kernsec.c
+ * GrSecurity KERNSEC
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ * Copyright (C) 2005 Brad Spengler
+ *
+ *   LICENSE:  GPLv2
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/grsecurity.h>
+#include <linux/fs.h>
+#include "kernsec.h"
+
+
+static 
+struct grsecurity_operations sec_ops = {
+#if defined(CONFIG_GRKERNSEC_PROC)
+	.keyboard_handler =		grks_keyboard_handler,
+	.proc_pci_legacy_init =		grks_proc_pci_legacy_init,
+	.proc_pci_init =		grks_proc_pci_init,
+	.proc_pid_make_inode =		grks_proc_pid_make_inode,
+	.proc_pid_revalidate =		grks_proc_pid_revalidate,
+	.proc_pid_lookup =		grks_proc_pid_lookup,
+	.proc_get_tgid_list =		grks_proc_get_tgid_list,
+	.proc_get_inode =		grks_proc_get_inode,
+# ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
+	.proc_task_stat =		grks_proc_task_stat,
+	.proc_show_map =		grks_proc_show_map,
+# endif /*CONFIG_GRKERNSEC_PROC_MEMMAP*/
+#endif /*CONFIG_GRKERNSEC_PROC*/
+#ifdef CONFIG_GRKERNSEC_SYMLINK_RESTR
+	.inode_follow_link =		grks_follow_link,
+#endif
+#ifdef CONFIG_GRKERNSEC_HARDLINK_RESTR
+	.inode_hardlink =		grks_handle_hardlink,
+#endif
+};
+
+static int __init
+kernsec_m_init(void)
+{
+        /* register ourselves with the security framework */
+	if (register_grsecurity (&sec_ops)) {
+		printk (KERN_INFO
+			"    Failure registering " GRKS_MY_FNAME
+			" module with the kernel\n");
+		return -EINVAL;
+	}
+
+	printk (KERN_INFO "    " GRKS_MY_FNAME " module initialized.\n");
+	
+	return 0;
+}
+
+static void __exit
+kernsec_m_exit(void)
+{
+	/* remove ourselves from the security framework */
+	if (unregister_grsecurity (&sec_ops)) {
+		printk (KERN_INFO "Failure unregistering " GRKS_MY_FNAME
+				" module with the kernel\n");
+	}
+	
+	printk (KERN_INFO GRKS_MY_FNAME " Plug module removed\n");
+}
+
+grsecurity_initcall(kernsec_m_init);
+module_exit(kernsec_m_exit);
+
+MODULE_AUTHOR("John Moser, using the work of Brad Spengler as a reference");
+MODULE_DESCRIPTION(GRKS_MY_FNAME " module");
+MODULE_LICENSE("GPL");
diff -urNp linux-2.6.10/security/grsecurity/kernsec/link_restr.c linux-2.6.10-grs/security/grsecurity/kernsec/link_restr.c
--- linux-2.6.10/security/grsecurity/kernsec/link_restr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/kernsec/link_restr.c	2005-01-25 18:47:23.654082000 -0500
@@ -0,0 +1,62 @@
+/*
+ * security/grsecurity/kernsec/link_restr.c
+ * GrSecurity KERNSEC linking restrictions
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ * Copyright (C) 2005 Brad Spengler
+ *
+ *   LICENSE:  GPLv2
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/grsecurity.h>
+#include <linux/fs.h>
+
+#include "kernsec.h"
+
+#ifdef CONFIG_GRKERNSEC_SYMLINK_RESTR
+/*
+ * If the parent's inode mode is S_ISVTX (sticky, +t) and o+w (world-writable),
+ * and the parent's owner (i_uid) != the inode's owner,
+ * and the inode isn't owned by the owner of current,
+ * deny access.
+ */
+int
+grks_follow_link(const struct dentry *dentry,
+		const struct nameidata *nd) {
+	struct inode *inode = dentry->d_inode;
+	struct inode *parent = dentry->d_parent->d_inode;
+
+	if (S_ISLNK(inode->i_mode) &&
+	    (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
+	    (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
+		return -EACCES;
+	}
+	return 0;
+}
+#endif
+
+#if defined(CONFIG_GRKERNSEC_HARDLINK_RESTR)
+/*
+ * Fails in certain cases for a number of reasons I don't yet understand
+ */
+int
+grks_handle_hardlink (const struct dentry *new_dentry,
+		const struct nameidata *old_nd,
+		const struct nameidata *nd,
+		const char *to) {
+	struct inode *inode = old_nd->dentry->d_inode;
+	int mode = inode->i_mode;
+	if (current->fsuid != inode->i_uid &&
+	    (!S_ISREG(mode) || (mode & S_ISUID) ||
+	     ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
+	      (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
+	     !capable(CAP_FOWNER) && current->uid) {
+		return -EPERM;
+	}
+	return 0;
+}
+#endif
+
diff -urNp linux-2.6.10/security/grsecurity/kernsec/Makefile linux-2.6.10-grs/security/grsecurity/kernsec/Makefile
--- linux-2.6.10/security/grsecurity/kernsec/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/kernsec/Makefile	2005-01-26 20:53:16.017290000 -0500
@@ -0,0 +1,12 @@
+#
+# Makefile for the grsecurity kernsec code
+#
+
+
+kernsec-objs-$(CONFIG_GRKERNSEC_LINK_RESTR)	:= link_restr.o
+kernsec-objs-$(CONFIG_GRKERNSEC_PROC)		+= proc_prot.o
+kernsec-objs					:= kernsec_main.o $(kernsec-objs-y)
+
+obj-$(CONFIG_GRSECURITY_KERNSEC)		= kernsec.o
+
+
diff -urNp linux-2.6.10/security/grsecurity/kernsec/proc_prot.c linux-2.6.10-grs/security/grsecurity/kernsec/proc_prot.c
--- linux-2.6.10/security/grsecurity/kernsec/proc_prot.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/kernsec/proc_prot.c	2005-01-26 20:31:32.315483000 -0500
@@ -0,0 +1,166 @@
+/*
+ * security/grsecurity/kernsec/proc.c
+ * GrSecurity KERNSEC proc restrictions and protections
+ *
+ * Copyright (C) 2005 John Moser <nigelenkiat_private>
+ * Copyright (C) 2005 Brad Spengler
+ *
+ *   LICENSE:  GPLv2
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/grsecurity.h>
+#include <linux/fs.h>
+#include <linux/keyboard.h>
+#include <linux/proc_fs.h>
+
+#include "kernsec.h"
+
+enum {
+_KBD_FN_HANDLERS
+};
+
+/*
+ * handle keyboard stuff, prevent magicsysrq from leaking info.
+ */
+int
+grks_keyboard_handler(const int value) {
+	if (value == fn_show_state || value == fn_show_ptregs ||
+			value == fn_show_mem)
+		return -EACCES;
+	return 0;
+}
+
+int grks_proc_pci_legacy_init(const struct proc_dir_entry **entry) {
+	*entry = create_proc_entry("pci", S_IRUSR
+#ifdef CONFIG_GRKERNSEC_PROC_GROUP_ACCESS
+		| S_IRGRP
+#endif
+		, NULL);
+	/*Returns nonzero on alter*/
+	return 1;
+}
+
+int grks_proc_pci_init(struct proc_dir_entry **proc_bus_pci_dir) {
+	*proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR
+#ifdef CONFIG_GRKERNSEC_PROC_GROUP_ACCESS
+		| S_IRGRP | S_IXGRP
+#endif
+		, proc_bus);
+	/*returns nonzero on alter*/
+	return 1;
+}
+
+static int local_proc_pid_task_check(const struct task_struct *task) {
+#if defined(CONFIG_GRKERNSEC_PROC_USER)
+	if ( ((current->uid || !capable(CAP_SYS_ADMIN))
+		&& (task->uid != current->uid))
+# if defined(CONFIG_GRKERNSEC_PROC_GROUP_ACCESS)
+		&& !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
+#endif /*defined(CONFIG_GRKERNSEC_PROC_GROUP_ACCESS)*/
+	     ) {
+		return -ENOENT;
+	}
+#endif /*defined(CONFIG_GRKERNSEC_PROC_USER)*/
+	return 0;
+}
+
+/*
+ * used for making an inode AND for proc_pid_revalidate 
+ */
+int grks_proc_pid_make_inode(const struct task_struct *task,
+		struct inode *inode) {
+	inode->i_uid = task->euid;
+#ifdef CONFIG_GRKERNSEC_PROC_GROUP_ACCESS
+	inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
+#else
+	inode->i_gid = task->egid;
+#endif /*CONFIG_GRKERNSEC_PROC_GROUP_ACCESS*/
+	/*next we validate if you can see the task*/
+	return local_proc_pid_task_check(task);
+}
+
+int grks_proc_pid_revalidate(const struct task_struct *task,
+		struct inode *inode) {
+#ifdef CONFIG_GRKERNSEC_PROC_GROUP_ACCESS
+	if (inode->i_uid)
+		inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
+#endif /*CONFIG_GRKERNSEC_PROC_GROUP_ACCESS*/
+	return 0;
+}
+
+/*
+ * This logic is hell when you consider adding PROC_GID with
+ * caps, AS AN OPTION.
+ */
+int grks_proc_pid_lookup(const struct task_struct *task,
+		struct inode *inode) {
+	int error = 0;
+	error = local_proc_pid_task_check(task);
+	if (error)
+		goto out;
+#ifdef CONFIG_GRKERNSEC_PROC_USER
+	inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
+#endif
+#ifdef CONFIG_GRKERNSEC_PROC_GROUP_ACCESS
+	inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
+	inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
+#endif /*CONFIG_GRKERNSEC_PROC_GROUP_ACCESS*/
+out:
+	return error;
+}
+
+int grks_proc_get_tgid_list(const struct task_struct *task) {
+	return local_proc_pid_task_check(task);
+}
+
+int grks_proc_get_inode(struct inode *inode,
+		const struct proc_dir_entry *de) {
+#ifdef CONFIG_GRKERNSEC_PROC_GROUP_ACCESS
+	if (de && de->mode)
+		inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
+#endif
+	return 0;
+}
+
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
+int grks_proc_task_stat(unsigned long *eip,
+		unsigned long *esp,
+		unsigned long *wchan,
+		unsigned long *start_code,
+		unsigned long *end_code,
+		unsigned long *start_stack,
+		struct task_struct *task) {
+	/*unless root with CAP_SYS_PTRACE, hide this info*/
+	if ( !capable(CAP_SYS_PTRACE) || current->uid ) {
+		*eip =
+		*esp =
+		*wchan =
+		*start_code =
+		*end_code =
+		*start_stack = 0;
+	}
+	return 0;
+}
+
+int grks_proc_show_map (unsigned long *vm_start,
+		unsigned long *vm_end,
+		unsigned long *vm_pgoff,
+		unsigned long *dev_mj,
+		unsigned long *dev_mn,
+		unsigned long *ino,
+		struct seq_file *m) {
+	/*unless root with CAP_SYS_PTRACE, hide this info*/
+	if ( !capable(CAP_SYS_PTRACE) || current->uid ) {
+		*vm_start =
+		*vm_end =
+		*vm_pgoff =
+		*dev_mj =
+		*dev_mn =
+		*ino = 0;
+	}
+	return 0;
+}
+#endif /*CONFIG_GRKERNSEC_PROC_MEMMAP*/
diff -urNp linux-2.6.10/security/grsecurity/Makefile linux-2.6.10-grs/security/grsecurity/Makefile
--- linux-2.6.10/security/grsecurity/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.10-grs/security/grsecurity/Makefile	2005-01-26 22:16:57.559227000 -0500
@@ -0,0 +1,11 @@
+#
+# Makefile for the grsecurity security code
+#
+
+obj-y					= grsecurity.o grfunctions.o
+
+#subdir-$(CONFIG_GRSECURITY_KERNSEC)	+= kernsec/
+# if we -y the kernsecs
+# Do we need to just obj- this wtf
+obj-$(CONFIG_GRSECURITY_KERNSEC)	+= kernsec/
+obj-$(CONFIG_GRSECURITY_DUMMY_TESTS)	+= dummy/
diff -urNp linux-2.6.10/security/Kconfig linux-2.6.10-grs/security/Kconfig
--- linux-2.6.10/security/Kconfig	2004-12-24 16:35:21.000000000 -0500
+++ linux-2.6.10-grs/security/Kconfig	2005-01-25 18:47:17.664993000 -0500
@@ -86,5 +86,7 @@ config SECURITY_SECLVL
 
 source security/selinux/Kconfig
 
+source security/grsecurity/Kconfig
+
 endmenu
 
diff -urNp linux-2.6.10/security/Makefile linux-2.6.10-grs/security/Makefile
--- linux-2.6.10/security/Makefile	2004-12-24 16:35:23.000000000 -0500
+++ linux-2.6.10-grs/security/Makefile	2005-01-25 18:47:17.665992000 -0500
@@ -17,3 +17,5 @@ obj-$(CONFIG_SECURITY_SELINUX)		+= selin
 obj-$(CONFIG_SECURITY_CAPABILITIES)	+= commoncap.o capability.o
 obj-$(CONFIG_SECURITY_ROOTPLUG)		+= commoncap.o root_plug.o
 obj-$(CONFIG_SECURITY_SECLVL)		+= seclvl.o
+
+obj-$(CONFIG_GRSECURITY)		+= grsecurity/





This archive was generated by hypermail 2.1.3 : Thu Jan 27 2005 - 20:49:09 PST