aboutsummaryrefslogtreecommitdiffstats
path: root/net/netrom/af_netrom.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-08-23 13:11:45 -0400
committerDavid S. Miller <davem@davemloft.net>2005-08-23 13:11:45 -0400
commit01d7dd0e9f8c5f1888619d2649c7da389232b408 (patch)
treeee4f22a33557bae4883eb2f4fb1359e97ac74186 /net/netrom/af_netrom.c
parent53b924b31fa53ac3007df3fef6870d5074a9adf8 (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.c24
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