diff options
author | Eric Dumazet <dada1@cosmosbay.com> | 2008-01-15 02:09:56 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:02:13 -0500 |
commit | 28d36e3702fcbed73c38e877bcf2a8f8946b7f3d (patch) | |
tree | e06248b21566229ec99f0ca9249d1deff6f467d9 | |
parent | 39a6d06300128d32f361f4f790beba0ca83730eb (diff) |
[FIB]: Avoid using static variables without proper locking
fib_trie_seq_show() uses two helper functions, rtn_scope() and
rtn_type() that can write to static storage without locking.
Just pass to them a temporary buffer to avoid potential corruption
(probably not triggerable but still...)
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/fib_trie.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 18fb73958a49..72c78c2209d5 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -2284,10 +2284,8 @@ static void seq_indent(struct seq_file *seq, int n) | |||
2284 | while (n-- > 0) seq_puts(seq, " "); | 2284 | while (n-- > 0) seq_puts(seq, " "); |
2285 | } | 2285 | } |
2286 | 2286 | ||
2287 | static inline const char *rtn_scope(enum rt_scope_t s) | 2287 | static inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s) |
2288 | { | 2288 | { |
2289 | static char buf[32]; | ||
2290 | |||
2291 | switch (s) { | 2289 | switch (s) { |
2292 | case RT_SCOPE_UNIVERSE: return "universe"; | 2290 | case RT_SCOPE_UNIVERSE: return "universe"; |
2293 | case RT_SCOPE_SITE: return "site"; | 2291 | case RT_SCOPE_SITE: return "site"; |
@@ -2295,7 +2293,7 @@ static inline const char *rtn_scope(enum rt_scope_t s) | |||
2295 | case RT_SCOPE_HOST: return "host"; | 2293 | case RT_SCOPE_HOST: return "host"; |
2296 | case RT_SCOPE_NOWHERE: return "nowhere"; | 2294 | case RT_SCOPE_NOWHERE: return "nowhere"; |
2297 | default: | 2295 | default: |
2298 | snprintf(buf, sizeof(buf), "scope=%d", s); | 2296 | snprintf(buf, len, "scope=%d", s); |
2299 | return buf; | 2297 | return buf; |
2300 | } | 2298 | } |
2301 | } | 2299 | } |
@@ -2315,13 +2313,11 @@ static const char *rtn_type_names[__RTN_MAX] = { | |||
2315 | [RTN_XRESOLVE] = "XRESOLVE", | 2313 | [RTN_XRESOLVE] = "XRESOLVE", |
2316 | }; | 2314 | }; |
2317 | 2315 | ||
2318 | static inline const char *rtn_type(unsigned t) | 2316 | static inline const char *rtn_type(char *buf, size_t len, unsigned t) |
2319 | { | 2317 | { |
2320 | static char buf[32]; | ||
2321 | |||
2322 | if (t < __RTN_MAX && rtn_type_names[t]) | 2318 | if (t < __RTN_MAX && rtn_type_names[t]) |
2323 | return rtn_type_names[t]; | 2319 | return rtn_type_names[t]; |
2324 | snprintf(buf, sizeof(buf), "type %u", t); | 2320 | snprintf(buf, len, "type %u", t); |
2325 | return buf; | 2321 | return buf; |
2326 | } | 2322 | } |
2327 | 2323 | ||
@@ -2359,13 +2355,19 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v) | |||
2359 | seq_printf(seq, " |-- %d.%d.%d.%d\n", NIPQUAD(val)); | 2355 | seq_printf(seq, " |-- %d.%d.%d.%d\n", NIPQUAD(val)); |
2360 | for (i = 32; i >= 0; i--) { | 2356 | for (i = 32; i >= 0; i--) { |
2361 | struct leaf_info *li = find_leaf_info(l, i); | 2357 | struct leaf_info *li = find_leaf_info(l, i); |
2358 | |||
2362 | if (li) { | 2359 | if (li) { |
2363 | struct fib_alias *fa; | 2360 | struct fib_alias *fa; |
2361 | |||
2364 | list_for_each_entry_rcu(fa, &li->falh, fa_list) { | 2362 | list_for_each_entry_rcu(fa, &li->falh, fa_list) { |
2363 | char buf1[32], buf2[32]; | ||
2364 | |||
2365 | seq_indent(seq, iter->depth+1); | 2365 | seq_indent(seq, iter->depth+1); |
2366 | seq_printf(seq, " /%d %s %s", i, | 2366 | seq_printf(seq, " /%d %s %s", i, |
2367 | rtn_scope(fa->fa_scope), | 2367 | rtn_scope(buf1, sizeof(buf1), |
2368 | rtn_type(fa->fa_type)); | 2368 | fa->fa_scope), |
2369 | rtn_type(buf2, sizeof(buf2), | ||
2370 | fa->fa_type)); | ||
2369 | if (fa->fa_tos) | 2371 | if (fa->fa_tos) |
2370 | seq_printf(seq, "tos =%d\n", | 2372 | seq_printf(seq, "tos =%d\n", |
2371 | fa->fa_tos); | 2373 | fa->fa_tos); |