* [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc
@ 2011-12-02 0:11 Sukadev Bhattiprolu
2011-12-02 1:23 ` Benjamin Herrenschmidt
2011-12-02 1:26 ` Benjamin Herrenschmidt
0 siblings, 2 replies; 4+ messages in thread
From: Sukadev Bhattiprolu @ 2011-12-02 0:11 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, sbest, paulus, anton
>From aebed2e9fb9fba7dd0a34595780b828d7a545ba2 Mon Sep 17 00:00:00 2001
From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Date: Mon, 29 Aug 2011 14:12:08 -0700
Subject: [PATCH 1/1][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc.
As described in the help text in the patch, this token restricts general
access to /dev/mem as a way of increasing security. Specifically, access
to exclusive IOMEM and kernel RAM is denied unless CONFIG_STRICT_DEVMEM is
set to 'n'.
Implement the 'devmem_is_allowed()' interface for POWER. It will be
called from range_is_allowed() when userpsace attempts to access /dev/mem.
This patch is based on an earlier patch from Steve Best and with input from
Paul Mackerras.
A test for this patch:
# cat /proc/rtas/rmo_buffer
000000000f190000 10000
# python -c "print 0x000000000f190000 / 0x10000"
3865
# dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3865
1+0 records in
1+0 records out
65536 bytes (66 kB) copied, 0.000205235 s, 319 MB/s
# dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3864
dd: reading `/dev/mem': Operation not permitted
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.000226844 s, 0.0 kB/s
# dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3866
dd: reading `/dev/mem': Operation not permitted
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.00023542 s, 0.0 kB/s
# dd if=/dev/mem of=/tmp/foo
dd: reading `/dev/mem': Operation not permitted
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.00022519 s, 0.0 kB/s
Changelog[v2]:
- [Anton Blanchard] Punch a hole in devmem to allow librtas/dlpar
tools access to /dev/mem.
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
---
arch/powerpc/Kconfig.debug | 12 ++++++++++++
arch/powerpc/include/asm/page.h | 1 +
arch/powerpc/kernel/rtas.c | 10 ++++++++++
arch/powerpc/mm/mem.c | 20 ++++++++++++++++++++
drivers/char/mem.c | 5 +++--
5 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 067cb84..1cf1b00 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -298,4 +298,16 @@ config PPC_EARLY_DEBUG_CPM_ADDR
platform probing is done, all platforms selected must
share the same address.
+config STRICT_DEVMEM
+ def_bool y
+ prompt "Filter access to /dev/mem"
+ help
+ This option restricts access to /dev/mem. If this option is
+ disabled, you allow userspace access to all memory, including
+ kernel and userspace memory. Accidental memory access is likely
+ to be disastrous.
+ Memory access is required for experts who want to debug the kernel.
+
+ If you are unsure, say Y.
+
endmenu
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 2cd664e..dc2ec96 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -261,6 +261,7 @@ extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
extern void copy_user_page(void *to, void *from, unsigned long vaddr,
struct page *p);
extern int page_is_ram(unsigned long pfn);
+extern int devmem_is_allowed(unsigned long pfn);
#ifdef CONFIG_PPC_SMLPAR
void arch_free_page(struct page *page, int order);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index d5ca823..07cf2cf 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -937,6 +937,16 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
return 0;
}
+int page_is_rtas(unsigned long pfn)
+{
+ unsigned long paddr = (pfn << PAGE_SHIFT);
+
+ if (paddr >= rtas_rmo_buf && paddr < (rtas_rmo_buf + RTAS_RMOBUF_MAX))
+ return 1;
+
+ return 0;
+}
+
/*
* Call early during boot, before mem init or bootmem, to retrieve the RTAS
* informations from the device-tree and allocate the RMO buffer for userland
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index c781bbc..d21dbc6 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -549,3 +549,23 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
hash_preload(vma->vm_mm, address, access, trap);
#endif /* CONFIG_PPC_STD_MMU */
}
+
+extern int page_is_rtas(unsigned long pfn);
+
+/*
+ * devmem_is_allowed(): check to see if /dev/mem access to a certain address
+ * is valid. The argument is a physical page number.
+ *
+ * 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 pfn)
+{
+ if (iomem_is_exclusive(pfn << PAGE_SHIFT))
+ return 0;
+ if (!page_is_ram(pfn))
+ return 1;
+ if (page_is_rtas(pfn))
+ return 1;
+ return 0;
+}
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 8fc04b4..64917e8 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -29,6 +29,7 @@
#include <asm/uaccess.h>
#include <asm/io.h>
+#include <asm/page.h>
#ifdef CONFIG_IA64
# include <linux/efi.h>
@@ -66,8 +67,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
while (cursor < to) {
if (!devmem_is_allowed(pfn)) {
printk(KERN_INFO
- "Program %s tried to access /dev/mem between %Lx->%Lx.\n",
- current->comm, from, to);
+ "Program %s tried to access /dev/mem between %Lx->%Lx and "
+ "pfn %lu.\n", current->comm, from, to, pfn);
return 0;
}
cursor += PAGE_SIZE;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc
2011-12-02 0:11 [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc Sukadev Bhattiprolu
@ 2011-12-02 1:23 ` Benjamin Herrenschmidt
2011-12-02 1:26 ` Benjamin Herrenschmidt
1 sibling, 0 replies; 4+ messages in thread
From: Benjamin Herrenschmidt @ 2011-12-02 1:23 UTC (permalink / raw)
To: Sukadev Bhattiprolu; +Cc: linuxppc-dev, sbest, paulus, anton
On Thu, 2011-12-01 at 16:11 -0800, Sukadev Bhattiprolu wrote:
> >From aebed2e9fb9fba7dd0a34595780b828d7a545ba2 Mon Sep 17 00:00:00 2001
> From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Date: Mon, 29 Aug 2011 14:12:08 -0700
> Subject: [PATCH 1/1][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc.
>
> As described in the help text in the patch, this token restricts general
> access to /dev/mem as a way of increasing security. Specifically, access
> to exclusive IOMEM and kernel RAM is denied unless CONFIG_STRICT_DEVMEM is
> set to 'n'.
>
> Implement the 'devmem_is_allowed()' interface for POWER. It will be
> called from range_is_allowed() when userpsace attempts to access /dev/mem.
>
> This patch is based on an earlier patch from Steve Best and with input from
> Paul Mackerras.
A slightly different version of that patch is already in my -next branch
since earlier this week. Please send a followup patch adding the missing
rtas bit.
Note that I've dropped the generic printk change which has nothing to do
in that patch and can/should be submitted separately if it's really
needed.
Cheers,
Ben.
> A test for this patch:
>
> # cat /proc/rtas/rmo_buffer
> 000000000f190000 10000
>
> # python -c "print 0x000000000f190000 / 0x10000"
> 3865
>
> # dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3865
> 1+0 records in
> 1+0 records out
> 65536 bytes (66 kB) copied, 0.000205235 s, 319 MB/s
>
> # dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3864
> dd: reading `/dev/mem': Operation not permitted
> 0+0 records in
> 0+0 records out
> 0 bytes (0 B) copied, 0.000226844 s, 0.0 kB/s
>
> # dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3866
> dd: reading `/dev/mem': Operation not permitted
> 0+0 records in
> 0+0 records out
> 0 bytes (0 B) copied, 0.00023542 s, 0.0 kB/s
>
> # dd if=/dev/mem of=/tmp/foo
> dd: reading `/dev/mem': Operation not permitted
> 0+0 records in
> 0+0 records out
> 0 bytes (0 B) copied, 0.00022519 s, 0.0 kB/s
>
> Changelog[v2]:
> - [Anton Blanchard] Punch a hole in devmem to allow librtas/dlpar
> tools access to /dev/mem.
>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> ---
> arch/powerpc/Kconfig.debug | 12 ++++++++++++
> arch/powerpc/include/asm/page.h | 1 +
> arch/powerpc/kernel/rtas.c | 10 ++++++++++
> arch/powerpc/mm/mem.c | 20 ++++++++++++++++++++
> drivers/char/mem.c | 5 +++--
> 5 files changed, 46 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
> index 067cb84..1cf1b00 100644
> --- a/arch/powerpc/Kconfig.debug
> +++ b/arch/powerpc/Kconfig.debug
> @@ -298,4 +298,16 @@ config PPC_EARLY_DEBUG_CPM_ADDR
> platform probing is done, all platforms selected must
> share the same address.
>
> +config STRICT_DEVMEM
> + def_bool y
> + prompt "Filter access to /dev/mem"
> + help
> + This option restricts access to /dev/mem. If this option is
> + disabled, you allow userspace access to all memory, including
> + kernel and userspace memory. Accidental memory access is likely
> + to be disastrous.
> + Memory access is required for experts who want to debug the kernel.
> +
> + If you are unsure, say Y.
> +
> endmenu
> diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
> index 2cd664e..dc2ec96 100644
> --- a/arch/powerpc/include/asm/page.h
> +++ b/arch/powerpc/include/asm/page.h
> @@ -261,6 +261,7 @@ extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
> extern void copy_user_page(void *to, void *from, unsigned long vaddr,
> struct page *p);
> extern int page_is_ram(unsigned long pfn);
> +extern int devmem_is_allowed(unsigned long pfn);
>
> #ifdef CONFIG_PPC_SMLPAR
> void arch_free_page(struct page *page, int order);
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index d5ca823..07cf2cf 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -937,6 +937,16 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
> return 0;
> }
>
> +int page_is_rtas(unsigned long pfn)
> +{
> + unsigned long paddr = (pfn << PAGE_SHIFT);
> +
> + if (paddr >= rtas_rmo_buf && paddr < (rtas_rmo_buf + RTAS_RMOBUF_MAX))
> + return 1;
> +
> + return 0;
> +}
> +
> /*
> * Call early during boot, before mem init or bootmem, to retrieve the RTAS
> * informations from the device-tree and allocate the RMO buffer for userland
> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> index c781bbc..d21dbc6 100644
> --- a/arch/powerpc/mm/mem.c
> +++ b/arch/powerpc/mm/mem.c
> @@ -549,3 +549,23 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
> hash_preload(vma->vm_mm, address, access, trap);
> #endif /* CONFIG_PPC_STD_MMU */
> }
> +
> +extern int page_is_rtas(unsigned long pfn);
> +
> +/*
> + * devmem_is_allowed(): check to see if /dev/mem access to a certain address
> + * is valid. The argument is a physical page number.
> + *
> + * 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 pfn)
> +{
> + if (iomem_is_exclusive(pfn << PAGE_SHIFT))
> + return 0;
> + if (!page_is_ram(pfn))
> + return 1;
> + if (page_is_rtas(pfn))
> + return 1;
> + return 0;
> +}
> diff --git a/drivers/char/mem.c b/drivers/char/mem.c
> index 8fc04b4..64917e8 100644
> --- a/drivers/char/mem.c
> +++ b/drivers/char/mem.c
> @@ -29,6 +29,7 @@
>
> #include <asm/uaccess.h>
> #include <asm/io.h>
> +#include <asm/page.h>
>
> #ifdef CONFIG_IA64
> # include <linux/efi.h>
> @@ -66,8 +67,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
> while (cursor < to) {
> if (!devmem_is_allowed(pfn)) {
> printk(KERN_INFO
> - "Program %s tried to access /dev/mem between %Lx->%Lx.\n",
> - current->comm, from, to);
> + "Program %s tried to access /dev/mem between %Lx->%Lx and "
> + "pfn %lu.\n", current->comm, from, to, pfn);
> return 0;
> }
> cursor += PAGE_SIZE;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc
2011-12-02 0:11 [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc Sukadev Bhattiprolu
2011-12-02 1:23 ` Benjamin Herrenschmidt
@ 2011-12-02 1:26 ` Benjamin Herrenschmidt
2011-12-02 3:25 ` Sukadev Bhattiprolu
1 sibling, 1 reply; 4+ messages in thread
From: Benjamin Herrenschmidt @ 2011-12-02 1:26 UTC (permalink / raw)
To: Sukadev Bhattiprolu; +Cc: linuxppc-dev, sbest, paulus, anton
And an additional comment regarding the rtas bit:
> #ifdef CONFIG_PPC_SMLPAR
> void arch_free_page(struct page *page, int order);
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index d5ca823..07cf2cf 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -937,6 +937,16 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
> return 0;
> }
>
> +int page_is_rtas(unsigned long pfn)
> +{
> + unsigned long paddr = (pfn << PAGE_SHIFT);
> +
> + if (paddr >= rtas_rmo_buf && paddr < (rtas_rmo_buf + RTAS_RMOBUF_MAX))
> + return 1;
> +
> + return 0;
> +}
So this only exist whenever rtas.c is compiled... but ...
> +
> /*
> * Call early during boot, before mem init or bootmem, to retrieve the RTAS
> * informations from the device-tree and allocate the RMO buffer for userland
> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> index c781bbc..d21dbc6 100644
> --- a/arch/powerpc/mm/mem.c
> +++ b/arch/powerpc/mm/mem.c
> @@ -549,3 +549,23 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
> hash_preload(vma->vm_mm, address, access, trap);
> #endif /* CONFIG_PPC_STD_MMU */
> }
> +
> +extern int page_is_rtas(unsigned long pfn);
> +
> +/*
> + * devmem_is_allowed(): check to see if /dev/mem access to a certain address
> + * is valid. The argument is a physical page number.
> + *
> + * 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 pfn)
> +{
> + if (iomem_is_exclusive(pfn << PAGE_SHIFT))
> + return 0;
> + if (!page_is_ram(pfn))
> + return 1;
> + if (page_is_rtas(pfn))
> + return 1;
> + return 0;
> +}
This calls it unconditionally... you just broke the build of all !rtas
platforms. Additionally, putting an extern definition like that in a .c
file is gross at best....
Please instead, put in a header something like
#ifdef CONFIG_PPC_RTAS
extern int page_is_rtas(unsigned long pfn);
#else
static inline int page_is_rtas(unsigned long pfn) { }
#endif
And while at it, call it page_is_rtas_user_buf(); to make it clear what
we are talking about, ie, not RTAS core per-se but specifically the RMO
buffer.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc
2011-12-02 1:26 ` Benjamin Herrenschmidt
@ 2011-12-02 3:25 ` Sukadev Bhattiprolu
0 siblings, 0 replies; 4+ messages in thread
From: Sukadev Bhattiprolu @ 2011-12-02 3:25 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, sbest, paulus, anton
Benjamin Herrenschmidt [benh@kernel.crashing.org] wrote:
| And an additional comment regarding the rtas bit:
| > +int devmem_is_allowed(unsigned long pfn)
| > +{
| > + if (iomem_is_exclusive(pfn << PAGE_SHIFT))
| > + return 0;
| > + if (!page_is_ram(pfn))
| > + return 1;
| > + if (page_is_rtas(pfn))
| > + return 1;
| > + return 0;
| > +}
|
| This calls it unconditionally... you just broke the build of all !rtas
| platforms. Additionally, putting an extern definition like that in a .c
| file is gross at best....
Oh, Sorry.
|
| Please instead, put in a header something like
|
| #ifdef CONFIG_PPC_RTAS
| extern int page_is_rtas(unsigned long pfn);
| #else
| static inline int page_is_rtas(unsigned long pfn) { }
| #endif
|
| And while at it, call it page_is_rtas_user_buf(); to make it clear what
| we are talking about, ie, not RTAS core per-se but specifically the RMO
| buffer.
Ok. I will rename, move the declaration to <asm/rtas.h> and resend the
incremental patch.
Sukadev
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-12-02 3:25 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-02 0:11 [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc Sukadev Bhattiprolu
2011-12-02 1:23 ` Benjamin Herrenschmidt
2011-12-02 1:26 ` Benjamin Herrenschmidt
2011-12-02 3:25 ` Sukadev Bhattiprolu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).