diff options
| author | Ralf Baechle <ralf@linux-mips.org> | 2009-08-17 21:05:32 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-08-17 21:05:32 -0400 |
| commit | c6ba973b8fa97422aab4204f7d79f1d413cde925 (patch) | |
| tree | 2fbd38ba11da09f18a6ba922c772b41364b03b20 | |
| parent | 68eac4602b9104cdaa6c18b3edd914cececa6a1e (diff) | |
NETROM: Fix use of static buffer
The static variable used by nr_call_to_digi might result in corruption if
multiple threads are trying to usee a node or neighbour via ioctl. Fixed
by having the caller pass a structure in. This is safe because nr_add_node
rsp. nr_add_neigh will allocate a permanent structure, if needed.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/netrom/nr_route.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c index e943c16552a2..4eb1ac9a7679 100644 --- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c | |||
| @@ -630,23 +630,23 @@ out: | |||
| 630 | return dev; | 630 | return dev; |
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | static ax25_digi *nr_call_to_digi(int ndigis, ax25_address *digipeaters) | 633 | static ax25_digi *nr_call_to_digi(ax25_digi *digi, int ndigis, |
| 634 | ax25_address *digipeaters) | ||
| 634 | { | 635 | { |
| 635 | static ax25_digi ax25_digi; | ||
| 636 | int i; | 636 | int i; |
| 637 | 637 | ||
| 638 | if (ndigis == 0) | 638 | if (ndigis == 0) |
| 639 | return NULL; | 639 | return NULL; |
| 640 | 640 | ||
| 641 | for (i = 0; i < ndigis; i++) { | 641 | for (i = 0; i < ndigis; i++) { |
| 642 | ax25_digi.calls[i] = digipeaters[i]; | 642 | digi->calls[i] = digipeaters[i]; |
| 643 | ax25_digi.repeated[i] = 0; | 643 | digi->repeated[i] = 0; |
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | ax25_digi.ndigi = ndigis; | 646 | digi->ndigi = ndigis; |
| 647 | ax25_digi.lastrepeat = -1; | 647 | digi->lastrepeat = -1; |
| 648 | 648 | ||
| 649 | return &ax25_digi; | 649 | return digi; |
| 650 | } | 650 | } |
| 651 | 651 | ||
| 652 | /* | 652 | /* |
| @@ -656,6 +656,7 @@ int nr_rt_ioctl(unsigned int cmd, void __user *arg) | |||
| 656 | { | 656 | { |
| 657 | struct nr_route_struct nr_route; | 657 | struct nr_route_struct nr_route; |
| 658 | struct net_device *dev; | 658 | struct net_device *dev; |
| 659 | ax25_digi digi; | ||
| 659 | int ret; | 660 | int ret; |
| 660 | 661 | ||
| 661 | switch (cmd) { | 662 | switch (cmd) { |
| @@ -673,13 +674,15 @@ int nr_rt_ioctl(unsigned int cmd, void __user *arg) | |||
| 673 | ret = nr_add_node(&nr_route.callsign, | 674 | ret = nr_add_node(&nr_route.callsign, |
| 674 | nr_route.mnemonic, | 675 | nr_route.mnemonic, |
| 675 | &nr_route.neighbour, | 676 | &nr_route.neighbour, |
| 676 | nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters), | 677 | nr_call_to_digi(&digi, nr_route.ndigis, |
| 678 | nr_route.digipeaters), | ||
| 677 | dev, nr_route.quality, | 679 | dev, nr_route.quality, |
| 678 | nr_route.obs_count); | 680 | nr_route.obs_count); |
| 679 | break; | 681 | break; |
| 680 | case NETROM_NEIGH: | 682 | case NETROM_NEIGH: |
| 681 | ret = nr_add_neigh(&nr_route.callsign, | 683 | ret = nr_add_neigh(&nr_route.callsign, |
| 682 | nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters), | 684 | nr_call_to_digi(&digi, nr_route.ndigis, |
| 685 | nr_route.digipeaters), | ||
| 683 | dev, nr_route.quality); | 686 | dev, nr_route.quality); |
| 684 | break; | 687 | break; |
| 685 | default: | 688 | default: |
