diff options
author | Xi Wang <xi.wang@gmail.com> | 2011-12-27 04:44:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-28 14:08:08 -0500 |
commit | 32288eb4d940b10e40c6d4178fe3a40d1437d2f8 (patch) | |
tree | 7cdd2b53eae8b6381eec1ddd497f28615277f1c2 | |
parent | ba1cffe0257bcd4d0070bc0e64f8ead97fefd148 (diff) |
netrom: avoid overflows in nr_setsockopt()
Check setsockopt arguments to avoid overflows and return -EINVAL for
too large arguments.
Signed-off-by: Xi Wang <xi.wang@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/netrom/af_netrom.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index c329b474eace..7dab229bfbcc 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -306,26 +306,26 @@ static int nr_setsockopt(struct socket *sock, int level, int optname, | |||
306 | { | 306 | { |
307 | struct sock *sk = sock->sk; | 307 | struct sock *sk = sock->sk; |
308 | struct nr_sock *nr = nr_sk(sk); | 308 | struct nr_sock *nr = nr_sk(sk); |
309 | int opt; | 309 | unsigned long opt; |
310 | 310 | ||
311 | if (level != SOL_NETROM) | 311 | if (level != SOL_NETROM) |
312 | return -ENOPROTOOPT; | 312 | return -ENOPROTOOPT; |
313 | 313 | ||
314 | if (optlen < sizeof(int)) | 314 | if (optlen < sizeof(unsigned int)) |
315 | return -EINVAL; | 315 | return -EINVAL; |
316 | 316 | ||
317 | if (get_user(opt, (int __user *)optval)) | 317 | if (get_user(opt, (unsigned int __user *)optval)) |
318 | return -EFAULT; | 318 | return -EFAULT; |
319 | 319 | ||
320 | switch (optname) { | 320 | switch (optname) { |
321 | case NETROM_T1: | 321 | case NETROM_T1: |
322 | if (opt < 1) | 322 | if (opt < 1 || opt > ULONG_MAX / HZ) |
323 | return -EINVAL; | 323 | return -EINVAL; |
324 | nr->t1 = opt * HZ; | 324 | nr->t1 = opt * HZ; |
325 | return 0; | 325 | return 0; |
326 | 326 | ||
327 | case NETROM_T2: | 327 | case NETROM_T2: |
328 | if (opt < 1) | 328 | if (opt < 1 || opt > ULONG_MAX / HZ) |
329 | return -EINVAL; | 329 | return -EINVAL; |
330 | nr->t2 = opt * HZ; | 330 | nr->t2 = opt * HZ; |
331 | return 0; | 331 | return 0; |
@@ -337,13 +337,13 @@ static int nr_setsockopt(struct socket *sock, int level, int optname, | |||
337 | return 0; | 337 | return 0; |
338 | 338 | ||
339 | case NETROM_T4: | 339 | case NETROM_T4: |
340 | if (opt < 1) | 340 | if (opt < 1 || opt > ULONG_MAX / HZ) |
341 | return -EINVAL; | 341 | return -EINVAL; |
342 | nr->t4 = opt * HZ; | 342 | nr->t4 = opt * HZ; |
343 | return 0; | 343 | return 0; |
344 | 344 | ||
345 | case NETROM_IDLE: | 345 | case NETROM_IDLE: |
346 | if (opt < 0) | 346 | if (opt > ULONG_MAX / (60 * HZ)) |
347 | return -EINVAL; | 347 | return -EINVAL; |
348 | nr->idle = opt * 60 * HZ; | 348 | nr->idle = opt * 60 * HZ; |
349 | return 0; | 349 | return 0; |