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/ax25/ax25_route.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/ax25/ax25_route.c')
-rw-r--r-- | net/ax25/ax25_route.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 44b99b1ff9f8..c288526da4ce 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c | |||
@@ -422,8 +422,8 @@ static inline void ax25_adjust_path(ax25_address *addr, ax25_digi *digipeat) | |||
422 | */ | 422 | */ |
423 | int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) | 423 | int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) |
424 | { | 424 | { |
425 | ax25_uid_assoc *user; | ||
425 | ax25_route *ax25_rt; | 426 | ax25_route *ax25_rt; |
426 | ax25_address *call; | ||
427 | int err; | 427 | int err; |
428 | 428 | ||
429 | if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL) | 429 | if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL) |
@@ -434,16 +434,18 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) | |||
434 | goto put; | 434 | goto put; |
435 | } | 435 | } |
436 | 436 | ||
437 | if ((call = ax25_findbyuid(current->euid)) == NULL) { | 437 | user = ax25_findbyuid(current->euid); |
438 | if (user) { | ||
439 | ax25->source_addr = user->call; | ||
440 | ax25_uid_put(user); | ||
441 | } else { | ||
438 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { | 442 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { |
439 | err = -EPERM; | 443 | err = -EPERM; |
440 | goto put; | 444 | goto put; |
441 | } | 445 | } |
442 | call = (ax25_address *)ax25->ax25_dev->dev->dev_addr; | 446 | ax25->source_addr = *(ax25_address *)ax25->ax25_dev->dev->dev_addr; |
443 | } | 447 | } |
444 | 448 | ||
445 | ax25->source_addr = *call; | ||
446 | |||
447 | if (ax25_rt->digipeat != NULL) { | 449 | if (ax25_rt->digipeat != NULL) { |
448 | if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { | 450 | if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { |
449 | err = -ENOMEM; | 451 | err = -ENOMEM; |