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(¤t->fs->lock);
+ read_lock(¤t->fs->lock);
if (*dentry == current->fs->root &&
- *mnt == current->fs->rootmnt) {
- read_unlock(¤t->fs->lock);
+ *mnt == current->fs->rootmnt) {
+ read_unlock(¤t->fs->lock);
break;
}
- read_unlock(¤t->fs->lock);
+ read_unlock(¤t->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 <nigelenki@comcast.net>
+ * Copyright (C) 2005 Brad Spengler
+ *
+ * Derived from security.h which is:
+ * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com>
+ * Copyright (C) 2001 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
+ * Copyright (C) 2001 James Morris <jmorris@intercode.com.au>
+ * 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 <nigelenki@comcast.net>
+ *
+ * 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 <nigelenki@comcast.net>
+ *
+ * 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 <nigelenki@comcast.net>
+ *
+ * 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 <nigelenki@comcast.net>
+ * Copyright (C) 2001-2005 Brad Spengler
+ *
+ * Derived partially from security.c which is:
+ * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com>
+ * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
+ *
+ * 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 <nigelenki@comcast.net>
+ * Copyright (C) 2001-2005 Brad Spengler
+ *
+ * Derived partially from security.c which is:
+ * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com>
+ * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
+ *
+ * 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 <nigelenki@comcast.net>
+ * 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 <nigelenki@comcast.net>
+ * 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 <nigelenki@comcast.net>
+ * 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 <nigelenki@comcast.net>
+ * 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