All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH][MIPS] add return value check to user_termio_to_kernel_termios()
@ 2009-01-25 13:45 Yoichi Yuasa
  2009-01-28 12:40 ` Ralf Baechle
  0 siblings, 1 reply; 4+ messages in thread
From: Yoichi Yuasa @ 2009-01-25 13:45 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: yoichi_yuasa, linux-mips


Signed-off-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>

diff -pruN -X /home/yuasa/Memo/dontdiff linux-orig/arch/mips/include/asm/termios.h linux/arch/mips/include/asm/termios.h
--- linux-orig/arch/mips/include/asm/termios.h	2008-10-19 22:33:14.114377349 +0900
+++ linux/arch/mips/include/asm/termios.h	2008-10-19 22:41:25.322369698 +0900
@@ -97,14 +97,14 @@ struct termio {
 #define user_termio_to_kernel_termios(termios, termio) \
 ({ \
 	unsigned short tmp; \
-	get_user(tmp, &(termio)->c_iflag); \
-	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
-	get_user(tmp, &(termio)->c_oflag); \
-	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
-	get_user(tmp, &(termio)->c_cflag); \
-	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
-	get_user(tmp, &(termio)->c_lflag); \
-	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	if (!get_user(tmp, &(termio)->c_iflag)) \
+		(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	if (!get_user(tmp, &(termio)->c_oflag)) \
+		(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	if (!get_user(tmp, &(termio)->c_cflag)) \
+		(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	if (!get_user(tmp, &(termio)->c_lflag)) \
+		(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
 	get_user((termios)->c_line, &(termio)->c_line); \
 	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
 })

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][MIPS] add return value check to user_termio_to_kernel_termios()
  2009-01-25 13:45 [PATCH][MIPS] add return value check to user_termio_to_kernel_termios() Yoichi Yuasa
@ 2009-01-28 12:40 ` Ralf Baechle
  2009-01-28 13:40   ` Ralf Baechle
  0 siblings, 1 reply; 4+ messages in thread
From: Ralf Baechle @ 2009-01-28 12:40 UTC (permalink / raw)
  To: Yoichi Yuasa; +Cc: linux-mips

On Sun, Jan 25, 2009 at 10:45:57PM +0900, Yoichi Yuasa wrote:

> diff -pruN -X /home/yuasa/Memo/dontdiff linux-orig/arch/mips/include/asm/termios.h linux/arch/mips/include/asm/termios.h
> --- linux-orig/arch/mips/include/asm/termios.h	2008-10-19 22:33:14.114377349 +0900
> +++ linux/arch/mips/include/asm/termios.h	2008-10-19 22:41:25.322369698 +0900
> @@ -97,14 +97,14 @@ struct termio {
>  #define user_termio_to_kernel_termios(termios, termio) \
>  ({ \
>  	unsigned short tmp; \
> -	get_user(tmp, &(termio)->c_iflag); \
> -	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
> -	get_user(tmp, &(termio)->c_oflag); \
> -	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
> -	get_user(tmp, &(termio)->c_cflag); \
> -	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
> -	get_user(tmp, &(termio)->c_lflag); \
> -	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
> +	if (!get_user(tmp, &(termio)->c_iflag)) \
> +		(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
> +	if (!get_user(tmp, &(termio)->c_oflag)) \
> +		(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
> +	if (!get_user(tmp, &(termio)->c_cflag)) \
> +		(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
> +	if (!get_user(tmp, &(termio)->c_lflag)) \
> +		(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
>  	get_user((termios)->c_line, &(termio)->c_line); \
>  	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \

Duh...  That sort of trivial thing is not fatal but just shouldn't
happen.  And other architectures have the same bug even.  Your patch
leaves the last get_user and the copy_from_user return values unchecked.
I'll sort that out.

Thanks for reporting and patch!

  Ralf

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][MIPS] add return value check to user_termio_to_kernel_termios()
  2009-01-28 12:40 ` Ralf Baechle
@ 2009-01-28 13:40   ` Ralf Baechle
  2009-01-29 12:00     ` Yoichi Yuasa
  0 siblings, 1 reply; 4+ messages in thread
From: Ralf Baechle @ 2009-01-28 13:40 UTC (permalink / raw)
  To: Yoichi Yuasa; +Cc: linux-mips

On Wed, Jan 28, 2009 at 12:40:47PM +0000, Ralf Baechle wrote:

> Duh...  That sort of trivial thing is not fatal but just shouldn't
> happen.  And other architectures have the same bug even.  Your patch
> leaves the last get_user and the copy_from_user return values unchecked.
> I'll sort that out.

How about this patch which also gets rid of the rest of the macro soup
by replacing them with inline functions.

How about this?

  Ralf

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

commit 848091da998d2f0d5fe70c6bcd34a0cdf5c7f2b2
Author: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Date:   Sun Jan 25 22:45:57 2009 +0900

    MIPS: Add return value checks to user_termio_to_kernel_termios()
    
    Signed-off-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
    Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

diff --git a/arch/mips/include/asm/termios.h b/arch/mips/include/asm/termios.h
index a275661..8f77f77 100644
--- a/arch/mips/include/asm/termios.h
+++ b/arch/mips/include/asm/termios.h
@@ -9,6 +9,7 @@
 #ifndef _ASM_TERMIOS_H
 #define _ASM_TERMIOS_H
 
