All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnd Bergmann <arnd@arndb.de>
To: monstr@monstr.eu
Cc: linux-kernel@vger.kernel.org, john.williams@petalogix.com
Subject: Re: [PATCH 20/30] microblaze_mmu_v1: uaccess MMU update
Date: Wed, 29 Apr 2009 13:26:23 +0200	[thread overview]
Message-ID: <200904291326.23511.arnd@arndb.de> (raw)
In-Reply-To: <1240821139-7247-21-git-send-email-monstr@monstr.eu>

Following up on my earlier comment:

On Monday 27 April 2009, monstr@monstr.eu wrote:

> +#define __get_user(var, ptr)				\
> +({							\
> +	int __gu_err = 0;				\
> +	switch (sizeof(*(ptr))) {			\
> +	case 1:						\
> +	case 2:						\
> +	case 4:						\
> +		(var) = *(ptr);				\
> +		break;					\
> +	case 8:						\
> +		memcpy((void *) &(var), (ptr), 8);	\
> +		break;					\
> +	default:					\
> +		(var) = 0;				\
> +		__gu_err = __get_user_bad();		\
> +		break;					\
> +	}						\
> +	__gu_err;					\
> +})

This needs more __force to dereference the user pointers.
  
>  #define __get_user_bad()	(bad_user_access_length(), (-EFAULT))

You have actually defined bad_user_access_length(), which is not
how it __get_user_bad()	was meant as. The idea was to declare
an undefined function, which results in a link error in case
of funny length inputs to __get_user, a cheap way to do
BUILD_BUG_ON() in a switch() statement.

> +/* FIXME is not there defined __pu_val */
> +({								\
> +	int __pu_err = 0;					\
> +	switch (sizeof(*(ptr))) {				\
> +	case 1:							\
> +	case 2:							\
> +	case 4:							\
> +		*(ptr) = (var);					\
> +		break;						\
> +	case 8: {						\
> +		typeof(*(ptr)) __pu_val = (var);		\
> +		memcpy(ptr, &__pu_val, sizeof(__pu_val));	\
> +		}						\
> +		break;						\
> +	default:						\
> +		__pu_err = __put_user_bad();			\
> +		break;						\
> +	}							\
> +	__pu_err;						\
> +})
>  
>  #define __put_user_bad()	(bad_user_access_length(), (-EFAULT))

Same comments apply here.
  
> -#define put_user(x, ptr)	__put_user(x, ptr)
> -#define get_user(x, ptr)	__get_user(x, ptr)
> -
> -#define copy_to_user(to, from, n)		(memcpy(to, from, n), 0)
> -#define copy_from_user(to, from, n)		(memcpy(to, from, n), 0)
> +#define put_user(x, ptr)	__put_user((x), (ptr))
> +#define get_user(x, ptr)	__get_user((x), (ptr))

put_user and get_user should call access_ok() for the !MMU version I guess,
if you can easily detect kernel pointers based on the address.
It's also a good idea to add might_sleep() in there if access_ok()
doesn't have it already.

> -#define __copy_to_user(to, from, n)		(copy_to_user(to, from, n))
> -#define __copy_from_user(to, from, n)		(copy_from_user(to, from, n))
> -#define __copy_to_user_inatomic(to, from, n)	(__copy_to_user(to, from, n))
> -#define __copy_from_user_inatomic(to, from, n)	(__copy_from_user(to, from, n))
> +#define copy_to_user(to, from, n)	(memcpy((to), (from), (n)), 0)
> +#define copy_from_user(to, from, n)	(memcpy((to), (from), (n)), 0)

Same here, plus they can be shared between MMU and NOMMU.

> +#else /* CONFIG_MMU */
> +
> +/*
> + * Address is valid if:
> + *  - "addr", "addr + size" and "size" are all below the limit
> + */
> +#define access_ok(type, addr, size) \
> +	(get_fs().seg > (((unsigned long)(addr)) | \
> +		(size) | ((unsigned long)(addr) + (size))))
> +
> +/* || printk("access_ok failed for %s at 0x%08lx (size %d), seg 0x%08x\n",
> + type?"WRITE":"READ",addr,size,get_fs().seg)) */
> +
> +/*
> + * All the __XXX versions macros/functions below do not perform
> + * access checking. It is assumed that the necessary checks have been
> + * already performed before the finction (macro) is called.
> + */
> +
> +#define get_user(x, ptr)						\
> +({									\
> +	access_ok(VERIFY_READ, (ptr), sizeof(*(ptr)))			\
> +		? __get_user((x), (ptr)) : -EFAULT;			\
> +})
> +
> +#define put_user(x, ptr)						\
> +({									\
> +	access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr)))			\
> +		? __put_user((x), (ptr)) : -EFAULT;			\
> +})

