diff options
Diffstat (limited to 'net/can/raw.c')
| -rw-r--r-- | net/can/raw.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/net/can/raw.c b/net/can/raw.c index da99cf153b33..a10e3338f084 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
| @@ -436,14 +436,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
| 436 | 436 | ||
| 437 | if (count > 1) { | 437 | if (count > 1) { |
| 438 | /* filter does not fit into dfilter => alloc space */ | 438 | /* filter does not fit into dfilter => alloc space */ |
| 439 | filter = kmalloc(optlen, GFP_KERNEL); | 439 | filter = memdup_user(optval, optlen); |
| 440 | if (!filter) | 440 | if (IS_ERR(filter)) |
| 441 | return -ENOMEM; | 441 | return PTR_ERR(filter); |
| 442 | |||
| 443 | if (copy_from_user(filter, optval, optlen)) { | ||
| 444 | kfree(filter); | ||
| 445 | return -EFAULT; | ||
| 446 | } | ||
| 447 | } else if (count == 1) { | 442 | } else if (count == 1) { |
| 448 | if (copy_from_user(&sfilter, optval, sizeof(sfilter))) | 443 | if (copy_from_user(&sfilter, optval, sizeof(sfilter))) |
| 449 | return -EFAULT; | 444 | return -EFAULT; |
| @@ -655,6 +650,10 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 655 | err = sock_tx_timestamp(msg, sk, skb_tx(skb)); | 650 | err = sock_tx_timestamp(msg, sk, skb_tx(skb)); |
| 656 | if (err < 0) | 651 | if (err < 0) |
| 657 | goto free_skb; | 652 | goto free_skb; |
| 653 | |||
| 654 | /* to be able to check the received tx sock reference in raw_rcv() */ | ||
| 655 | skb_tx(skb)->prevent_sk_orphan = 1; | ||
| 656 | |||
| 658 | skb->dev = dev; | 657 | skb->dev = dev; |
| 659 | skb->sk = sk; | 658 | skb->sk = sk; |
| 660 | 659 | ||
