[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>
This commit is contained in:
committed by
David S. Miller
parent
53b924b31f
commit
01d7dd0e9f
@ -536,7 +536,8 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
struct nr_sock *nr = nr_sk(sk);
|
||||
struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr;
|
||||
struct net_device *dev;
|
||||
ax25_address *user, *source;
|
||||
ax25_uid_assoc *user;
|
||||
ax25_address *source;
|
||||
|
||||
lock_sock(sk);
|
||||
if (!sock_flag(sk, SOCK_ZAPPED)) {
|
||||
@ -575,16 +576,19 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
} else {
|
||||
source = &addr->fsa_ax25.sax25_call;
|
||||
|
||||
if ((user = ax25_findbyuid(current->euid)) == NULL) {
|
||||
user = ax25_findbyuid(current->euid);
|
||||
if (user) {
|
||||
nr->user_addr = user->call;
|
||||
ax25_uid_put(user);
|
||||
} else {
|
||||
if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
|
||||
release_sock(sk);
|
||||
dev_put(dev);
|
||||
return -EPERM;
|
||||
}
|
||||
user = source;
|
||||
nr->user_addr = *source;
|
||||
}
|
||||
|
||||
nr->user_addr = *user;
|
||||
nr->source_addr = *source;
|
||||
}
|
||||
|
||||
@ -604,7 +608,8 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
|
||||
struct sock *sk = sock->sk;
|
||||
struct nr_sock *nr = nr_sk(sk);
|
||||
struct sockaddr_ax25 *addr = (struct sockaddr_ax25 *)uaddr;
|
||||
ax25_address *user, *source = NULL;
|
||||
ax25_address *source = NULL;
|
||||
ax25_uid_assoc *user;
|
||||
struct net_device *dev;
|
||||
|
||||
lock_sock(sk);
|
||||
@ -645,16 +650,19 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
|
||||
}
|
||||
source = (ax25_address *)dev->dev_addr;
|
||||
|
||||
if ((user = ax25_findbyuid(current->euid)) == NULL) {
|
||||
user = ax25_findbyuid(current->euid);
|
||||
if (user) {
|
||||
nr->user_addr = user->call;
|
||||
ax25_uid_put(user);
|
||||
} else {
|
||||
if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) {
|
||||
dev_put(dev);
|
||||
release_sock(sk);
|
||||
return -EPERM;
|
||||
}
|
||||
user = source;
|
||||
nr->user_addr = *source;
|
||||
}
|
||||
|
||||
nr->user_addr = *user;
|
||||
nr->source_addr = *source;
|
||||
nr->device = dev;
|
||||
|
||||
|
Reference in New Issue
Block a user