Please add might_sleep() either here or in access_ok().

> +#define __get_user(x, ptr)						\
> +({									\
> +	unsigned long __gu_val;						\
> +	/*unsigned long __gu_ptr = (unsigned long)(ptr);*/		\
> +	long __gu_err;							\
> +	switch (sizeof(*(ptr))) {					\
> +	case 1:								\
> +		__get_user_asm("lbu", (ptr), __gu_val, __gu_err);	\
> +		break;							\
> +	case 2:								\
> +		__get_user_asm("lhu", (ptr), __gu_val, __gu_err);	\
> +		break;							\
> +	case 4:								\
> +		__get_user_asm("lw", (ptr), __gu_val, __gu_err);	\
> +		break;							\
> +	default:							\
> +		__gu_val = 0; __gu_err = -EINVAL;			\
> +	}								\
> +	x = (__typeof__(*(ptr))) __gu_val;				\
> +	__gu_err;							\
> +})

Again, the 'default:' case should give a link error, not a runtime
error. 

It seems inconsistent to have a 'case 8:' in !MMU as well as both
__put_user variants but not in the MMU __get_user.

> +#define __put_user(x, ptr)						\
> +({									\
> +	__typeof__(*(ptr)) __gu_val = x;				\
> +	long __gu_err = 0;						\
> +	switch (sizeof(__gu_val)) {					\
> +	case 1:								\
> +		__put_user_asm("sb", (ptr), __gu_val, __gu_err);	\
> +		break;							\
> +	case 2: 							\
> +		__put_user_asm("sh", (ptr), __gu_val, __gu_err);	\
> +		break;							\
> +	case 4:								\
> +		__put_user_asm("sw", (ptr), __gu_val, __gu_err);	\
> +		break;							\
> +	case 8:								\
> +		__put_user_asm_8((ptr), __gu_val, __gu_err);		\
> +		break;							\
> +	default:							\
> +		__gu_err = -EINVAL;					\
> +	}								\
> +	__gu_err;							\
> +})

> +/*
> + * Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail.
> + */
> +static inline int clear_user(char *to, int size)
> +{
> +	if (size && access_ok(VERIFY_WRITE, to, size)) {
> +		__asm__ __volatile__ ("				\
> +				1:				\
> +					sb	r0, %2, r0;	\
> +					addik	%0, %0, -1;	\
> +					bneid	%0, 1b;		\
> +					addik	%2, %2, 1;	\
> +				2:				\
> +				.section __ex_table,\"a\";	\
> +				.word	1b,2b;			\
> +				.section .text;"		\
> +			: "=r"(size)				\
> +			: "0"(size), "r"(to)
> +		);
> +	}
> +	return size;
> +}

Please use the prototype I mentioned in the other mail.

While I don't remember the exact story, I think the preferred
way to write multi-line inline assembly is

	asm volatile("# clear_user		\n"
		"1:				\n"
		"	sb r0, %2, r0		\n"
		"	addik	%0, %0, -1	\n"
		"	bneid	%0, 1b		\n"
		"2:				\n"
		".section __ex_table,\"a\"	\n"
		".word	1b,2b;			\n"
		".section .text;		\n");

rather than a single multi-line string.

> +extern unsigned long __copy_tofrom_user(void __user *to,
> +		const void __user *from, unsigned long size);
> +
> +#define copy_to_user(to, from, n)					\
> +	(access_ok(VERIFY_WRITE, (to), (n)) ?				\
> +		__copy_tofrom_user((void __user *)(to),			\
> +			(__force const void __user *)(from), (n))	\
> +		: -EFAULT)

No, copy_to_user does *not* return an errno, but instead the number
of bytes not copied. Assuming your __copy_tofrom_user is correct,
this would be

static inline __must_check unsigned long
copy_to_user(void __user *to, void *from, size_t n)
{
	might_sleep();

	if (!access_ok(VERIFY_WRITE, to, n))
		return n;

	return __copy_tofrom_user(to, (const void __force __user *)from, n);
}

