aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2009-01-28 09:13:37 -0500
committerRalf Baechle <ralf@linux-mips.org>2009-01-30 16:32:57 -0500
commit732f0462d59721764843783d790a613613287b33 (patch)
tree5079395c9aa6ec1311a259f7df897800725d425a
parent2d8965156b79dbfed722804c6036537c81699639 (diff)
MIPS: Add return value checks to user_termio_to_kernel_termios()
And while at it, convert all functions from macros to inline functions for sanity. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/include/asm/termios.h100
1 files changed, 72 insertions, 28 deletions
diff --git a/arch/mips/include/asm/termios.h b/arch/mips/include/asm/termios.h
index a275661fa7e1..8f77f774a2a0 100644
--- a/arch/mips/include/asm/termios.h
+++ b/arch/mips/include/asm/termios.h
@@ -9,6 +9,7 @@
9#ifndef _ASM_TERMIOS_H 9#ifndef _ASM_TERMIOS_H
10#define _ASM_TERMIOS_H 10#define _ASM_TERMIOS_H
11 11
12#include <linux/errno.h>
12#include <asm/termbits.h> 13#include <asm/termbits.h>
13#include <asm/ioctls.h> 14#include <asm/ioctls.h>
14 15
@@ -94,38 +95,81 @@ struct termio {
94/* 95/*
95 * Translate a "termio" structure into a "termios". Ugh. 96 * Translate a "termio" structure into a "termios". Ugh.
96 */ 97 */
97#define user_termio_to_kernel_termios(termios, termio) \ 98static inline int user_termio_to_kernel_termios(struct ktermios *termios,
98({ \ 99 struct termio __user *termio)
99 unsigned short tmp; \ 100{
100 get_user(tmp, &(termio)->c_iflag); \ 101 unsigned short iflag, oflag, cflag, lflag;
101 (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ 102 unsigned int err;
102 get_user(tmp, &(termio)->c_oflag); \ 103
103 (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ 104 if (!access_ok(VERIFY_READ, termio, sizeof(struct termio)))
104 get_user(tmp, &(termio)->c_cflag); \ 105 return -EFAULT;
105 (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ 106
106 get_user(tmp, &(termio)->c_lflag); \ 107 err = __get_user(iflag, &termio->c_iflag);
107 (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ 108 termios->c_iflag = (termios->c_iflag & 0xffff0000) | iflag;
108 get_user((termios)->c_line, &(termio)->c_line); \ 109 err |=__get_user(oflag, &termio->c_oflag);
109 copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ 110 termios->c_oflag = (termios->c_oflag & 0xffff0000) | oflag;
110}) 111 err |=__get_user(cflag, &termio->c_cflag);
112 termios->c_cflag = (termios->c_cflag & 0xffff0000) | cflag;
113 err |=__get_user(lflag, &termio->c_lflag);
114 termios->c_lflag = (termios->c_lflag & 0xffff0000) | lflag;
115 err |=__get_user(termios->c_line, &termio->c_line);
116 if (err)
117 return -EFAULT;
118
119 if (__copy_from_user(termios->c_cc, termio->c_cc, NCC))
120 return -EFAULT;
121
122 return 0;
123}
111 124
112/* 125/*
113 * Translate a "termios" structure into a "termio". Ugh. 126 * Translate a "termios" structure into a "termio". Ugh.
114 */ 127 */
115#define kernel_termios_to_user_termio(termio, termios) \ 128static inline int kernel_termios_to_user_termio(struct termio __user *termio,
116({ \ 129 struct ktermios *termios)
117 put_user((termios)->c_iflag, &(termio)->c_iflag); \ 130{
118 put_user((termios)->c_oflag, &(termio)->c_oflag); \ 131 int err;
119 put_user((termios)->c_cflag, &(termio)->c_cflag); \ 132
120 put_user((termios)->c_lflag, &(termio)->c_lflag); \ 133 if (!access_ok(VERIFY_WRITE, termio, sizeof(struct termio)))
121 put_user((termios)->c_line, &(termio)->c_line); \ 134 return -EFAULT;
122 copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ 135
123}) 136 err = __put_user(termios->c_iflag, &termio->c_iflag);
124 137 err |= __put_user(termios->c_oflag, &termio->c_oflag);
125#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) 138 err |= __put_user(termios->c_cflag, &termio->c_cflag);
126#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) 139 err |= __put_user(termios->c_lflag, &termio->c_lflag);
127#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) 140 err |= __put_user(termios->c_line, &termio->c_line);
128#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) 141 if (err)
142 return -EFAULT;
143
144 if (__copy_to_user(termio->c_cc, termios->c_cc, NCC))
145 return -EFAULT;
146
147 return 0;
148}
149
150static inline int user_termios_to_kernel_termios(struct ktermios __user *k,
151 struct termios2 *u)
152{
153 return copy_from_user(k, u, sizeof(struct termios2)) ? -EFAULT : 0;
154}
155
156static inline int kernel_termios_to_user_termios(struct termios2 __user *u,
157 struct ktermios *k)
158{
159 return copy_to_user(u, k, sizeof(struct termios2)) ? -EFAULT : 0;
160}
161
162static inline int user_termios_to_kernel_termios_1(struct ktermios *k,
163 struct termios __user *u)
164{
165 return copy_from_user(k, u, sizeof(struct termios)) ? -EFAULT : 0;
166}
167
168static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
169 struct ktermios *k)
170{
171 return copy_to_user(u, k, sizeof(struct termios)) ? -EFAULT : 0;
172}
129 173
130#endif /* defined(__KERNEL__) */ 174#endif /* defined(__KERNEL__) */
131 175