diff options
author | Sam Ravnborg <sam@ravnborg.org> | 2008-04-27 01:57:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-27 17:26:51 -0400 |
commit | 3f91bd420a955803421f2db17b2e04aacfbb2bb8 (patch) | |
tree | 52f47db69004eddcd22bfa69246d08632dfcd256 /net/can/raw.c | |
parent | 5c5d6dabb7aac9d0ea7aa76b909bbd28efa99065 (diff) |
can: Fix copy_from_user() results interpretation
Both copy_to_ and _from_user return the number of bytes, that failed to
reach their destination, not the 0/-EXXX values.
Based on patch from Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Acked-by: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/can/raw.c')
-rw-r--r-- | net/can/raw.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/net/can/raw.c b/net/can/raw.c index 201cbfc6b9ec..69877b8e7e9c 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -435,15 +435,13 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
435 | if (!filter) | 435 | if (!filter) |
436 | return -ENOMEM; | 436 | return -ENOMEM; |
437 | 437 | ||
438 | err = copy_from_user(filter, optval, optlen); | 438 | if (copy_from_user(filter, optval, optlen)) { |
439 | if (err) { | ||
440 | kfree(filter); | 439 | kfree(filter); |
441 | return err; | 440 | return -EFAULT; |
442 | } | 441 | } |
443 | } else if (count == 1) { | 442 | } else if (count == 1) { |
444 | err = copy_from_user(&sfilter, optval, optlen); | 443 | if (copy_from_user(&sfilter, optval, optlen)) |
445 | if (err) | 444 | return -EFAULT; |
446 | return err; | ||
447 | } | 445 | } |
448 | 446 | ||
449 | lock_sock(sk); | 447 | lock_sock(sk); |
@@ -493,9 +491,8 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
493 | if (optlen != sizeof(err_mask)) | 491 | if (optlen != sizeof(err_mask)) |
494 | return -EINVAL; | 492 | return -EINVAL; |
495 | 493 | ||
496 | err = copy_from_user(&err_mask, optval, optlen); | 494 | if (copy_from_user(&err_mask, optval, optlen)) |
497 | if (err) | 495 | return -EFAULT; |
498 | return err; | ||
499 | 496 | ||
500 | err_mask &= CAN_ERR_MASK; | 497 | err_mask &= CAN_ERR_MASK; |
501 | 498 | ||
@@ -531,7 +528,8 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
531 | if (optlen != sizeof(ro->loopback)) | 528 | if (optlen != sizeof(ro->loopback)) |
532 | return -EINVAL; | 529 | return -EINVAL; |
533 | 530 | ||
534 | err = copy_from_user(&ro->loopback, optval, optlen); | 531 | if (copy_from_user(&ro->loopback, optval, optlen)) |
532 | return -EFAULT; | ||
535 | 533 | ||
536 | break; | 534 | break; |
537 | 535 | ||
@@ -539,7 +537,8 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
539 | if (optlen != sizeof(ro->recv_own_msgs)) | 537 | if (optlen != sizeof(ro->recv_own_msgs)) |
540 | return -EINVAL; | 538 | return -EINVAL; |
541 | 539 | ||
542 | err = copy_from_user(&ro->recv_own_msgs, optval, optlen); | 540 | if (copy_from_user(&ro->recv_own_msgs, optval, optlen)) |
541 | return -EFAULT; | ||
543 | 542 | ||
544 | break; | 543 | break; |
545 | 544 | ||