+#include <linux/errno.h>
 #include <asm/termbits.h>
 #include <asm/ioctls.h>
 
@@ -94,38 +95,81 @@ struct termio {
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-#define user_termio_to_kernel_termios(termios, termio) \
-({ \
-	unsigned short tmp; \
-	get_user(tmp, &(termio)->c_iflag); \
-	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
-	get_user(tmp, &(termio)->c_oflag); \
-	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
-	get_user(tmp, &(termio)->c_cflag); \
-	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
-	get_user(tmp, &(termio)->c_lflag); \
-	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
-	get_user((termios)->c_line, &(termio)->c_line); \
-	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-})
+static inline int user_termio_to_kernel_termios(struct ktermios *termios,
+	struct termio __user *termio)
+{
+	unsigned short iflag, oflag, cflag, lflag;
+	unsigned int err;
+
+	if (!access_ok(VERIFY_READ, termio, sizeof(struct termio)))
+		return -EFAULT;
+
+	err = __get_user(iflag, &termio->c_iflag);
+	termios->c_iflag = (termios->c_iflag & 0xffff0000) | iflag;
+	err |=__get_user(oflag, &termio->c_oflag);
+	termios->c_oflag = (termios->c_oflag & 0xffff0000) | oflag;
+	err |=__get_user(cflag, &termio->c_cflag);
+	termios->c_cflag = (termios->c_cflag & 0xffff0000) | cflag;
+	err |=__get_user(lflag, &termio->c_lflag);
+	termios->c_lflag = (termios->c_lflag & 0xffff0000) | lflag;
+	err |=__get_user(termios->c_line, &termio->c_line);
+	if (err)
+		return -EFAULT;
+
+	if (__copy_from_user(termios->c_cc, termio->c_cc, NCC))
+		return -EFAULT;
+
+	return 0;
+}
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  */
-#define kernel_termios_to_user_termio(termio, termios) \
-({ \
-	put_user((termios)->c_iflag, &(termio)->c_iflag); \
-	put_user((termios)->c_oflag, &(termio)->c_oflag); \
-	put_user((termios)->c_cflag, &(termio)->c_cflag); \
-	put_user((termios)->c_lflag, &(termio)->c_lflag); \
-	put_user((termios)->c_line, &(termio)->c_line); \
-	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
-})
-
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
-#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
+static inline int kernel_termios_to_user_termio(struct termio __user *termio,
+	struct ktermios *termios)
+{
+	int err;
+
+	if (!access_ok(VERIFY_WRITE, termio, sizeof(struct termio)))
+		return -EFAULT;
+
+	err = __put_user(termios->c_iflag, &termio->c_iflag);
+	err |= __put_user(termios->c_oflag, &termio->c_oflag);
+	err |= __put_user(termios->c_cflag, &termio->c_cflag);
+	err |= __put_user(termios->c_lflag, &termio->c_lflag);
+	err |= __put_user(termios->c_line, &termio->c_line);
+	if (err)
+		return -EFAULT;
+
+	if (__copy_to_user(termio->c_cc, termios->c_cc, NCC))
+		return -EFAULT;
+
+	return 0;
+}
+
+static inline int user_termios_to_kernel_termios(struct ktermios __user *k,
+	struct termios2 *u)
+{
+	return copy_from_user(k, u, sizeof(struct termios2)) ? -EFAULT : 0;
+}
+
+static inline int kernel_termios_to_user_termios(struct termios2 __user *u,
+	struct ktermios *k)
+{
+	return copy_to_user(u, k, sizeof(struct termios2)) ? -EFAULT : 0;
+}
+
+static inline int user_termios_to_kernel_termios_1(struct ktermios *k,
+	struct termios __user *u)
+{
+	return copy_from_user(k, u, sizeof(struct termios)) ? -EFAULT : 0;
+}
+
+static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
+	struct ktermios *k)
+{
+	return copy_to_user(u, k, sizeof(struct termios)) ? -EFAULT : 0;
+}
 
 #endif /* defined(__KERNEL__) */
 

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH][MIPS] add return value check to user_termio_to_kernel_termios()
  2009-01-28 13:40   ` Ralf Baechle
@ 2009-01-29 12:00     ` Yoichi Yuasa
  0 siblings, 0 replies; 4+ messages in thread
From: Yoichi Yuasa @ 2009-01-29 12:00 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: yoichi_yuasa, linux-mips

Hi,

On Wed, 28 Jan 2009 13:40:07 +0000
Ralf Baechle <ralf@linux-mips.org> wrote:

> On Wed, Jan 28, 2009 at 12:40:47PM +0000, Ralf Baechle wrote:
> 
> > Duh...  That sort of trivial thing is not fatal but just shouldn't
> > happen.  And other architectures have the same bug even.  Your patch
> > leaves the last get_user and the copy_from_user return values unchecked.
> > I'll sort that out.
> 
> How about this patch which also gets rid of the rest of the macro soup
> by replacing them with inline functions.
> 
> How about this?

It's good for me.

Yoichi

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-01-29 12:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-25 13:45 [PATCH][MIPS] add return value check to user_termio_to_kernel_termios() Yoichi Yuasa
2009-01-28 12:40 ` Ralf Baechle
2009-01-28 13:40   ` Ralf Baechle
2009-01-29 12:00     ` Yoichi Yuasa

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.