diff options
| author | Nelson Elhage <nelhage@ksplice.com> | 2010-11-03 12:35:41 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-11-04 15:26:34 -0400 |
| commit | 22e76c849d505d87c5ecf3d3e6742a65f0ff4860 (patch) | |
| tree | ba8ac3765ae60f1bc8ce20d280baa741eb7b046e | |
| parent | 6b8c92ba07287578718335ce409de8e8d7217e40 (diff) | |
inet_diag: Make sure we actually run the same bytecode we audited.
We were using nlmsg_find_attr() to look up the bytecode by attribute when
auditing, but then just using the first attribute when actually running
bytecode. So, if we received a message with two attribute elements, where only
the second had type INET_DIAG_REQ_BYTECODE, we would validate and run different
bytecode strings.
Fix this by consistently using nlmsg_find_attr everywhere.
Signed-off-by: Nelson Elhage <nelhage@ksplice.com>
Signed-off-by: Thomas Graf <tgraf@infradead.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ipv4/inet_diag.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index ba8042665849..2ada17129fce 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -490,9 +490,11 @@ static int inet_csk_diag_dump(struct sock *sk, | |||
| 490 | { | 490 | { |
| 491 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); | 491 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); |
| 492 | 492 | ||
| 493 | if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { | 493 | if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { |
| 494 | struct inet_diag_entry entry; | 494 | struct inet_diag_entry entry; |
| 495 | struct rtattr *bc = (struct rtattr *)(r + 1); | 495 | const struct nlattr *bc = nlmsg_find_attr(cb->nlh, |
| 496 | sizeof(*r), | ||
| 497 | INET_DIAG_REQ_BYTECODE); | ||
| 496 | struct inet_sock *inet = inet_sk(sk); | 498 | struct inet_sock *inet = inet_sk(sk); |
| 497 | 499 | ||
| 498 | entry.family = sk->sk_family; | 500 | entry.family = sk->sk_family; |
| @@ -512,7 +514,7 @@ static int inet_csk_diag_dump(struct sock *sk, | |||
| 512 | entry.dport = ntohs(inet->inet_dport); | 514 | entry.dport = ntohs(inet->inet_dport); |
| 513 | entry.userlocks = sk->sk_userlocks; | 515 | entry.userlocks = sk->sk_userlocks; |
| 514 | 516 | ||
| 515 | if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) | 517 | if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) |
| 516 | return 0; | 518 | return 0; |
| 517 | } | 519 | } |
| 518 | 520 | ||
| @@ -527,9 +529,11 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, | |||
| 527 | { | 529 | { |
| 528 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); | 530 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); |
| 529 | 531 | ||
| 530 | if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { | 532 | if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { |
| 531 | struct inet_diag_entry entry; | 533 | struct inet_diag_entry entry; |
| 532 | struct rtattr *bc = (struct rtattr *)(r + 1); | 534 | const struct nlattr *bc = nlmsg_find_attr(cb->nlh, |
| 535 | sizeof(*r), | ||
| 536 | INET_DIAG_REQ_BYTECODE); | ||
| 533 | 537 | ||
| 534 | entry.family = tw->tw_family; | 538 | entry.family = tw->tw_family; |
| 535 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | 539 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
| @@ -548,7 +552,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, | |||
| 548 | entry.dport = ntohs(tw->tw_dport); | 552 | entry.dport = ntohs(tw->tw_dport); |
| 549 | entry.userlocks = 0; | 553 | entry.userlocks = 0; |
| 550 | 554 | ||
| 551 | if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) | 555 | if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) |
| 552 | return 0; | 556 | return 0; |
| 553 | } | 557 | } |
| 554 | 558 | ||
| @@ -618,7 +622,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
| 618 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); | 622 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); |
| 619 | struct inet_connection_sock *icsk = inet_csk(sk); | 623 | struct inet_connection_sock *icsk = inet_csk(sk); |
| 620 | struct listen_sock *lopt; | 624 | struct listen_sock *lopt; |
| 621 | struct rtattr *bc = NULL; | 625 | const struct nlattr *bc = NULL; |
| 622 | struct inet_sock *inet = inet_sk(sk); | 626 | struct inet_sock *inet = inet_sk(sk); |
| 623 | int j, s_j; | 627 | int j, s_j; |
| 624 | int reqnum, s_reqnum; | 628 | int reqnum, s_reqnum; |
| @@ -638,8 +642,9 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
| 638 | if (!lopt || !lopt->qlen) | 642 | if (!lopt || !lopt->qlen) |
| 639 | goto out; | 643 | goto out; |
| 640 | 644 | ||
| 641 | if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { | 645 | if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { |
| 642 | bc = (struct rtattr *)(r + 1); | 646 | bc = nlmsg_find_attr(cb->nlh, sizeof(*r), |
| 647 | INET_DIAG_REQ_BYTECODE); | ||
| 643 | entry.sport = inet->inet_num; | 648 | entry.sport = inet->inet_num; |
| 644 | entry.userlocks = sk->sk_userlocks; | 649 | entry.userlocks = sk->sk_userlocks; |
| 645 | } | 650 | } |
| @@ -672,8 +677,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
| 672 | &ireq->rmt_addr; | 677 | &ireq->rmt_addr; |
| 673 | entry.dport = ntohs(ireq->rmt_port); | 678 | entry.dport = ntohs(ireq->rmt_port); |
| 674 | 679 | ||
| 675 | if (!inet_diag_bc_run(RTA_DATA(bc), | 680 | if (!inet_diag_bc_run(nla_data(bc), |
| 676 | RTA_PAYLOAD(bc), &entry)) | 681 | nla_len(bc), &entry)) |
| 677 | continue; | 682 | continue; |
| 678 | } | 683 | } |
| 679 | 684 | ||