> +#define __copy_to_user(to, from, n)	copy_to_user((to), (from), (n))
> +#define __copy_to_user_inatomic(to, from, n)	copy_to_user((to), (from), (n))
> +
> +#define copy_from_user(to, from, n)					\
> +	(access_ok(VERIFY_READ, (from), (n)) ?				\
> +		__copy_tofrom_user((__force void __user *)(to),		\
> +			(void __user *)(from), (n))			\
> +		: -EFAULT)

same here

> +#define __copy_from_user(to, from, n)	copy_from_user((to), (from), (n))
> +#define __copy_from_user_inatomic(to, from, n) \
> +		copy_from_user((to), (from), (n))
> +
> +extern int __strncpy_user(char *to, const char __user *from, int len);
> +extern int __strnlen_user(const char __user *sstr, int len);
> +
> +#define strncpy_from_user(to, from, len)	\
> +		(access_ok(VERIFY_READ, from, 1) ?	\
> +			__strncpy_user(to, from, len) : -EFAULT)

and here.

	Arnd <><

  parent reply	other threads:[~2009-04-29 11:27 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-27  8:31 Microblaze MMU patches monstr
2009-04-27  8:31 ` [PATCH 01/30] microblaze_mmu_v1: Makefiles monstr
2009-04-27  8:31   ` [PATCH 02/30] microblaze_mmu_v1: Kconfig update monstr
2009-04-27  8:31     ` [PATCH 03/30] microblaze_mmu_v1: Add mmu_defconfig monstr
2009-04-27  8:31       ` [PATCH 04/30] microblaze_mmu_v1: MMU update for startup code monstr
2009-04-27  8:31         ` [PATCH 05/30] microblaze_mmu_v1: Alocate TLB for early console monstr
2009-04-27  8:31           ` [PATCH 06/30] microblaze_mmu_v1: TLB low level code monstr
2009-04-27  8:31             ` [PATCH 07/30] microblaze_mmu_v1: MMU initialization monstr
2009-04-27  8:31               ` [PATCH 08/30] microblaze_mmu_v1: mmu.h update monstr
2009-04-27  8:31                 ` [PATCH 09/30] microblaze_mmu_v1: Page fault handling high level - fault.c monstr
2009-04-27  8:31                   ` [PATCH 10/30] microblaze_mmu_v1: Context handling - mmu_context.c/h monstr
2009-04-27  8:32                     ` [PATCH 11/30] microblaze_mmu_v1: Page table - ioremap - pgtable.c/h, section update monstr
2009-04-27  8:32                       ` [PATCH 12/30] microblaze_mmu_v1: io.h MMU update monstr
2009-04-27  8:32                         ` [PATCH 13/30] microblaze_mmu_v1: pgalloc.h and page.h monstr
2009-04-27  8:32                           ` [PATCH 14/30] microblaze_mmu_v1: Update process creation for MMU monstr
2009-04-27  8:32                             ` [PATCH 15/30] microblaze_mmu_v1: Update tlb.h and tlbflush.h monstr
2009-04-27  8:32                               ` [PATCH 16/30] microblaze_mmu_v1: MMU asm offset update monstr
2009-04-27  8:32                                 ` [PATCH 17/30] microblaze_mmu_v1: Add CURRENT_TASK for entry.S monstr
2009-04-27  8:32                                   ` [PATCH 18/30] microblaze_mmu_v1: entry.S, entry.h monstr
2009-04-27  8:32                                     ` [PATCH 19/30] microblaze_mmu_v1: Update exception handling - MMU exception monstr
2009-04-27  8:32                                       ` [PATCH 20/30] microblaze_mmu_v1: uaccess MMU update monstr
2009-04-27  8:32                                         ` [PATCH 21/30] microblaze_mmu_v1: Add MMU related exceptions handling monstr
2009-04-27  8:32                                           ` [PATCH 22/30] microblaze_mmu_v1: Update linker script for MMU monstr
2009-04-27  8:32                                             ` [PATCH 23/30] microblaze_mmu_v1: Enable fork syscall for MMU and add fork as vfork for noMMU monstr
2009-04-27  8:32                                               ` [PATCH 24/30] microblaze_mmu_v1: Traps MMU update monstr
2009-04-27  8:32                                                 ` [PATCH 25/30] microblaze_mmu_v1: Update signal returning address monstr
2009-04-27  8:32                                                   ` [PATCH 26/30] microblaze_mmu_v1: Update cacheflush.h monstr
2009-04-27  8:32                                                     ` [PATCH 27/30] microblaze_mmu_v1: Update dma.h for MMU monstr
2009-04-27  8:32                                                       ` [PATCH 28/30] microblaze_mmu_v1: Elf update monstr
2009-04-27  8:32                                                         ` [PATCH 29/30] microblaze_mmu_v1: stat.h MMU update monstr
2009-04-27  8:32                                                           ` [PATCH 30/30] microblaze_mmu_v1: fcntl.h " monstr
2009-04-27  9:59                                                             ` Christoph Hellwig
2009-04-27 10:05                                                               ` John Williams
2009-04-27 10:56                                                                 ` Michal Simek
2009-04-27  9:58                                                           ` [PATCH 29/30] microblaze_mmu_v1: stat.h " Christoph Hellwig
2009-04-27 10:35                                                             ` Michal Simek
2009-04-27 11:30                                                               ` Christoph Hellwig
2009-04-27 11:43                                                                 ` Michal Simek
2009-04-27 11:57                                                                   ` Arnd Bergmann
2009-04-27 12:15                                                                     ` Sam Ravnborg
2009-04-27 12:37                                                                       ` Arnd Bergmann
2009-04-27 12:48                                                                         ` Sam Ravnborg
2009-04-27 12:55                                                                           ` Arnd Bergmann
2009-04-27 12:31                                                                     ` Michal Simek
2009-04-27 12:42                                                                       ` Arnd Bergmann
2009-04-27 12:44                                                                         ` Michal Simek
2009-04-27 12:47                                                                           ` Arnd Bergmann
2009-04-27 12:48                                                                             ` Michal Simek
2009-04-30 13:53                                                                               ` Arnd Bergmann
2009-04-30 14:10                                                                                 ` Michal Simek
2009-04-30 14:40                                                                                   ` Arnd Bergmann
2009-04-30 14:51                                                                                     ` Michal Simek
2009-04-27 12:53                                                               ` Arnd Bergmann
2009-04-27 13:03                                                                 ` Michal Simek
2009-04-27 13:13                                                                   ` Arnd Bergmann
2009-04-27 11:43                                               ` [PATCH 23/30] microblaze_mmu_v1: Enable fork syscall for MMU and add fork as vfork for noMMU John Williams
2009-04-29 10:16                                                 ` Michal Simek
2009-04-29 11:31                                                   ` Arnd Bergmann
2009-04-29 11:27                                             ` [PATCH 22/30] microblaze_mmu_v1: Update linker script for MMU Arnd Bergmann
2009-04-29 11:39                                               ` Michal Simek
2009-04-29  5:54                                           ` [PATCH 21/30] microblaze_mmu_v1: Add MMU related exceptions handling Andrew Morton
2009-04-29  9:36                                             ` Michal Simek
2009-04-29  5:53                                         ` [PATCH 20/30] microblaze_mmu_v1: uaccess MMU update Andrew Morton
2009-04-29 10:12                                           ` Michal Simek
2009-04-29 10:58                                             ` Arnd Bergmann
2009-04-29 15:19                                               ` Michal Simek
2009-04-29 15:35                                                 ` Arnd Bergmann
2009-04-29 15:43                                                   ` Michal Simek
2009-04-29 15:55                                                     ` Arnd Bergmann
2009-04-29 11:26                                         ` Arnd Bergmann [this message]
2009-04-27 10:55                     ` [PATCH 10/30] microblaze_mmu_v1: Context handling - mmu_context.c/h Arnd Bergmann
2009-04-27 11:18                     ` Geert Uytterhoeven
2009-04-29  5:46                   ` [PATCH 09/30] microblaze_mmu_v1: Page fault handling high level - fault.c Andrew Morton
2009-04-29  9:30                     ` Michal Simek
2009-04-29  5:44                 ` [PATCH 08/30] microblaze_mmu_v1: mmu.h update Andrew Morton
2009-04-29  9:28                   ` Michal Simek
2009-04-29  5:42               ` [PATCH 07/30] microblaze_mmu_v1: MMU initialization Andrew Morton
2009-04-29  7:02                 ` Michal Simek
2009-04-29  8:42                 ` Michal Simek
2009-04-27 10:50   ` [PATCH 01/30] microblaze_mmu_v1: Makefiles Arnd Bergmann
2009-04-27 10:54     ` Michal Simek

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=200904291326.23511.arnd@arndb.de \
    --to=arnd@arndb.de \
    --cc=john.williams@petalogix.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=monstr@monstr.eu \
    /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.