aboutsummaryrefslogtreecommitdiffstats
path: root/net/ax25/af_ax25.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/ax25/af_ax25.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/ax25/af_ax25.c')
-rw-r--r--net/ax25/af_ax25.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 7d8ecadba668..a5c94f11547c 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1002,7 +1002,8 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1002 struct sock *sk = sock->sk; 1002 struct sock *sk = sock->sk;
1003 struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr; 1003 struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr;
1004 ax25_dev *ax25_dev = NULL; 1004 ax25_dev *ax25_dev = NULL;
1005 ax25_address *call; 1005 ax25_uid_assoc *user;
1006 ax25_address call;
1006 ax25_cb *ax25; 1007 ax25_cb *ax25;
1007 int err = 0; 1008 int err = 0;
1008 1009
@@ -1021,9 +1022,15 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1021 if (addr->fsa_ax25.sax25_family != AF_AX25) 1022 if (addr->fsa_ax25.sax25_family != AF_AX25)
1022 return -EINVAL; 1023 return -EINVAL;
1023 1024
1024 call = ax25_findbyuid(current->euid); 1025 user = ax25_findbyuid(current->euid);
1025 if (call == NULL && ax25_uid_policy && !capable(CAP_NET_ADMIN)) { 1026 if (user) {
1026 return -EACCES; 1027 call = user->call;
1028 ax25_uid_put(user);
1029 } else {
1030 if (ax25_uid_policy && !capable(CAP_NET_ADMIN))
1031 return -EACCES;
1032
1033 call = addr->fsa_ax25.sax25_call;
1027 } 1034 }
1028 1035
1029 lock_sock(sk); 1036 lock_sock(sk);
@@ -1034,10 +1041,7 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1034 goto out; 1041 goto out;
1035 } 1042 }
1036 1043
1037 if (call == NULL) 1044 ax25->source_addr = call;
1038 ax25->source_addr = addr->fsa_ax25.sax25_call;
1039 else
1040 ax25->source_addr = *call;
1041 1045
1042 /* 1046 /*
1043 * User already set interface with SO_BINDTODEVICE 1047 * User already set interface with SO_BINDTODEVICE