diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-08-23 13:11:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-08-23 13:11:45 -0400 |
commit | 01d7dd0e9f8c5f1888619d2649c7da389232b408 (patch) | |
tree | ee4f22a33557bae4883eb2f4fb1359e97ac74186 /net/netrom/af_netrom.c | |
parent | 53b924b31fa53ac3007df3fef6870d5074a9adf8 (diff) |
[AX25]: UID fixes
o Brown paperbag bug - ax25_findbyuid() was always returning a NULL pointer
as the result. Breaks ROSE completly and AX.25 if UID policy set to deny.
o While the list structure of AX.25's UID to callsign mapping table was
properly protected by a spinlock, it's elements were not refcounted
resulting in a race between removal and usage of an element.
Signed-off-by: Ralf Baechle DL5RB <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netrom/af_netrom.c')
-rw-r--r-- | net/netrom/af_netrom.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 5385835e9267..162a85fed150 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -536,7 +536,8 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
536 | struct nr_sock *nr = nr_sk(sk); | 536 | struct nr_sock *nr = nr_sk(sk); |
537 | struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr; | 537 | struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr; |
538 | struct net_device *dev; | 538 | struct net_device *dev; |
539 | ax25_address *user, *source; | 539 | ax25_uid_assoc *user; |
540 | ax25_address *source; | ||
540 | 541 | ||
541 | lock_sock(sk); | 542 | lock_sock(sk); |
542 | if (!sock_flag(sk, SOCK_ZAPPED)) { | 543 | if (!sock_flag(sk, SOCK_ZAPPED)) { |
@@ -575,16 +576,19 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
575 | } else { | 576 | } else { |
576 | source = &addr->fsa_ax25.sax25_call; | 577 | source = &addr->fsa_ax25.sax25_call; |
577 | 578 | ||
578 | if ((user = ax25_findbyuid(current->euid)) == NULL) { | 579 | user = ax25_findbyuid(current->euid); |
580 | if (user) { | ||
581 | nr->user_addr = user->call; | ||
582 | ax25_uid_put(user); | ||
583 | } else { | ||
579 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { | 584 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { |
580 | release_sock(sk); | 585 | release_sock(sk); |
581 | dev_put(dev); | 586 | dev_put(dev); |
582 | return -EPERM; | 587 | return -EPERM; |
583 | } | 588 | } |
584 | user = source; | 589 | nr->user_addr = *source; |
585 | } | 590 | } |
586 | 591 | ||
587 | nr->user_addr = *user; | ||
588 | nr->source_addr = *source; | 592 | nr->source_addr = *source; |
589 | } | 593 | } |
590 | 594 | ||
@@ -604,7 +608,8 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr, | |||
604 | struct sock *sk = sock->sk; | 608 | struct sock *sk = sock->sk; |
605 | struct nr_sock *nr = nr_sk(sk); | 609 | struct nr_sock *nr = nr_sk(sk); |
606 | struct sockaddr_ax25 *addr = (struct sockaddr_ax25 *)uaddr; | 610 | struct sockaddr_ax25 *addr = (struct sockaddr_ax25 *)uaddr; |
607 | ax25_address *user, *source = NULL; | 611 | ax25_address *source = NULL; |
612 | ax25_uid_assoc *user; | ||
608 | struct net_device *dev; | 613 | struct net_device *dev; |
609 | 614 | ||
610 | lock_sock(sk); | 615 | lock_sock(sk); |
@@ -645,16 +650,19 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr, | |||
645 | } | 650 | } |
646 | source = (ax25_address *)dev->dev_addr; | 651 | source = (ax25_address *)dev->dev_addr; |
647 | 652 | ||
648 | if ((user = ax25_findbyuid(current->euid)) == NULL) { | 653 | user = ax25_findbyuid(current->euid); |
654 | if (user) { | ||
655 | nr->user_addr = user->call; | ||
656 | ax25_uid_put(user); | ||
657 | } else { | ||
649 | if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) { | 658 | if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) { |
650 | dev_put(dev); | 659 | dev_put(dev); |
651 | release_sock(sk); | 660 | release_sock(sk); |
652 | return -EPERM; | 661 | return -EPERM; |
653 | } | 662 | } |
654 | user = source; | 663 | nr->user_addr = *source; |
655 | } | 664 | } |
656 | 665 | ||
657 | nr->user_addr = *user; | ||
658 | nr->source_addr = *source; | 666 | nr->source_addr = *source; |
659 | nr->device = dev; | 667 | nr->device = dev; |
660 | 668 | ||