Re: [ANNOUNCE] WOLK v2.3 for Kernel v2.6.4
Marc-Christian Petersen <[email protected]> Wed, 31 Mar 2004 06:33:16 +0200
| Newsgroups | gmane.linux.wolk.devel |
|---|---|
| Organization | Working Overloaded Linux Kernel |
| Message-ID | <200403310633.16334@WOLK> |
On Wednesday 31 March 2004 03:24, KORN Andras wrote:
Hi Andrew,
> > > BTW: What's up with "/proc restrictions w/o the need of grsecurity"
> > > patch?
> Well, here it is. It worked for me before I added the #ifdefs, so it should
> probably still work.
wooohoo.
> I'm not sure about the correct permissions on some of the entries. I'm also
> not sure what software this patch breaks. A lot more testing is needed.
> The attached patch also corrects two typos in security/Kconfig.
thanks alot. Unfortunately there were 2 compile errors, very trivial fixable
but the kernel BUG()s alot at booting. I cooked up something similar with
some more security stuff. What do you think about the attached one?
Should apply on 2.6-wolk2.3 though I work with 2.6-wolk2.4 (not yet released)
This adds:
----------
- restrict /proc to user only
- Allow special group for /proc restrictions
- Additional restrictions (no cpu and device info)
- Even more additional restrictions (read the help ;)
- hide kernel symbols
- /proc/<pid>/ipaddr
- Deny writing to /dev/kmem, /dev/mem, and /dev/port
- Disable privileged I/O
- Linking restrictions
- FIFO restrictions
- dmesg(8) restrictions
- Randomizing of: PIDS, TCP ISN, IP IDs, TCP source ports
- and last but not blech, sysctl support for some of it ;)
I plan to add more features from grsecurity. My goal is to offer all
grsecurity's stuff without: RBAC and PaX. Kinda difficult to rip out all ACL
and PaX stuff from grsec ;(
Someone else want to help here? Dariush: broken-out patches are there for
2.6-wolk but where are all the developers? ;p
P.S.: I took stuff from OpenPaX. One question to those coders: Have you been
on holy shit drugs while coding that?
ciao, Marc
8008_misc-security.patch
(text/x-diff, 58.7 KB)
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/arch/i386/kernel/cpu/mtrr/if.c linux-2.6.4-wolk2.4-procrestrict/arch/i386/kernel/cpu/mtrr/if.c
--- linux-2.6.4-wolk2.4-fullkernel/arch/i386/kernel/cpu/mtrr/if.c 2004-03-11 16:03:07.000000000 +0100
+++ linux-2.6.4-wolk2.4-procrestrict/arch/i386/kernel/cpu/mtrr/if.c 2004-03-31 05:35:44.000000000 +0200
@@ -360,8 +360,13 @@ static int __init mtrr_if_init(void)
(!cpu_has(c, X86_FEATURE_CENTAUR_MCR)))
return -ENODEV;
- proc_root_mtrr =
- create_proc_entry("mtrr", S_IWUSR | S_IRUGO, &proc_root);
+#if defined (CONFIG_SECURITY_PROC_ADD_MORE) && defined (CONFIG_SECURITY_PROC_USER)
+ proc_root_mtrr = create_proc_entry("mtrr", S_IRUSR, &proc_root);
+#elif defined (CONFIG_SECURITY_PROC_ADD_MORE) && defined (CONFIG_SECURITY_PROC_USERGROUP)
+ proc_root_mtrr = create_proc_entry("mtrr", S_IRUSR | S_IRGRP, &proc_root);
+#else
+ proc_root_mtrr = create_proc_entry("mtrr", S_IWUSR | S_IRUGO, &proc_root);
+#endif
if (proc_root_mtrr) {
proc_root_mtrr->owner = THIS_MODULE;
proc_root_mtrr->proc_fops = &mtrr_fops;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/arch/i386/kernel/ioport.c linux-2.6.4-wolk2.4-procrestrict/arch/i386/kernel/ioport.c
--- linux-2.6.4-wolk2.4-fullkernel/arch/i386/kernel/ioport.c 2004-03-17 19:04:16.000000000 +0100
+++ linux-2.6.4-wolk2.4-procrestrict/arch/i386/kernel/ioport.c 2004-03-31 03:53:25.000000000 +0200
@@ -62,8 +62,13 @@ asmlinkage long sys_ioperm(unsigned long
if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
return -EINVAL;
+#ifdef CONFIG_SECURITY_IO
+ if (turn_on)
+ return -EPERM;
+#else
if (turn_on && !capable(CAP_SYS_RAWIO))
return -EPERM;
+#endif
/*
* If it's the first ioperm() call in this thread's lifetime, set the
@@ -115,8 +120,12 @@ asmlinkage long sys_iopl(unsigned long u
return -EINVAL;
/* Trying to gain more privileges? */
if (level > old) {
+#ifdef CONFIG_SECURITY_IO
+ return -EPERM;
+#else
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
+#endif
}
regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
/* Make sure we return the long way (not sysenter) */
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/drivers/char/mem.c linux-2.6.4-wolk2.4-procrestrict/drivers/char/mem.c
--- linux-2.6.4-wolk2.4-fullkernel/drivers/char/mem.c 2004-03-30 19:38:58.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/drivers/char/mem.c 2004-03-31 03:53:25.000000000 +0200
@@ -559,6 +559,14 @@ static loff_t memory_lseek(struct file *
static int open_port(struct inode * inode, struct file * filp)
{
+#ifdef CONFIG_SECURITY_KMEM
+ return -EPERM;
+#endif
+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+}
+
+static int open_mem(struct inode * inode, struct file * filp)
+{
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
}
@@ -567,7 +575,6 @@ static int open_port(struct inode * inod
#define full_lseek null_lseek
#define write_zero write_null
#define read_full read_zero
-#define open_mem open_port
#define open_kmem open_mem
static struct file_operations mem_fops = {
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/drivers/char/random.c linux-2.6.4-wolk2.4-procrestrict/drivers/char/random.c
--- linux-2.6.4-wolk2.4-fullkernel/drivers/char/random.c 2004-03-30 19:41:26.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/drivers/char/random.c 2004-03-31 03:53:25.000000000 +0200
@@ -259,7 +259,7 @@
/*
* Configuration information
*/
-#ifdef CONFIG_NET_RANDOM
+#if defined (CONFIG_NET_RANDOM) || defined (CONFIG_SECURITY_RANDNET)
# define INPUT_POOL_SIZE 2048
# define BLOCKING_POOL_SIZE 256
#else
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/drivers/pci/proc.c linux-2.6.4-wolk2.4-procrestrict/drivers/pci/proc.c
--- linux-2.6.4-wolk2.4-fullkernel/drivers/pci/proc.c 2004-03-30 19:38:58.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/drivers/pci/proc.c 2004-03-31 06:22:45.000000000 +0200
@@ -565,7 +565,15 @@ static struct file_operations proc_pci_o
static void legacy_proc_init(void)
{
+#ifdef CONFIG_SECURITY_PROC_ADD
+#ifdef CONFIG_SECURITY_PROC_USER
+ struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR, NULL);
+#elif CONFIG_SECURITY_PROC_USERGROUP
+ struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
+#endif
+#else
struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
+#endif
if (entry)
entry->proc_fops = &proc_pci_operations;
}
@@ -594,7 +602,15 @@ static int __init pci_proc_init(void)
{
struct proc_dir_entry *entry;
struct pci_dev *dev = NULL;
+#ifdef CONFIG_SECURITY_PROC_ADD
+#ifdef CONFIG_SECURITY_PROC_USER
+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
+#elif CONFIG_SECURITY_PROC_USERGROUP
+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
+#endif
+#else
proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
+#endif
entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
if (entry)
entry->proc_fops = &proc_bus_pci_dev_operations;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/fs/namei.c linux-2.6.4-wolk2.4-procrestrict/fs/namei.c
--- linux-2.6.4-wolk2.4-fullkernel/fs/namei.c 2004-03-30 19:41:19.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/fs/namei.c 2004-03-31 03:53:25.000000000 +0200
@@ -395,6 +395,24 @@ static struct dentry * real_lookup(struc
return result;
}
+#ifdef CONFIG_SECURITY_LINK
+int sec_handle_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ struct inode *inode, *dir;
+
+ inode = dentry->d_inode;
+ dir = dentry->d_parent->d_inode;
+
+ if ((dir->i_mode & S_ISVTX) &&
+ inode->i_uid != dir->i_uid &&
+ current->fsuid != inode->i_uid) {
+ return -EACCES;
+ }
+
+ return 0;
+}
+#endif
+
/*
* This limits recursive symlink follows to 8, while
* limiting consecutive symlinks to 40.
@@ -405,12 +423,15 @@ static struct dentry * real_lookup(struc
static int do_follow_link(struct dentry *dentry, struct nameidata *nd)
{
int err = -ELOOP;
- if (current->link_count >= 5)
+ if (current->link_count >= 8)
goto loop;
if (current->total_link_count >= 40)
goto loop;
cond_resched();
err = security_inode_follow_link(dentry, nd);
+#ifdef CONFIG_SECURITY_LINK
+ err |= sec_handle_follow_link(dentry, nd);
+#endif
if (err)
goto loop;
current->link_count++;
@@ -1262,6 +1283,9 @@ int open_namei(const char * pathname, in
int acc_mode, error = 0;
struct dentry *dentry;
struct dentry *dir;
+#ifdef CONFIG_SECURITY_FIFO
+ struct inode *inode;
+#endif
int count = 0;
acc_mode = ACC_MODE(flag);
@@ -1332,6 +1356,23 @@ do_last:
/*
* It already exists.
*/
+#ifdef CONFIG_SECURITY_FIFO
+ /*
+ * Don't write to FIFOs that we don't own in +t directories,
+ * unless the FIFO is owned by the owner of the directory.
+ *
+ * Do this check early while we hold the directory.
+ */
+ inode = dentry->d_inode;
+ if (S_ISFIFO(inode->i_mode) && !(flag & O_EXCL) &&
+ (dir->d_inode->i_mode & S_ISVTX) &&
+ inode->i_uid != dir->d_inode->i_uid &&
+ current->fsuid != inode->i_uid) {
+ up(&dir->d_inode->i_sem);
+ error = -EACCES;
+ goto exit_dput;
+ }
+#endif
up(&dir->d_inode->i_sem);
error = -EEXIST;
@@ -1383,6 +1424,9 @@ do_link:
*/
nd->flags |= LOOKUP_PARENT;
error = security_inode_follow_link(dentry, nd);
+#ifdef CONFIG_SECURITY_LINK
+ error |= sec_handle_follow_link(dentry, nd);
+#endif
if (error)
goto exit_dput;
touch_atime(nd->mnt, dentry);
@@ -1821,6 +1865,18 @@ out:
return error;
}
+#ifdef CONFIG_SECURITY_LINK
+int sec_handle_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+
+ if (current->fsuid && (current->fsuid != inode->i_uid))
+ return -EACCES;
+
+ return 0;
+}
+#endif
+
int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
{
struct inode *inode = old_dentry->d_inode;
@@ -1847,6 +1903,11 @@ int vfs_link(struct dentry *old_dentry,
return -EPERM;
error = security_inode_link(old_dentry, dir, new_dentry);
+
+#ifdef CONFIG_SECURITY_LINK
+ /* this way we won't break anything :) */
+ error |= sec_handle_inode_link(old_dentry, dir, new_dentry);
+#endif
if (error)
return error;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/fs/proc/array.c linux-2.6.4-wolk2.4-procrestrict/fs/proc/array.c
--- linux-2.6.4-wolk2.4-fullkernel/fs/proc/array.c 2004-03-30 19:41:18.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/fs/proc/array.c 2004-03-31 03:53:25.000000000 +0200
@@ -322,6 +322,12 @@ int proc_pid_stat(struct task_struct *ta
wchan = get_wchan(task);
+#ifdef CONFIG_SECURITY_HIDESYM
+ wchan = 0;
+ eip =0;
+ esp =0;
+#endif
+
sigemptyset(&sigign);
sigemptyset(&sigcatch);
read_lock(&tasklist_lock);
@@ -420,3 +426,14 @@ int proc_pid_statm(struct task_struct *t
return sprintf(buffer,"%d %d %d %d %d %d %d\n",
size, resident, shared, text, lib, data, 0);
}
+
+#ifdef CONFIG_SECURITY_PROC_IPADDR
+int proc_pid_ipaddr(struct task_struct *task, char * buffer)
+{
+ int len;
+
+ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));
+ return len;
+}
+#endif
+
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/fs/proc/base.c linux-2.6.4-wolk2.4-procrestrict/fs/proc/base.c
--- linux-2.6.4-wolk2.4-fullkernel/fs/proc/base.c 2004-03-31 04:33:15.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/fs/proc/base.c 2004-03-31 04:36:20.000000000 +0200
@@ -67,6 +67,9 @@ enum pid_directory_inos {
PROC_TGID_ATTR_EXEC,
PROC_TGID_ATTR_FSCREATE,
#endif
+#ifdef CONFIG_SECURITY_PROC_IPADDR
+ PROC_TGID_IPADDR,
+#endif
PROC_TGID_FD_DIR,
PROC_TID_INO,
PROC_TID_STATUS,
@@ -123,6 +126,9 @@ static struct pid_entry tgid_base_stuff[
E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
+#ifdef CONFIG_SECURITY_PROC_IPADDR
+ E(PROC_TGID_IPADDR, "ipaddr", S_IFREG|S_IRUSR),
+#endif
#ifdef CONFIG_SECURITY
E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
#endif
@@ -193,6 +199,9 @@ int proc_pid_stat(struct task_struct*,ch
int proc_pid_status(struct task_struct*,char*);
int proc_pid_statm(struct task_struct*,char*);
int proc_pid_cpu(struct task_struct*,char*);
+#ifdef CONFIG_SECURITY_PROC_IPADDR
+int proc_pid_ipaddr(struct task_struct*,char*);
+#endif
static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
{
@@ -1031,6 +1040,9 @@ static struct inode *proc_pid_make_inode
inode->i_uid = task->euid;
inode->i_gid = task->egid;
}
+#ifdef CONFIG_SECURITY_PROC_USERGROUP
+ inode->i_gid = CONFIG_SECURITY_PROC_GID;
+#endif
security_task_to_inode(task, inode);
out:
@@ -1059,7 +1071,9 @@ static int pid_revalidate(struct dentry
if (pid_alive(task)) {
if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
inode->i_uid = task->euid;
+#ifndef CONFIG_SECURITY_PROC_USERGROUP
inode->i_gid = task->egid;
+#endif
} else {
inode->i_uid = 0;
inode->i_gid = 0;
@@ -1407,6 +1421,12 @@ static struct dentry *proc_pident_lookup
inode->i_fop = &proc_info_file_operations;
ei->op.proc_read = proc_pid_status;
break;
+#ifdef CONFIG_SECURITY_PROC_IPADDR
+ case PROC_TGID_IPADDR:
+ inode->i_fop = &proc_info_file_operations;
+ ei->op.proc_read = proc_pid_ipaddr;
+ break;
+#endif
case PROC_TID_STAT:
case PROC_TGID_STAT:
inode->i_fop = &proc_info_file_operations;
@@ -1667,6 +1687,17 @@ struct dentry *proc_pid_lookup(struct in
if (!task)
goto out;
+#if defined(CONFIG_SECURITY_PROC_USER) || defined(CONFIG_SECURITY_PROC_USERGROUP)
+ if (current->uid && (task->uid != current->uid)
+#ifdef CONFIG_SECURITY_PROC_USERGROUP
+ && !in_group_p(CONFIG_SECURITY_PROC_GID)
+#endif
+ ) {
+ put_task_struct(task);
+ goto out;
+ }
+#endif
+
inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
@@ -1674,7 +1705,15 @@ struct dentry *proc_pid_lookup(struct in
put_task_struct(task);
goto out;
}
+
+#ifdef CONFIG_SECURITY_PROC_USER
+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
+#elif CONFIG_SECURITY_PROC_USERGROUP
+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
+ inode->i_gid = CONFIG_SECURITY_PROC_GID;
+#else
inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+#endif
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_nlink = 3;
@@ -1758,6 +1797,9 @@ out:
static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
{
struct task_struct *p;
+#if defined(CONFIG_SECURITY_PROC_USER) || defined(CONFIG_SECURITY_PROC_USERGROUP)
+ struct task_struct *tmp = current;
+#endif
int nr_tgids = 0;
index--;
@@ -1778,6 +1820,14 @@ static int get_tgid_list(int index, unsi
int tgid = p->pid;
if (!pid_alive(p))
continue;
+#if defined(CONFIG_SECURITY_PROC_USER) || defined(CONFIG_SECURITY_PROC_USERGROUP)
+ if (tmp->uid && (p->uid != tmp->uid)
+#ifdef CONFIG_SECURITY_PROC_USERGROUP
+ && !in_group_p(CONFIG_SECURITY_PROC_GID)
+#endif
+ )
+ continue;
+#endif
if (--index >= 0)
continue;
tgids[nr_tgids] = tgid;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/fs/proc/inode.c linux-2.6.4-wolk2.4-procrestrict/fs/proc/inode.c
--- linux-2.6.4-wolk2.4-fullkernel/fs/proc/inode.c 2004-03-31 04:33:15.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/fs/proc/inode.c 2004-03-31 03:53:25.000000000 +0200
@@ -205,7 +205,11 @@ printk("proc_iget: using deleted entry %
if (de->mode) {
inode->i_mode = de->mode;
inode->i_uid = de->uid;
+#ifdef CONFIG_SECURITY_PROC_USERGROUP
+ inode->i_gid = CONFIG_SECURITY_PROC_GID;
+#else
inode->i_gid = de->gid;
+#endif
}
if (de->size)
inode->i_size = de->size;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/fs/proc/proc_misc.c linux-2.6.4-wolk2.4-procrestrict/fs/proc/proc_misc.c
--- linux-2.6.4-wolk2.4-fullkernel/fs/proc/proc_misc.c 2004-03-31 04:33:15.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/fs/proc/proc_misc.c 2004-03-31 06:12:07.000000000 +0200
@@ -752,11 +752,13 @@ static struct file_operations proc_lockm
void __init proc_misc_init(void)
{
struct proc_dir_entry *entry;
+ int sec_mode = 0;
+
static struct {
char *name;
int (*read_proc)(char*,char**,off_t,int,int*,void*);
} *p, simple_ones[] = {
- {"loadavg", loadavg_read_proc},
+ {"loadavg", loadavg_read_proc},
{"uptime", uptime_read_proc},
{"meminfo", meminfo_read_proc},
{"version", version_read_proc},
@@ -766,9 +768,13 @@ void __init proc_misc_init(void)
#ifdef CONFIG_STRAM_PROC
{"stram", stram_read_proc},
#endif
+#ifndef CONFIG_SECURITY_PROC_ADD
{"devices", devices_read_proc},
+#endif
{"filesystems", filesystems_read_proc},
+#ifndef CONFIG_SECURITY_PROC_ADD
{"cmdline", cmdline_read_proc},
+#endif
#ifdef CONFIG_SGI_DS1286
{"rtc", ds1286_read_proc},
#endif
@@ -778,33 +784,77 @@ void __init proc_misc_init(void)
{"execdomains", execdomains_read_proc},
{NULL,}
};
+
for (p = simple_ones; p->name; p++)
create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
+#ifdef CONFIG_SECURITY_PROC_USER
+ sec_mode = S_IRUSR;
+#elif CONFIG_SECURITY_PROC_USERGROUP
+ sec_mode = S_IRUSR | S_IRGRP;
+#endif
+
+#ifdef CONFIG_SECURITY_PROC_ADD
+ create_proc_read_entry("devices", sec_mode, NULL, &devices_read_proc, NULL);
+ create_proc_read_entry("cmdline", sec_mode, NULL, &cmdline_read_proc, NULL);
+#endif
+
proc_symlink("mounts", NULL, "self/mounts");
/* And now for trickier ones */
entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
if (entry)
entry->proc_fops = &proc_kmsg_operations;
+
+#ifdef CONFIG_SECURITY_PROC_ADD
+ create_seq_entry("cpuinfo", sec_mode, &proc_cpuinfo_operations);
+#ifndef CONFIG_SLOB
+ create_seq_entry("slabinfo", sec_mode, &proc_slabinfo_operations);
+#endif
+#else
create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
- create_seq_entry("partitions", 0, &proc_partitions_operations);
- create_seq_entry("stat", 0, &proc_stat_operations);
- create_seq_entry("interrupts", 0, &proc_interrupts_operations);
#ifndef CONFIG_SLOB
create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
#endif
+#endif /* CONFIG_SECURITY_PROC_ADD */
+
+#ifdef CONFIG_SECURITY_PROC_ADD_MORE
+ create_seq_entry("partitions", sec_mode, &proc_partitions_operations);
+ create_seq_entry("stat", sec_mode, &proc_stat_operations);
+ create_seq_entry("interrupts", sec_mode, &proc_interrupts_operations);
+#ifdef CONFIG_KMALLOC_ACCOUNTING
+ create_seq_entry("kmalloc", sec_mode, &proc_kmalloc_account_operations);
+#endif
+#ifdef CONFIG_PROC_SLEEP
+ create_seq_entry("sleep", sec_mode, &proc_global_sleep_operations);
+#endif
+ create_seq_entry("buddyinfo", sec_mode, &fragmentation_file_operations);
+ create_seq_entry("vmstat", sec_mode, &proc_vmstat_file_operations);
+ create_seq_entry("zoneinfo", sec_mode, &proc_zoneinfo_file_operations);
+ create_seq_entry("diskstats", sec_mode, &proc_diskstats_operations);
+
+#else /* !CONFIG_SECURITY_PROC_ADD_MORE */
+
+ create_seq_entry("partitions", 0, &proc_partitions_operations);
+ create_seq_entry("stat", 0, &proc_stat_operations);
+ create_seq_entry("interrupts", 0, &proc_interrupts_operations);
#ifdef CONFIG_KMALLOC_ACCOUNTING
- create_seq_entry("kmalloc", S_IRUGO, &proc_kmalloc_account_operations);
+ create_seq_entry("kmalloc", S_IRUGO, &proc_kmalloc_account_operations);
#endif
- create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
- create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
- create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
+#ifdef CONFIG_PROC_SLEEP
+ create_seq_entry("sleep", 0, &proc_global_sleep_operations);
+#endif
+ create_seq_entry("buddyinfo", S_IRUGO, &fragmentation_file_operations);
+ create_seq_entry("vmstat", S_IRUGO, &proc_vmstat_file_operations);
+ create_seq_entry("zoneinfo", S_IRUGO, &proc_zoneinfo_file_operations);
create_seq_entry("diskstats", 0, &proc_diskstats_operations);
+#endif /* CONFIG_SECURITY_PROC_ADD_MORE */
+
+
#ifdef CONFIG_MODULES
- create_seq_entry("modules", 0, &proc_modules_operations);
+ create_seq_entry("modules", sec_mode, &proc_modules_operations);
#endif
-#ifdef CONFIG_PROC_KCORE
+#if defined(CONFIG_PROC_KCORE)
proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
if (proc_root_kcore) {
proc_root_kcore->proc_fops = &proc_kcore_operations;
@@ -839,7 +889,4 @@ void __init proc_misc_init(void)
entry->proc_fops = &ppc_htab_operations;
}
#endif
-#ifdef CONFIG_PROC_SLEEP
- create_seq_entry("sleep", 0, &proc_global_sleep_operations);
-#endif
}
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/fs/proc/root.c linux-2.6.4-wolk2.4-procrestrict/fs/proc/root.c
--- linux-2.6.4-wolk2.4-fullkernel/fs/proc/root.c 2004-03-31 04:33:15.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/fs/proc/root.c 2004-03-31 03:53:25.000000000 +0200
@@ -52,13 +52,26 @@ void __init proc_root_init(void)
return;
}
proc_misc_init();
+
+#ifdef CONFIG_SECURITY_PROC_USER
+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, 0);
+#elif CONFIG_SECURITY_PROC_USERGROUP
+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
+#else
proc_net = proc_mkdir("net", 0);
+#endif
#ifdef CONFIG_SYSVIPC
proc_mkdir("sysvipc", 0);
#endif
#ifdef CONFIG_SYSCTL
+#ifdef CONFIG_SECURITY_PROC_USER
+ proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR, 0);
+#elif CONFIG_SECURITY_PROC_USERGROUP
+ proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
+#else
proc_sys_root = proc_mkdir("sys", 0);
#endif
+#endif
#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
proc_mkdir("sys/fs", 0);
proc_mkdir("sys/fs/binfmt_misc", 0);
@@ -78,7 +91,15 @@ void __init proc_root_init(void)
#ifdef CONFIG_PROC_DEVICETREE
proc_device_tree_init();
#endif
+#ifdef CONFIG_SECURITY_PROC_ADD
+#ifdef CONFIG_SECURITY_PROC_USER
+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, 0);
+#elif CONFIG_SECURITY_PROC_USERGROUP
+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
+#endif
+#else
proc_bus = proc_mkdir("bus", 0);
+#endif
}
static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/include/linux/proc_fs.h linux-2.6.4-wolk2.4-procrestrict/include/linux/proc_fs.h
--- linux-2.6.4-wolk2.4-fullkernel/include/linux/proc_fs.h 2004-03-31 04:33:15.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/include/linux/proc_fs.h 2004-03-31 03:53:25.000000000 +0200
@@ -234,7 +234,7 @@ extern struct proc_dir_entry proc_root;
#endif /* CONFIG_PROC_FS */
-#if !defined(CONFIG_PROC_FS)
+#if !defined(CONFIG_PROC_FS) || !defined(CONFIG_PROC_KCORE)
static inline void kclist_add(struct kcore_list *new, void *addr, size_t size)
{
}
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/include/linux/sched.h linux-2.6.4-wolk2.4-procrestrict/include/linux/sched.h
--- linux-2.6.4-wolk2.4-fullkernel/include/linux/sched.h 2004-03-30 19:42:32.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/include/linux/sched.h 2004-03-31 03:53:25.000000000 +0200
@@ -538,6 +538,11 @@ struct task_struct {
* to a stack based synchronous wait) if its doing sync IO.
*/
wait_queue_t *io_wait;
+
+#ifdef CONFIG_SECURITY_PROC_IPADDR
+ u32 curr_ip;
+ u8 used_accept:1;
+#endif
};
static inline pid_t process_group(struct task_struct *tsk)
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/include/linux/sysctl.h linux-2.6.4-wolk2.4-procrestrict/include/linux/sysctl.h
--- linux-2.6.4-wolk2.4-fullkernel/include/linux/sysctl.h 2004-03-30 20:03:26.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/include/linux/sysctl.h 2004-03-31 03:53:25.000000000 +0200
@@ -61,7 +61,10 @@ enum
CTL_DEV=7, /* Devices */
CTL_BUS=8, /* Busses */
CTL_ABI=9, /* Binary emulation */
- CTL_CPU=10 /* CPU stuff (speed scaling, etc) */
+ CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
+#ifdef CONFIG_SECURITY_SYSCTL
+ CTL_SECURITY=11 /* Security toggles */
+#endif
};
/* CTL_BUS names: */
@@ -825,6 +828,18 @@ enum
ABI_FAKE_UTSNAME=6, /* fake target utsname information */
};
+#ifdef CONFIG_SECURITY_SYSCTL
+/* /proc/sys/security */
+enum
+{
+ SECURITY_RANDPID=1, /* Randomize process IDs */
+ SECURITY_RANDID=2, /* Randomize IP packet IDs */
+ SECURITY_RANDISN=3, /* Randomize TCP ISN values */
+ SECURITY_RANDSRC=4, /* Randomize TCP source ports */
+ SECURITY_SYSCTL=6, /* Lockdown value for the others */
+};
+#endif
+
#ifdef __KERNEL__
extern void sysctl_init(void);
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/include/net/inetpeer.h linux-2.6.4-wolk2.4-procrestrict/include/net/inetpeer.h
--- linux-2.6.4-wolk2.4-fullkernel/include/net/inetpeer.h 2004-03-30 19:41:23.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/include/net/inetpeer.h 2004-03-31 03:53:25.000000000 +0200
@@ -35,6 +35,12 @@ void inet_initpeers(void) __init;
/* can be called with or without local BH being disabled */
struct inet_peer *inet_getpeer(__u32 daddr, int create);
+#ifdef CONFIG_SECURITY_NEEDIPRAND
+extern int security_enable_randid;
+extern __u16 ip_randomid(void);
+extern __u32 ip_randomisn(void);
+#endif
+
extern spinlock_t inet_peer_unused_lock;
extern struct inet_peer *inet_peer_unused_head;
extern struct inet_peer **inet_peer_unused_tailp;
@@ -59,7 +65,12 @@ static inline __u16 inet_getid(struct in
__u16 id;
spin_lock_bh(&inet_peer_idlock);
- id = p->ip_id_count;
+#ifdef CONFIG_SECURITY_RANDID
+ if (security_enable_randid)
+ id = ip_randomid();
+ else
+#endif
+ id = p->ip_id_count;
p->ip_id_count += 1 + more;
spin_unlock_bh(&inet_peer_idlock);
return id;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/include/net/ip.h linux-2.6.4-wolk2.4-procrestrict/include/net/ip.h
--- linux-2.6.4-wolk2.4-fullkernel/include/net/ip.h 2004-03-17 19:04:16.000000000 +0100
+++ linux-2.6.4-wolk2.4-procrestrict/include/net/ip.h 2004-03-31 03:53:25.000000000 +0200
@@ -66,6 +66,12 @@ struct ip_ra_chain
void (*destructor)(struct sock *);
};
+#ifdef CONFIG_SECURITY_NEEDIPRAND
+extern int security_enable_randid;
+extern __u16 ip_randomid(void);
+extern __u32 ip_randomisn(void);
+#endif
+
extern struct ip_ra_chain *ip_ra_chain;
extern rwlock_t ip_ra_lock;
@@ -194,6 +200,11 @@ static inline void ip_select_ident(struc
* does not change, they drop every other packet in
* a TCP stream using header compression.
*/
+#ifdef CONFIG_SECURITY_RANDID
+ if (security_enable_randid)
+ iph->id = ip_randomid();
+ else
+#endif
iph->id = (sk && inet_sk(sk)->daddr) ?
htons(inet_sk(sk)->id++) : 0;
} else
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/init/Kconfig linux-2.6.4-wolk2.4-procrestrict/init/Kconfig
--- linux-2.6.4-wolk2.4-fullkernel/init/Kconfig 2004-03-30 20:17:13.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/init/Kconfig 2004-03-31 03:53:25.000000000 +0200
@@ -324,6 +324,7 @@ source "drivers/block/Kconfig.iosched"
config KALLSYMS
bool "Load all symbols for debugging/kksymoops" if EMBEDDED
default y
+ depends on !SECURITY_HIDESYM
help
Say Y here to let the kernel print out symbolic crash information and
symbolic stack backtraces. This increases the size of the kernel
@@ -401,6 +402,7 @@ config ELF_CORE
config PROC_KCORE
depends !ARM
+ depends on !SECURITY_PROC_ADD
default y
bool "Enable /proc/kcore support" if EMBEDDED
help
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/init/main.c linux-2.6.4-wolk2.4-procrestrict/init/main.c
--- linux-2.6.4-wolk2.4-fullkernel/init/main.c 2004-03-30 20:03:28.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/init/main.c 2004-03-31 03:53:25.000000000 +0200
@@ -98,6 +98,10 @@ extern void free_initmem(void);
extern void populate_rootfs(void);
extern void driver_init(void);
+#ifdef CONFIG_SECURITY_MISC
+extern void security_init(void);
+#endif
+
#ifdef CONFIG_TC
extern void tc_init(void);
#endif
@@ -787,6 +791,10 @@ static int init(void * unused)
else
prepare_namespace();
+#ifdef CONFIG_SECURITY_MISC
+ security_init();
+#endif
+
/*
* Ok, we have completed the initial bootup, and
* we're essentially up and running. Get rid of the
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/kernel/configs.c linux-2.6.4-wolk2.4-procrestrict/kernel/configs.c
--- linux-2.6.4-wolk2.4-fullkernel/kernel/configs.c 2004-03-17 17:21:28.000000000 +0100
+++ linux-2.6.4-wolk2.4-procrestrict/kernel/configs.c 2004-03-31 03:53:25.000000000 +0200
@@ -81,8 +81,16 @@ static int __init ikconfig_init(void)
IKCONFIG_VERSION);
/* create the current config file */
+#ifdef CONFIG_SECURITY_PROC_ADD
+#ifdef CONFIG_SECURITY_PROC_USER
+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
+#elif CONFIG_SECURITY_PROC_USERGROUP
+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
+#endif
+#else
entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
&proc_root);
+#endif
if (!entry)
return -ENOMEM;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/kernel/kallsyms.c linux-2.6.4-wolk2.4-procrestrict/kernel/kallsyms.c
--- linux-2.6.4-wolk2.4-fullkernel/kernel/kallsyms.c 2004-03-30 19:40:56.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/kernel/kallsyms.c 2004-03-31 03:53:25.000000000 +0200
@@ -314,7 +314,15 @@ int __init kallsyms_init(void)
{
struct proc_dir_entry *entry;
+#ifdef CONFIG_SECURITY_PROC_ADD
+#ifdef CONFIG_SECURITY_PROC_USER
+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
+#elif CONFIG_SECURITY_PROC_USERGROUP
+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
+#endif
+#else
entry = create_proc_entry("kallsyms", 0444, NULL);
+#endif
if (entry)
entry->proc_fops = &kallsyms_operations;
return 0;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/kernel/pid.c linux-2.6.4-wolk2.4-procrestrict/kernel/pid.c
--- linux-2.6.4-wolk2.4-fullkernel/kernel/pid.c 2004-03-30 19:38:59.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/kernel/pid.c 2004-03-31 03:53:25.000000000 +0200
@@ -26,6 +26,11 @@
#include <linux/bootmem.h>
#include <linux/hash.h>
+#ifdef CONFIG_SECURITY_RANDPID
+#include <linux/random.h>
+extern int security_enable_randpid;
+#endif
+
#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
static struct list_head *pid_hash[PIDTYPE_MAX];
static int pidhash_shift;
@@ -102,6 +107,13 @@ int alloc_pidmap(void)
int pid, offset, max_steps = PIDMAP_ENTRIES + 1;
pidmap_t *map;
+#ifdef CONFIG_SECURITY_RANDPID
+ unsigned int randpid;
+ if (security_enable_randpid && (last_pid >= RESERVED_PIDS)) {
+ get_random_bytes(&randpid,sizeof(randpid));
+ pid = (randpid % (pid_max - RESERVED_PIDS)) + RESERVED_PIDS + 1;
+ } else
+#endif
pid = last_pid + 1;
if (pid >= pid_max)
pid = RESERVED_PIDS;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/kernel/printk.c linux-2.6.4-wolk2.4-procrestrict/kernel/printk.c
--- linux-2.6.4-wolk2.4-fullkernel/kernel/printk.c 2004-03-31 04:33:15.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/kernel/printk.c 2004-03-31 03:53:25.000000000 +0200
@@ -258,6 +258,10 @@ int do_syslog(int type, char __user * bu
char c;
int error = 0;
+#ifdef CONFIG_SECURITY_DMESG
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+#endif
error = security_syslog(type);
if (error)
return error;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/kernel/sysctl.c linux-2.6.4-wolk2.4-procrestrict/kernel/sysctl.c
--- linux-2.6.4-wolk2.4-fullkernel/kernel/sysctl.c 2004-03-30 19:42:32.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/kernel/sysctl.c 2004-03-31 03:53:25.000000000 +0200
@@ -77,6 +77,11 @@ static int ngroups_max = NGROUPS_MAX;
/* renice GID support */
extern int renice_gid;
+/* security */
+#ifdef CONFIG_SECURITY_SYSCTL
+extern int sec_handle_sysctl_mod(const char *dirname, const char *name, const int op);
+#endif
+
#ifdef CONFIG_KMOD
extern char modprobe_path[];
#endif
@@ -150,6 +155,24 @@ extern ctl_table random_table[];
extern ctl_table pty_table[];
#endif
+#ifdef CONFIG_SECURITY_SYSCTL
+static ctl_table security_table[];
+
+extern int security_lock;
+#ifdef CONFIG_SECURITY_RANDPID
+extern int security_enable_randpid;
+#endif
+#ifdef CONFIG_SECURITY_RANDID
+extern int security_enable_randid;
+#endif
+#ifdef CONFIG_SECURITY_RANDISN
+extern int security_enable_randisn;
+#endif
+#ifdef CONFIG_SECURITY_RANDSRC
+extern int security_enable_randsrc;
+#endif
+#endif
+
/* /proc declarations: */
#ifdef CONFIG_PROC_FS
@@ -218,6 +241,14 @@ static ctl_table root_table[] = {
.mode = 0555,
.child = dev_table,
},
+#ifdef CONFIG_SECURITY_SYSCTL
+ {
+ .ctl_name = CTL_SECURITY,
+ .procname = "security",
+ .mode = 0500,
+ .child = security_table,
+ },
+#endif
{ .ctl_name = 0 }
};
@@ -981,6 +1012,63 @@ static ctl_table dev_table[] = {
{ .ctl_name = 0 }
};
+#ifdef CONFIG_SECURITY_SYSCTL
+static ctl_table security_table[] = {
+#ifdef CONFIG_SECURITY_RANDPID
+ {
+ .ctl_name = SECURITY_RANDPID,
+ .procname = "rand_pids",
+ .data = &security_enable_randpid,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
+#ifdef CONFIG_SECURITY_RANDID
+ {
+ .ctl_name = SECURITY_RANDID,
+ .procname = "rand_ip_ids",
+ .data = &security_enable_randid,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
+#ifdef CONFIG_SECURITY_RANDISN
+ {
+ .ctl_name = SECURITY_RANDISN,
+ .procname = "rand_isns",
+ .data = &security_enable_randisn,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
+#ifdef CONFIG_SECURITY_RANDSRC
+ {
+ .ctl_name = SECURITY_RANDSRC,
+ .procname = "rand_tcp_src_ports",
+ .data = &security_enable_randsrc,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
+#ifdef CONFIG_SECURITY_SYSCTL
+ {
+ .ctl_name = SECURITY_SYSCTL,
+ .procname = "security_lock",
+ .data = &security_lock,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
+ { .ctl_name = 0 }
+};
+
+#endif
+
extern void init_irq_proc (void);
void __init sysctl_init(void)
@@ -1054,6 +1142,10 @@ static int test_perm(int mode, int op)
static inline int ctl_perm(ctl_table *table, int op)
{
int error;
+#ifdef CONFIG_SECURITY_SYSCTL
+ if (table->de && sec_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
+ return -EACCES;
+#endif
error = security_sysctl(table, op);
if (error)
return error;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/net/core/Makefile linux-2.6.4-wolk2.4-procrestrict/net/core/Makefile
--- linux-2.6.4-wolk2.4-fullkernel/net/core/Makefile 2004-03-30 19:41:23.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/net/core/Makefile 2004-03-31 03:53:25.000000000 +0200
@@ -2,12 +2,15 @@
# Makefile for the Linux networking core.
#
+rand-$(CONFIG_SECURITY_NEEDIPRAND) := obsd_rand.o
+
obj-y := sock.o skbuff.o iovec.o datagram.o scm.o
obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
obj-y += flow.o dev.o net-sysfs.o dst.o \
- neighbour.o utils.o link_watch.o
+ neighbour.o utils.o link_watch.o \
+ $(rand-y)
obj-$(CONFIG_ETHTOOL) += ethtool.o
obj-$(CONFIG_NETFILTER) += netfilter.o
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/net/core/obsd_rand.c linux-2.6.4-wolk2.4-procrestrict/net/core/obsd_rand.c
--- linux-2.6.4-wolk2.4-fullkernel/net/core/obsd_rand.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.4-wolk2.4-procrestrict/net/core/obsd_rand.c 2004-03-31 03:53:25.000000000 +0200
@@ -0,0 +1,209 @@
+
+/*
+ * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
+ *
+ * Version 1.89, last modified 19-Sep-99
+ *
+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
+ * All rights reserved.
+ *
+ * Copyright 1998 Niels Provos <[email protected]>
+ * All rights reserved.
+ * Theo de Raadt <[email protected]> came up with the idea of using
+ * such a mathematical system to generate more random (yet non-repeating)
+ * ids to solve the resolver/named problem. But Niels designed the
+ * actual system based on the constraints.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Niels Provos.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/smp_lock.h>
+#include <linux/random.h>
+
+#define RU_OUT 180
+#define RU_MAX 30000
+#define RU_GEN 2
+#define RU_N 32749
+#define RU_AGEN 7
+#define RU_M 31104
+#define PFAC_N 3
+const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
+
+static __u16 ru_x;
+static __u16 ru_seed, ru_seed2;
+static __u16 ru_a, ru_b;
+static __u16 ru_g;
+static __u16 ru_counter = 0;
+static __u16 ru_msb = 0;
+static unsigned long ru_reseed = 0;
+
+#define TCP_RNDISS_ROUNDS 15
+#define TCP_RNDISS_OUT 7200
+#define TCP_RNDISS_MAX 30000
+
+static __u8 tcp_rndiss_sbox[NR_CPUS][128];
+static __u16 tcp_rndiss_msb[NR_CPUS];
+static __u16 tcp_rndiss_cnt[NR_CPUS];
+static unsigned long tcp_rndiss_reseed[NR_CPUS];
+
+static __u16 pmod(__u16, __u16, __u16);
+static void ip_initid(void);
+__u16 ip_randomid(void);
+
+static __u16
+pmod(__u16 gen, __u16 exp, __u16 mod)
+{
+ __u16 s, t, u;
+
+ s = 1;
+ t = gen;
+ u = exp;
+
+ while (u) {
+ if (u & 1)
+ s = (s * t) % mod;
+ u >>= 1;
+ t = (t * t) % mod;
+ }
+ return (s);
+}
+
+static void
+ip_initid(void)
+{
+ __u32 tmp;
+ int noprime = 1;
+ __u16 j, i;
+
+ get_random_bytes(&tmp,4);
+ ru_x = (tmp & 0xFFFF) % RU_M;
+
+ get_random_bytes(&tmp,4);
+ ru_seed = (tmp >> 16) & 0x7FFF;
+ ru_seed2 = tmp & 0x7FFF;
+
+ get_random_bytes(&tmp,4);
+ ru_b = (tmp & 0xfffe) | 1;
+ ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
+ while (ru_b % 3 == 0)
+ ru_b += 2;
+
+ get_random_bytes(&tmp,4);
+ j = tmp % RU_N;
+ tmp = tmp >> 16;
+
+ while (noprime) {
+ for (i = 0; i < PFAC_N; i++)
+ if (j % pfacts[i] == 0)
+ break;
+
+ if (i >= PFAC_N)
+ noprime = 0;
+ else
+ j = (j + 1) % RU_N;
+ }
+
+ ru_g = pmod(RU_GEN, j, RU_N);
+ ru_counter = 0;
+
+ ru_reseed = xtime.tv_sec + RU_OUT;
+ ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
+}
+
+__u16
+ip_randomid(void)
+{
+ int i, n;
+ __u32 tmp;
+
+ if (ru_counter >= RU_MAX || time_after((unsigned long) xtime.tv_sec, ru_reseed))
+ ip_initid();
+
+ if (!tmp)
+ get_random_bytes(&tmp,4);
+
+ n = tmp & 0x3;
+ tmp = tmp >> 2;
+ if (ru_counter + n >= RU_MAX)
+ ip_initid();
+ for (i = 0; i <= n; i++)
+ ru_x = (ru_a * ru_x + ru_b) % RU_M;
+ ru_counter += i;
+
+ return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
+}
+
+__u16
+tcp_rndiss_encrypt(__u16 val)
+{
+ __u16 sum = 0, i;
+ int cpu = smp_processor_id();
+
+ for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
+ sum += 0x79b9;
+ val ^= ((__u16) tcp_rndiss_sbox[cpu][(val ^ sum) ^ 0x7f]) << 7;
+ val = ((val & 0xff) << 7) | (val >> 8);
+ }
+
+ return val;
+}
+
+static void
+tcp_rndiss_init(void)
+{
+ int cpu = smp_processor_id();
+
+ get_random_bytes(tcp_rndiss_sbox[cpu], sizeof (tcp_rndiss_sbox[0]));
+ tcp_rndiss_reseed[cpu] = xtime.tv_sec + TCP_RNDISS_OUT;
+ tcp_rndiss_msb[cpu] = tcp_rndiss_msb[cpu] == 0x8000 ? 0 : 0x8000;
+ tcp_rndiss_cnt[cpu] = 0;
+}
+
+__u32
+ip_randomisn(void)
+{
+ __u32 tmp;
+ int cpu = smp_processor_id();
+
+ if (tcp_rndiss_cnt[cpu] >= TCP_RNDISS_MAX ||
+ time_after((unsigned long) xtime.tv_sec, tcp_rndiss_reseed[cpu]))
+ tcp_rndiss_init();
+
+ get_random_bytes(&tmp,4);
+ return (((tcp_rndiss_encrypt(tcp_rndiss_cnt[cpu]++) |
+ tcp_rndiss_msb[cpu]) << 16) | (tmp & 0x7fff));
+}
+
+/*
+#ifdef CONFIG_SECURITY_RANDID
+#ifdef CONFIG_MODULES
+EXPORT_SYMBOL(ip_randomid);
+#endif
+#endif
+*/
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/net/ipv4/af_inet.c linux-2.6.4-wolk2.4-procrestrict/net/ipv4/af_inet.c
--- linux-2.6.4-wolk2.4-fullkernel/net/ipv4/af_inet.c 2004-03-30 19:41:23.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/net/ipv4/af_inet.c 2004-03-31 03:53:25.000000000 +0200
@@ -385,6 +385,11 @@ static int inet_create(struct socket *so
else
inet->pmtudisc = IP_PMTUDISC_WANT;
+#ifdef CONFIG_SECURITY_RANDID
+ if (security_enable_randid)
+ inet->id = htons(ip_randomid());
+ else
+#endif
inet->id = 0;
sock_init_data(sock, sk);
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/net/ipv4/ip_output.c linux-2.6.4-wolk2.4-procrestrict/net/ipv4/ip_output.c
--- linux-2.6.4-wolk2.4-fullkernel/net/ipv4/ip_output.c 2004-03-30 19:41:02.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/net/ipv4/ip_output.c 2004-03-31 03:53:25.000000000 +0200
@@ -1164,6 +1164,12 @@ int ip_push_pending_frames(struct sock *
if (!df) {
__ip_select_ident(iph, &rt->u.dst, 0);
} else {
+#ifdef CONFIG_SECURITY_RANDID
+ if (security_enable_randid) {
+ iph->id = ip_randomid();
+ inet->id = ip_randomid();
+ } else
+#endif
iph->id = htons(inet->id++);
}
iph->ttl = ttl;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/net/ipv4/tcp_ipv4.c linux-2.6.4-wolk2.4-procrestrict/net/ipv4/tcp_ipv4.c
--- linux-2.6.4-wolk2.4-fullkernel/net/ipv4/tcp_ipv4.c 2004-03-30 19:40:56.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/net/ipv4/tcp_ipv4.c 2004-03-31 03:53:25.000000000 +0200
@@ -95,6 +95,17 @@ int sysctl_tcp_restrict = 0;
/* Socket used for sending RSTs */
static struct socket *tcp_socket;
+/* Various security enhancements */
+#ifdef CONFIG_SECURITY_RANDSRC
+extern int security_enable_randsrc;
+#endif
+#ifdef CONFIG_SECURITY_RANDISN
+extern int security_enable_randisn;
+#endif
+#ifdef CONFIG_SECURITY_RANDID
+extern int security_enable_randid;
+#endif
+
void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
struct sk_buff *skb);
@@ -234,9 +245,18 @@ static int tcp_v4_get_port(struct sock *
spin_lock(&tcp_portalloc_lock);
rover = tcp_port_rover;
do {
+#ifdef CONFIG_SECURITY_RANDSRC
+ if (security_enable_randsrc && (high > low)) {
+ int randport;
+ get_random_bytes(&randport,sizeof(randport));
+ rover = low + (randport % (high - low));
+ } else
+#endif
+ {
rover++;
if (rover < low || rover > high)
rover = low;
+ }
head = &tcp_bhash[tcp_bhashfn(rover)];
spin_lock(&head->lock);
tb_for_each(tb, node, &head->chain)
@@ -547,6 +567,11 @@ inline struct sock *tcp_v4_lookup(u32 sa
static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
{
+#ifdef CONFIG_SECURITY_RANDISN
+ if (likely(security_enable_randisn))
+ return ip_randomisn();
+ else
+#endif
return secure_tcp_sequence_number(skb->nh.iph->daddr,
skb->nh.iph->saddr,
skb->h.th->dest,
@@ -681,9 +706,18 @@ static int tcp_v4_hash_connect(struct so
rover = tcp_port_rover;
do {
+#ifdef CONFIG_SECURITY_RANDSRC
+ if (security_enable_randsrc && (high > low)) {
+ int randport;
+ get_random_bytes(&randport,sizeof(randport));
+ rover = low + (randport % (high - low));
+ } else
+#endif
+ {
rover++;
if ((rover < low) || (rover > high))
rover = low;
+ }
head = &tcp_bhash[tcp_bhashfn(rover)];
spin_lock(&head->lock);
@@ -853,12 +887,23 @@ int tcp_v4_connect(struct sock *sk, stru
tcp_v4_setup_caps(sk, &rt->u.dst);
tp->ext2_header_len = rt->u.dst.header_len;
- if (!tp->write_seq)
+ if (!tp->write_seq) {
+#ifdef CONFIG_SECURITY_RANDISN
+ if (likely(security_enable_randisn))
+ tp->write_seq = ip_randomisn();
+ else
+#endif
tp->write_seq = secure_tcp_sequence_number(inet->saddr,
inet->daddr,
inet->sport,
usin->sin_port);
+ }
+#ifdef CONFIG_SECURITY_RANDID
+ if (security_enable_randid)
+ inet->id = ip_randomid();
+ else
+#endif
inet->id = tp->write_seq ^ jiffies;
err = tcp_connect(sk);
@@ -1608,6 +1653,11 @@ struct sock *tcp_v4_syn_recv_sock(struct
if (newinet->opt)
newtp->ext_header_len = newinet->opt->optlen;
newtp->ext2_header_len = dst->header_len;
+#ifdef CONFIG_SECURITY_RANDID
+ if (security_enable_randid)
+ newinet->id = ip_randomid();
+ else
+#endif
newinet->id = newtp->write_seq ^ jiffies;
tcp_sync_mss(newsk, dst_pmtu(dst));
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/net/ipv4/udp.c linux-2.6.4-wolk2.4-procrestrict/net/ipv4/udp.c
--- linux-2.6.4-wolk2.4-fullkernel/net/ipv4/udp.c 2004-03-30 19:41:09.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/net/ipv4/udp.c 2004-03-31 03:53:25.000000000 +0200
@@ -959,6 +959,11 @@ int udp_connect(struct sock *sk, struct
inet->daddr = rt->rt_dst;
inet->dport = usin->sin_port;
sk->sk_state = TCP_ESTABLISHED;
+#ifdef CONFIG_SECURITY_RANDID
+ if (security_enable_randid)
+ inet->id = ip_randomid();
+ else
+#endif
inet->id = jiffies;
sk_dst_set(sk, &rt->u.dst);
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/net/socket.c linux-2.6.4-wolk2.4-procrestrict/net/socket.c
--- linux-2.6.4-wolk2.4-fullkernel/net/socket.c 2004-03-30 19:40:54.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/net/socket.c 2004-03-31 03:53:25.000000000 +0200
@@ -82,6 +82,8 @@
#include <linux/syscalls.h>
#include <linux/compat.h>
#include <linux/kmod.h>
+#include <linux/in.h>
+#include <linux/ip.h>
#ifdef CONFIG_NET_RADIO
#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
@@ -268,6 +270,16 @@ int move_addr_to_user(void *kaddr, int k
return __put_user(klen, ulen);
}
+#ifdef CONFIG_SECURITY_PROC_IPADDR
+void sec_attach_curr_ip(const struct sock *sk)
+{
+ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
+ return;
+ current->curr_ip = inet_sk(sk)->daddr;
+ return;
+}
+#endif
+
#define SOCKFS_MAGIC 0x534F434B
static kmem_cache_t * sock_inode_cachep;
@@ -1309,6 +1321,10 @@ asmlinkage long sys_accept(int fd, struc
security_socket_post_accept(sock, newsock);
+#ifdef CONFIG_SECURITY_PROC_IPADDR
+ sec_attach_curr_ip(newsock->sk);
+#endif
+
out_put:
sockfd_put(sock);
out:
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/net/unix/af_unix.c linux-2.6.4-wolk2.4-procrestrict/net/unix/af_unix.c
--- linux-2.6.4-wolk2.4-fullkernel/net/unix/af_unix.c 2004-03-30 19:40:59.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/net/unix/af_unix.c 2004-03-31 04:04:51.000000000 +0200
@@ -1088,6 +1088,14 @@ restart:
/* Set credentials */
sk->sk_peercred = other->sk_peercred;
+#ifdef CONFIG_SECURITY_PROC_IPADDR
+ struct pid *pid = find_pid(PIDTYPE_PID, other->sk_peercred.pid);
+
+ if (pid) {
+ pid->task->curr_ip = current->curr_ip;
+ }
+#endif
+
sock_hold(newsk);
unix_peer(sk) = newsk;
sock->state = SS_CONNECTED;
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/security/Kconfig linux-2.6.4-wolk2.4-procrestrict/security/Kconfig
--- linux-2.6.4-wolk2.4-fullkernel/security/Kconfig 2004-03-31 04:33:15.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/security/Kconfig 2004-03-31 03:53:25.000000000 +0200
@@ -4,6 +4,8 @@
menu "Security options"
+source "security/Kconfig.misc"
+
config NOPROMISC
bool "Deny promiscuous mode for interfaces"
default n
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/security/Kconfig.misc linux-2.6.4-wolk2.4-procrestrict/security/Kconfig.misc
--- linux-2.6.4-wolk2.4-fullkernel/security/Kconfig.misc 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.4-wolk2.4-procrestrict/security/Kconfig.misc 2004-03-31 06:12:52.000000000 +0200
@@ -0,0 +1,259 @@
+#
+# Miscellaneous security configuration
+#
+
+menu "Miscellaneous security features"
+
+config SECURITY_MISC
+ bool "Miscellaneous security features"
+ help
+ If you say Y here, you will be able to configure many features
+ that will enhance the security of your system. It is highly
+ recommended that you say Y here and read through the help
+ for each option so that you fully understand the features and
+ can evaluate their usefulness for your machine.
+
+menu "Address Space Protection"
+depends on SECURITY_MISC
+
+config SECURITY_KMEM
+ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
+ help
+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
+ be written to via mmap or otherwise to modify the running kernel.
+ /dev/port will also not be allowed to be opened. If you have module
+ support disabled, enabling this will close up four ways that are
+ currently used to insert malicious code into the running kernel.
+ Even with all these features enabled, we still highly recommend that
+ you use the ACL system, as it is still possible for an attacker to
+ modify the running kernel through privileged I/O granted by ioperm/iopl.
+ If you are not using XFree86, you may be able to stop this additional
+ case by enabling the 'Disable privileged I/O' option. Though nothing
+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
+ but only to video memory, which is the only writing we allow in this
+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
+ not be allowed to mprotect it with PROT_WRITE later.
+ Enabling this feature could make certain apps like VMWare stop working,
+ as they need to write to other locations in /dev/mem.
+ It is highly recommended that you say Y here if you meet all the
+ conditions above.
+
+config SECURITY_IO
+ bool "Disable privileged I/O"
+ depends on X86
+ select RTC
+ help
+ If you say Y here, all ioperm and iopl calls will return an error.
+ Ioperm and iopl can be used to modify the running kernel.
+ Unfortunately, some programs need this access to operate properly,
+ the most notable of which are XFree86 and hwclock. hwclock can be
+ remedied by having RTC support in the kernel, so CONFIG_RTC is
+ enabled if this option is enabled, to ensure that hwclock operates
+ correctly. XFree86 still will not operate correctly with this option
+ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
+ and you still want to protect your kernel against modification,
+ use the ACL system.
+
+config SECURITY_HIDESYM
+ bool "Hide kernel symbols"
+ help
+ If you say Y here, getting information on loaded modules, and
+ displaying all kernel symbols through a syscall will be restricted
+ to users with CAP_SYS_MODULE. This option is only effective
+ provided the following conditions are met:
+ 1) The kernel using misc security is not precompiled by some distribution
+ 2) You are using the ACL system and hiding other files such as your
+ kernel image and System.map
+ 3) You have the additional /proc restrictions enabled, which removes
+ /proc/kcore
+ If the above conditions are met, this option will aid to provide a
+ useful protection against local and remote kernel exploitation of
+ overflows and arbitrary read/write vulnerabilities.
+endmenu
+
+menu "Filesystem Protections"
+depends on SECURITY_MISC
+
+config SECURITY_PROC
+ bool "Proc restrictions"
+ help
+ If you say Y here, the permissions of the /proc filesystem
+ will be altered to enhance system security and privacy. Depending
+ upon the options you choose, you can either restrict users to see
+ only the processes they themselves run, or choose a group that can
+ view all processes and files normally restricted to root if you choose
+ the "restrict to user only" option. NOTE: If you're running identd as
+ a non-root user, you will have to run it as the group you specify here.
+
+config SECURITY_PROC_USER
+ bool "Restrict /proc to user only"
+ depends on SECURITY_PROC
+ help
+ If you say Y here, non-root users will only be able to view their own
+ processes, and restricts them from viewing network-related information,
+ and viewing kernel symbol and module information.
+
+config SECURITY_PROC_USERGROUP
+ bool "Allow special group"
+ depends on SECURITY_PROC && !SECURITY_PROC_USER
+ help
+ If you say Y here, you will be able to select a group that will be
+ able to view all processes, network-related information, and
+ kernel and symbol information. This option is useful if you want
+ to run identd as a non-root user.
+
+config SECURITY_PROC_GID
+ int "GID for special group"
+ depends on SECURITY_PROC_USERGROUP
+ default 1001
+
+config SECURITY_PROC_ADD
+ bool "Additional restrictions"
+ depends on SECURITY_PROC_USER || SECURITY_PROC_USERGROUP
+ help
+ If you say Y here, additional restrictions will be placed on
+ /proc that keep normal users from viewing cpu and device information.
+
+config SECURITY_PROC_ADD_MORE
+ bool "Even more additional restrictions"
+ depends on SECURITY_PROC_ADD && (SECURITY_PROC_USER || SECURITY_PROC_USERGROUP)
+ help
+ If you say Y here, even more additional restrictions will be placed on
+ /proc that keep normal users from viewing the following things:
+ - partitions
+ - interrupts
+ - kmalloc
+ - sleep
+ - buddyinfo
+ - vmstat
+ - zoneinfo
+ - diskstats
+ - mtrr
+
+config SECURITY_LINK
+ bool "Linking restrictions"
+ help
+ If you say Y here, /tmp race exploits will be prevented, since users
+ will no longer be able to follow symlinks owned by other users in
+ world-writable +t directories (i.e. /tmp), unless the owner of the
+ symlink is the owner of the directory. users will also not be
+ able to hardlink to files they do not own. If the sysctl option is
+ enabled, a sysctl option with name "linking_restrictions" is created.
+
+config SECURITY_FIFO
+ bool "FIFO restrictions"
+ help
+ If you say Y here, users will not be able to write to FIFOs they don't
+ own in world-writable +t directories (i.e. /tmp), unless the owner of
+ the FIFO is the same owner of the directory it's held in. If the sysctl
+ option is enabled, a sysctl option with name "fifo_restrictions" is
+ created.
+
+config SECURITY_PROC_IPADDR
+ bool "/proc/<pid>/ipaddr support"
+ help
+ If you say Y here, a new entry will be added to each /proc/<pid>
+ directory that contains the IP address of the person using the task.
+ The IP is carried across local TCP and AF_UNIX stream sockets.
+ This information can be useful for IDS/IPSes to perform remote response
+ to a local attack. The entry is readable by only the owner of the
+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
+ the RBAC system), and thus does not create privacy concerns.
+endmenu
+
+menu "Executable Protections"
+depends on SECURITY_MISC
+
+config SECURITY_DMESG
+ bool "Dmesg(8) restriction"
+ help
+ If you say Y here, non-root users will not be able to use dmesg(8)
+ to view up to the last 4kb of messages in the kernel's log buffer.
+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
+ created.
+
+config SECURITY_RANDPID
+ bool "Randomized PIDs"
+ help
+ If you say Y here, all PIDs created on the system will be
+ pseudo-randomly generated. This is extremely effective along
+ with the /proc restrictions to disallow an attacker from guessing
+ pids of daemons, etc. PIDs are also used in some cases as part
+ of a naming system for temporary files, so this option would keep
+ those filenames from being predicted as well. We also use code
+ to make sure that PID numbers aren't reused too soon. If the sysctl
+ option is enabled, a sysctl option with name "rand_pids" is created.
+endmenu
+
+menu "Network Protections"
+depends on SECURITY_MISC
+
+config SECURITY_RANDNET
+ bool "Larget entropy pools"
+ help
+ If you say Y here, the entropy pools used for many features of Linux
+ and misc security will be doubled in size. Since several security
+ features use additional randomness, it is recommended that you say Y
+ here.
+
+config SECURITY_RANDISN
+ bool "Truly random TCP ISN selection"
+ help
+ If you say Y here, Linux's default selection of TCP Initial Sequence
+ Numbers (ISNs) will be replaced with that of OpenBSD. Linux uses
+ an MD4 hash based on the connection plus a time value to create the
+ ISN, while OpenBSD's selection is random. If the sysctl option is
+ enabled, a sysctl option with name "rand_isns" is created.
+
+config SECURITY_RANDID
+ bool "Randomized IP IDs"
+ help
+ If you say Y here, all the id field on all outgoing packets
+ will be randomized. This hinders os fingerprinters and
+ keeps your machine from being used as a bounce for an untraceable
+ portscan. Ids are used for fragmented packets, fragments belonging
+ to the same packet have the same id. By default linux only
+ increments the id value on each packet sent to an individual host.
+ We use a port of the OpenBSD random ip id code to achieve the
+ randomness, while keeping the possibility of id duplicates to
+ near none. If the sysctl option is enabled, a sysctl option with name
+ "rand_ip_ids" is created.
+
+config SECURITY_RANDSRC
+ bool "Randomized TCP source ports"
+ default n
+ help
+ If you say Y here, situations where a source port is generated on the
+ fly for the TCP protocol (ie. with connect() ) will be altered so that
+ the source port is generated at random, instead of a simple incrementing
+ algorithm. If the sysctl option is enabled, a sysctl option with name
+ "rand_tcp_src_ports" is created.
+endmenu
+
+menu "Sysctl support"
+depends on SECURITY_MISC && SYSCTL
+
+config SECURITY_SYSCTL
+ bool "Sysctl support"
+ help
+ If you say Y here, you will be able to change the options that you
+ run with at bootup, without having to recompile your kernel. You can
+ echo values to files in /proc/sys/security to enable (1) or disable (0)
+ various features. All the sysctl entries are mutable until the
+ "security_lock" entry is set to a non-zero value.
+ All features are disabled by default. Please note that this option could
+ reduce the effectiveness of the added security of this patch if an ACL
+ system is not put in place. Your init scripts should be read-only, and
+ root should not have access to adding modules or performing raw i/o
+ operations. All options should be set at startup, and the security_lock
+ entry should be set to a non-zero value after all the options are set.
+ *THIS IS EXTREMELY IMPORTANT*
+endmenu
+
+config SECURITY_NEEDIPRAND
+ def_bool SECURITY_RANDID || SECURITY_RANDISN || SECURITY_RANDSRC
+
+config SECURITY_MISC
+ def_bool SECURITY_NEEDIPRAND || SECURITY_RANDPID || SECURITY_SYSCTL
+
+endmenu
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/security/Makefile linux-2.6.4-wolk2.4-procrestrict/security/Makefile
--- linux-2.6.4-wolk2.4-fullkernel/security/Makefile 2004-03-30 19:40:59.000000000 +0200
+++ linux-2.6.4-wolk2.4-procrestrict/security/Makefile 2004-03-31 03:53:25.000000000 +0200
@@ -19,3 +19,4 @@ obj-$(CONFIG_SECURITY_ROOTPLUG) += comm
ifeq ($(CONFIG_LIDS),y)
obj-$(CONFIG_LIDS) += lids/built-in.o
endif
+obj-$(CONFIG_SECURITY_MISC) += misc_init.o
diff -Naurp linux-2.6.4-wolk2.4-fullkernel/security/misc_init.c linux-2.6.4-wolk2.4-procrestrict/security/misc_init.c
--- linux-2.6.4-wolk2.4-fullkernel/security/misc_init.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.4-wolk2.4-procrestrict/security/misc_init.c 2004-03-31 03:53:25.000000000 +0200
@@ -0,0 +1,76 @@
+/*
+ * Miscellaneous security features
+ *
+ * Copyright (C) 2004 Valdis Kletnieks <[email protected]>
+ *
+ * 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.
+ *
+ * This code is based on the 'grsecurity' patch for the 2.4 kernel
+ * available from http://www.grsecurity.net
+ */
+
+ /*
+ * Err, Valdis, you were on drugs while coding this weren't you? :p (mcp)
+ *
+ * Now actually all works the right way after I fixed lots of stuff up!
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+int security_enable_randpid;
+int security_enable_randid;
+extern int ip_randomid;
+int security_enable_randisn;
+int security_enable_randsrc;
+int security_lock;
+
+#ifdef CONFIG_SECURITY_SYSCTL
+int sec_handle_sysctl_mod(const char *dirname, const char *name, const int op)
+{
+ if (!strcmp(dirname, "security") && security_lock && (op & 002)) {
+ return -EACCES;
+ }
+
+ return 0;
+}
+#endif
+
+void security_init(void)
+{
+#ifndef CONFIG_SECURITY_SYSCTL
+ security_lock = 1;
+
+#ifdef CONFIG_SECURITY_RANDPID
+security_enable_randpid = 1;
+#endif
+
+#ifdef CONFIG_SECURITY_RANDID
+security_enable_randid = 1;
+#ifdef CONFIG_MODULES
+EXPORT_SYMBOL(security_enable_randid);
+#endif
+#endif
+
+#ifdef CONFIG_SECURITY_RANDID
+extern int ip_randomid(void);
+#ifdef CONFIG_MODULES
+EXPORT_SYMBOL(ip_randomid);
+#endif
+#endif
+
+#ifdef CONFIG_SECURITY_RANDISN
+security_enable_randisn = 1;
+#endif
+
+#ifdef CONFIG_SECURITY_RANDSRC
+security_enable_randsrc = 1;
+#endif
+
+#endif /* CONFIG_SECURITY_SYSCTL */
+
+ return;
+}