All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: linuxppc-dev@ozlabs.org, sbest@us.ibm.com, paulus@samba.org,
	anton@samba.org
Subject: Re: [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc
Date: Fri, 02 Dec 2011 12:23:28 +1100	[thread overview]
Message-ID: <1322789008.3729.42.camel@pasglop> (raw)
In-Reply-To: <20111202001141.GA14860@us.ibm.com>

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;

  reply	other threads:[~2011-12-02  1:25 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-02  0:11 [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc Sukadev Bhattiprolu
2011-12-02  1:23 ` Benjamin Herrenschmidt [this message]
2011-12-02  1:26 ` Benjamin Herrenschmidt
2011-12-02  3:25   ` Sukadev Bhattiprolu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1322789008.3729.42.camel@pasglop \
    --to=benh@kernel.crashing.org \
    --cc=anton@samba.org \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=paulus@samba.org \
    --cc=sbest@us.ibm.com \
    --cc=sukadev@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.