rpms/kernel/devel config-generic, 1.39, 1.40 linux-2.6-devmem.patch, 1.20, 1.21
Dave Jones (davej)
fedora-extras-commits at redhat.com
Thu Nov 15 19:22:36 UTC 2007
Author: davej
Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv23134
Modified Files:
config-generic linux-2.6-devmem.patch
Log Message:
clean up the restricted devmem patch a little
Index: config-generic
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-generic,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- config-generic 15 Nov 2007 18:02:03 -0000 1.39
+++ config-generic 15 Nov 2007 19:22:02 -0000 1.40
@@ -3362,3 +3362,6 @@
# CONFIG_SAMPLES is not set
+# CONFIG_WRITABLE_DEVMEM is not set
+# CONFIG_WRITABLE_DEVKMEM is not set
+
linux-2.6-devmem.patch:
Index: linux-2.6-devmem.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-devmem.patch,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- linux-2.6-devmem.patch 22 Oct 2007 05:46:46 -0000 1.20
+++ linux-2.6-devmem.patch 15 Nov 2007 19:22:02 -0000 1.21
@@ -1,3 +1,11 @@
+
+Restrict the abilities of /dev/mem and /dev/kmem
+Make them read-only, and also restrict which areas of
+memory can be read.
+
+Original by Arjan van de Ven
+Signed-off-by: Dave Jones <davej at redhat.com>
+
Index: linux-2.6/arch/i386/mm/init.c
===================================================================
--- linux-2.6.orig/arch/x86/mm/init_32.c
@@ -18,11 +26,11 @@
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
-+ if (pagenr <= 256)
-+ return 1;
-+ if (!page_is_ram(pagenr))
-+ return 1;
-+ return 0;
++ if (pagenr <= 256)
++ return 1;
++ if (!page_is_ram(pagenr))
++ return 1;
++ return 0;
+}
+
#ifdef CONFIG_HIGHMEM
@@ -32,14 +40,13 @@
===================================================================
--- linux-2.6.orig/arch/ia64/mm/init.c
+++ linux-2.6/arch/ia64/mm/init.c
-@@ -263,6 +263,13 @@ free_initrd_mem (unsigned long start, un
+@@ -263,6 +263,12 @@ free_initrd_mem (unsigned long start, un
}
}
+int page_is_ram(unsigned long pagenr)
+{
+ //FIXME: implement w/efi walk
-+ printk("page is ram is called!!!!!\n");
+ return 1;
+}
+
@@ -84,7 +91,7 @@
free_area_init_nodes(max_zone_pfns);
}
-+int page_is_ram (unsigned long pagenr)
++int page_is_ram(unsigned long pagenr)
+{
+ return pagenr < max_mapnr;
+}
@@ -100,7 +107,7 @@
__flush_tlb_all();
}
-+static int page_is_ram (unsigned long pagenr)
++static int page_is_ram(unsigned long pagenr)
+{
+ int i;
+
@@ -134,10 +141,10 @@
+ * valid. The argument is a physical page number.
+ *
+ *
-+ * On x86-64, access has to be given to the first megabyte of ram because that area
++ * On x86-64, access has to be given to the first 1MB of ram because that area
+ * contains bios code and data regions used by X and dosemu and similar apps.
-+ * Access has to be given to non-kernel-ram areas as well, these contain the PCI
-+ * mmio resources as well as potential bios/acpi data regions.
++ * Access has to be given to non-kernel-ram areas as well, these contain the
++ * PCI MMIO resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
@@ -152,202 +159,6 @@
static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
kcore_vsyscall;
-Index: linux-2.6/drivers/char/mem.c
-===================================================================
---- linux-2.6.orig/drivers/char/mem.c
-+++ linux-2.6/drivers/char/mem.c
-@@ -102,6 +102,22 @@ static inline int valid_mmap_phys_addr_r
- }
- #endif
-
-+static inline int range_is_allowed(unsigned long from, unsigned long to)
-+{
-+ unsigned long cursor;
-+
-+ cursor = from >> PAGE_SHIFT;
-+ while ((cursor << PAGE_SHIFT) < to) {
-+ if (!devmem_is_allowed(cursor)) {
-+ printk ("Program %s tried to read /dev/mem between %lx->%lx.\n",
-+ current->comm, from, to);
-+ return 0;
-+ }
-+ cursor++;
-+ }
-+ return 1;
-+}
-+
- /*
- * This funcion reads the *physical* memory. The f_pos points directly to the
- * memory location.
-@@ -151,6 +167,8 @@ static ssize_t read_mem(struct file * fi
- */
- ptr = xlate_dev_mem_ptr(p);
-
-+ if (!range_is_allowed(p, p+count))
-+ return -EPERM;
- if (copy_to_user(buf, ptr, sz))
- return -EFAULT;
- buf += sz;
-@@ -208,6 +226,8 @@ static ssize_t write_mem(struct file * f
- */
- ptr = xlate_dev_mem_ptr(p);
-
-+ if (!range_is_allowed(ptr, ptr+sz))
-+ return -EPERM;
- copied = copy_from_user(ptr, buf, sz);
- if (copied) {
- written += sz - copied;
-@@ -357,6 +377,8 @@ static ssize_t read_kmem(struct file *fi
- ssize_t low_count, read, sz;
- char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
-
-+ return -EPERM;
-+
- read = 0;
- if (p < (unsigned long) high_memory) {
- low_count = count;
-@@ -454,125 +454,6 @@ static ssize_t read_kmem(struct file *fi
- }
-
-
--static inline ssize_t
--do_write_kmem(void *p, unsigned long realp, const char __user * buf,
-- size_t count, loff_t *ppos)
--{
-- ssize_t written, sz;
-- unsigned long copied;
--
-- written = 0;
--#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
-- /* we don't have page 0 mapped on sparc and m68k.. */
-- if (realp < PAGE_SIZE) {
-- unsigned long sz = PAGE_SIZE - realp;
-- if (sz > count)
-- sz = count;
-- /* Hmm. Do something? */
-- buf += sz;
-- p += sz;
-- realp += sz;
-- count -= sz;
-- written += sz;
-- }
--#endif
--
-- while (count > 0) {
-- char *ptr;
-- /*
-- * Handle first page in case it's not aligned
-- */
-- if (-realp & (PAGE_SIZE - 1))
-- sz = -realp & (PAGE_SIZE - 1);
-- else
-- sz = PAGE_SIZE;
--
-- sz = min_t(unsigned long, sz, count);
--
-- /*
-- * On ia64 if a page has been mapped somewhere as
-- * uncached, then it must also be accessed uncached
-- * by the kernel or data corruption may occur
-- */
-- ptr = xlate_dev_kmem_ptr(p);
--
-- copied = copy_from_user(ptr, buf, sz);
-- if (copied) {
-- written += sz - copied;
-- if (written)
-- break;
-- return -EFAULT;
-- }
-- buf += sz;
-- p += sz;
-- realp += sz;
-- count -= sz;
-- written += sz;
-- }
--
-- *ppos += written;
-- return written;
--}
--
--
--/*
-- * This function writes to the *virtual* memory as seen by the kernel.
-- */
--static ssize_t write_kmem(struct file * file, const char __user * buf,
-- size_t count, loff_t *ppos)
--{
-- unsigned long p = *ppos;
-- ssize_t wrote = 0;
-- ssize_t virtr = 0;
-- ssize_t written;
-- char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
--
-- if (p < (unsigned long) high_memory) {
--
-- wrote = count;
-- if (count > (unsigned long) high_memory - p)
-- wrote = (unsigned long) high_memory - p;
--
-- written = do_write_kmem((void*)p, p, buf, wrote, ppos);
-- if (written != wrote)
-- return written;
-- wrote = written;
-- p += wrote;
-- buf += wrote;
-- count -= wrote;
-- }
--
-- if (count > 0) {
-- kbuf = (char *)__get_free_page(GFP_KERNEL);
-- if (!kbuf)
-- return wrote ? wrote : -ENOMEM;
-- while (count > 0) {
-- int len = count;
--
-- if (len > PAGE_SIZE)
-- len = PAGE_SIZE;
-- if (len) {
-- written = copy_from_user(kbuf, buf, len);
-- if (written) {
-- if (wrote + virtr)
-- break;
-- free_page((unsigned long)kbuf);
-- return -EFAULT;
-- }
-- }
-- len = vwrite(kbuf, (char *)p, len);
-- count -= len;
-- buf += len;
-- virtr += len;
-- p += len;
-- }
-- free_page((unsigned long)kbuf);
-- }
--
-- *ppos = p;
-- return virtr + wrote;
--}
--
- #ifdef CONFIG_DEVPORT
- static ssize_t read_port(struct file * file, char __user * buf,
- size_t count, loff_t *ppos)
-@@ -818,7 +720,6 @@ static const struct file_operations mem_
- static const struct file_operations kmem_fops = {
- .llseek = memory_lseek,
- .read = read_kmem,
-- .write = write_kmem,
- .mmap = mmap_kmem,
- .open = open_kmem,
- .get_unmapped_area = get_unmapped_area_mem,
-@@ -859,7 +859,6 @@ static const struct {
- const struct file_operations *fops;
- } devlist[] = { /* list of minor devices */
- {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
-- {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
- {3, "null", S_IRUGO | S_IWUGO, &null_fops},
- #ifdef CONFIG_DEVPORT
- {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
Index: linux-2.6/fs/proc/kcore.c
===================================================================
--- linux-2.6.orig/fs/proc/kcore.c
@@ -620,7 +431,7 @@
#define CORE_STR "CORE"
-
-+unsigned int allow_kcore_access = 0;
++unsigned int allow_kcore_access;
static int open_kcore(struct inode * inode, struct file * filp)
{
- return -EPERM;
@@ -647,3 +458,125 @@
total_mem = get_total_mem();
ret = parse_crashkernel(boot_command_line, total_mem,
+--- linux-2.6.23.noarch/drivers/char/Kconfig~ 2007-11-15 14:10:18.000000000 -0500
++++ linux-2.6.23.noarch/drivers/char/Kconfig 2007-11-15 14:10:40.000000000 -0500
+@@ -1062,6 +1062,20 @@ config DEVPORT
+ depends on ISA || PCI
+ default y
+
++config WRITABLE_DEVMEM
++ bool "Allow writing to /dev/mem"
++ help
++ Very little software actually requires a writable /dev/mem
++ Disabling this feature will close off a potential attack
++ vector for kernel rootkits.
++
++config WRITABLE_DEVKMEM
++ bool "Allow writing to /dev/kmem"
++ help
++ Very little software actually requires a writable /dev/kmem
++ Disabling this feature will close off a potential attack
++ vector for kernel rootkits.
++
+ source "drivers/s390/char/Kconfig"
+
+ endmenu
+--- vanilla/drivers/char/mem.c 2007-11-15 14:15:27.000000000 -0500
++++ linux-2.6.23.noarch/drivers/char/mem.c 2007-11-15 14:13:54.000000000 -0500
+@@ -108,6 +108,23 @@ static inline int valid_mmap_phys_addr_r
+ }
+ #endif
+
++static inline int range_is_allowed(unsigned long from, unsigned long to)
++{
++ unsigned long cursor;
++
++ cursor = from >> PAGE_SHIFT;
++ while ((cursor << PAGE_SHIFT) < to) {
++ if (!devmem_is_allowed(cursor)) {
++ printk(KERN_INFO "Program %s tried to read /dev/mem "
++ "between %lx->%lx.\n",
++ current->comm, from, to);
++ return 0;
++ }
++ cursor++;
++ }
++ return 1;
++}
++
+ /*
+ * This funcion reads the *physical* memory. The f_pos points directly to the
+ * memory location.
+@@ -157,6 +174,9 @@ static ssize_t read_mem(struct file * fi
+ */
+ ptr = xlate_dev_mem_ptr(p);
+
++ //FIXME: Add write-once sysctl
++ //if (!range_is_allowed(p, p+count))
++ // return -EPERM;
+ if (copy_to_user(buf, ptr, sz))
+ return -EFAULT;
+ buf += sz;
+@@ -169,6 +189,7 @@ static ssize_t read_mem(struct file * fi
+ return read;
+ }
+
++#ifdef CONFIG_WRITABLE_DEVMEM
+ static ssize_t write_mem(struct file * file, const char __user * buf,
+ size_t count, loff_t *ppos)
+ {
+@@ -214,6 +235,8 @@ static ssize_t write_mem(struct file * f
+ */
+ ptr = xlate_dev_mem_ptr(p);
+
++ if (!range_is_allowed(ptr, ptr+sz))
++ return -EPERM;
+ copied = copy_from_user(ptr, buf, sz);
+ if (copied) {
+ written += sz - copied;
+@@ -230,6 +253,9 @@ static ssize_t write_mem(struct file * f
+ *ppos += written;
+ return written;
+ }
++#else
++#define write_mem 0
++#endif
+
+ #ifndef __HAVE_PHYS_MEM_ACCESS_PROT
+ static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+@@ -363,6 +389,9 @@ static ssize_t read_kmem(struct file *fi
+ ssize_t low_count, read, sz;
+ char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
+
++ //FIXME: Add write-once sysctl
++ //return -EPERM;
++
+ read = 0;
+ if (p < (unsigned long) high_memory) {
+ low_count = count;
+@@ -439,6 +468,7 @@ static ssize_t read_kmem(struct file *fi
+ }
+
+
++#ifdef CONFIG_WRITABLE_DEVKMEM
+ static inline ssize_t
+ do_write_kmem(void *p, unsigned long realp, const char __user * buf,
+ size_t count, loff_t *ppos)
+@@ -557,6 +587,9 @@ static ssize_t write_kmem(struct file *
+ *ppos = p;
+ return virtr + wrote;
+ }
++#else
++#define write_kmem 0
++#endif
+
+ #ifdef CONFIG_DEVPORT
+ static ssize_t read_port(struct file * file, char __user * buf,
+@@ -873,7 +906,6 @@ static const struct {
+ const struct file_operations *fops;
+ } devlist[] = { /* list of minor devices */
+ {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
+- {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
+ {3, "null", S_IRUGO | S_IWUGO, &null_fops},
+ #ifdef CONFIG_DEVPORT
+ {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
More information about the fedora-extras-commits
mailing list