Commit 9281acea6a3687ff0f262e0be31eac34895b95d7

Authored by Tejun Heo
Committed by Linus Torvalds
1 parent b45d527974

kallsyms: make KSYM_NAME_LEN include space for trailing '\0'

KSYM_NAME_LEN is peculiar in that it does not include the space for the
trailing '\0', forcing all users to use KSYM_NAME_LEN + 1 when allocating
buffer.  This is nonsense and error-prone.  Moreover, when the caller
forgets that it's very likely to subtly bite back by corrupting the stack
because the last position of the buffer is always cleared to zero.

This patch increments KSYM_NAME_LEN by one and updates code accordingly.

* off-by-one bug in asm-powerpc/kprobes.h::kprobe_lookup_name() macro
  is fixed.

* Where MODULE_NAME_LEN and KSYM_NAME_LEN were used together,
  MODULE_NAME_LEN was treated as if it didn't include space for the
  trailing '\0'.  Fix it.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Acked-by: Paulo Marques <pmarques@grupopie.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 11 changed files with 27 additions and 27 deletions Side-by-side Diff

arch/parisc/kernel/unwind.c
... ... @@ -242,7 +242,7 @@
242 242 #ifdef CONFIG_KALLSYMS
243 243 /* Handle some frequent special cases.... */
244 244 {
245   - char symname[KSYM_NAME_LEN+1];
  245 + char symname[KSYM_NAME_LEN];
246 246 char *modname;
247 247  
248 248 kallsyms_lookup(info->ip, NULL, NULL, &modname,
... ... @@ -283,7 +283,7 @@
283 283 static int proc_pid_wchan(struct task_struct *task, char *buffer)
284 284 {
285 285 unsigned long wchan;
286   - char symname[KSYM_NAME_LEN+1];
  286 + char symname[KSYM_NAME_LEN];
287 287  
288 288 wchan = get_wchan(task);
289 289  
include/asm-powerpc/kprobes.h
... ... @@ -65,10 +65,10 @@
65 65 } else if (name[0] != '.') \
66 66 addr = *(kprobe_opcode_t **)addr; \
67 67 } else { \
68   - char dot_name[KSYM_NAME_LEN+1]; \
  68 + char dot_name[KSYM_NAME_LEN]; \
69 69 dot_name[0] = '.'; \
70 70 dot_name[1] = '\0'; \
71   - strncat(dot_name, name, KSYM_NAME_LEN); \
  71 + strncat(dot_name, name, KSYM_NAME_LEN - 2); \
72 72 addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name); \
73 73 } \
74 74 }
include/linux/kallsyms.h
... ... @@ -7,9 +7,9 @@
7 7  
8 8 #include <linux/errno.h>
9 9  
10   -#define KSYM_NAME_LEN 127
11   -#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN + \
12   - 2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1)
  10 +#define KSYM_NAME_LEN 128
  11 +#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
  12 + 2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
13 13  
14 14 #ifdef CONFIG_KALLSYMS
15 15 /* Lookup the address for a symbol. Returns 0 if not found. */
... ... @@ -152,7 +152,7 @@
152 152 /* Lookup the address for this symbol. Returns 0 if not found. */
153 153 unsigned long kallsyms_lookup_name(const char *name)
154 154 {
155   - char namebuf[KSYM_NAME_LEN+1];
  155 + char namebuf[KSYM_NAME_LEN];
156 156 unsigned long i;
157 157 unsigned int off;
158 158  
... ... @@ -248,7 +248,7 @@
248 248 {
249 249 const char *msym;
250 250  
251   - namebuf[KSYM_NAME_LEN] = 0;
  251 + namebuf[KSYM_NAME_LEN - 1] = 0;
252 252 namebuf[0] = 0;
253 253  
254 254 if (is_ksym_addr(addr)) {
... ... @@ -265,7 +265,7 @@
265 265 /* see if it's in a module */
266 266 msym = module_address_lookup(addr, symbolsize, offset, modname);
267 267 if (msym)
268   - return strncpy(namebuf, msym, KSYM_NAME_LEN);
  268 + return strncpy(namebuf, msym, KSYM_NAME_LEN - 1);
269 269  
270 270 return NULL;
271 271 }
... ... @@ -273,7 +273,7 @@
273 273 int lookup_symbol_name(unsigned long addr, char *symname)
274 274 {
275 275 symname[0] = '\0';
276   - symname[KSYM_NAME_LEN] = '] = '\0';';
  276 + symname[KSYM_NAME_LEN - 1] = '] = '\0';';
277 277  
278 278 if (is_ksym_addr(addr)) {
279 279 unsigned long pos;
... ... @@ -291,7 +291,7 @@
291 291 unsigned long *offset, char *modname, char *name)
292 292 {
293 293 name[0] = '\0';
294   - name[KSYM_NAME_LEN] = '] = '\0';';
  294 + name[KSYM_NAME_LEN - 1] = '] = '\0';';
295 295  
296 296 if (is_ksym_addr(addr)) {
297 297 unsigned long pos;
... ... @@ -312,7 +312,7 @@
312 312 char *modname;
313 313 const char *name;
314 314 unsigned long offset, size;
315   - char namebuf[KSYM_NAME_LEN+1];
  315 + char namebuf[KSYM_NAME_LEN];
316 316  
317 317 name = kallsyms_lookup(address, &size, &offset, &modname, namebuf);
318 318 if (!name)
... ... @@ -342,8 +342,8 @@
342 342 unsigned long value;
343 343 unsigned int nameoff; /* If iterating in core kernel symbols */
344 344 char type;
345   - char name[KSYM_NAME_LEN+1];
346   - char module_name[MODULE_NAME_LEN + 1];
  345 + char name[KSYM_NAME_LEN];
  346 + char module_name[MODULE_NAME_LEN];
347 347 int exported;
348 348 };
349 349  
... ... @@ -379,7 +379,7 @@
379 379  
380 380 static void print_lock_name(struct lock_class *class)
381 381 {
382   - char str[KSYM_NAME_LEN + 1], c1, c2, c3, c4;
  382 + char str[KSYM_NAME_LEN], c1, c2, c3, c4;
383 383 const char *name;
384 384  
385 385 get_usage_chars(class, &c1, &c2, &c3, &c4);
... ... @@ -401,7 +401,7 @@
401 401 static void print_lockdep_cache(struct lockdep_map *lock)
402 402 {
403 403 const char *name;
404   - char str[KSYM_NAME_LEN + 1];
  404 + char str[KSYM_NAME_LEN];
405 405  
406 406 name = lock->name;
407 407 if (!name)
... ... @@ -2133,7 +2133,7 @@
2133 2133 sym = get_ksymbol(mod, addr, NULL, NULL);
2134 2134 if (!sym)
2135 2135 goto out;
2136   - strlcpy(symname, sym, KSYM_NAME_LEN + 1);
  2136 + strlcpy(symname, sym, KSYM_NAME_LEN);
2137 2137 mutex_unlock(&module_mutex);
2138 2138 return 0;
2139 2139 }
2140 2140  
... ... @@ -2158,9 +2158,9 @@
2158 2158 if (!sym)
2159 2159 goto out;
2160 2160 if (modname)
2161   - strlcpy(modname, mod->name, MODULE_NAME_LEN + 1);
  2161 + strlcpy(modname, mod->name, MODULE_NAME_LEN);
2162 2162 if (name)
2163   - strlcpy(name, sym, KSYM_NAME_LEN + 1);
  2163 + strlcpy(name, sym, KSYM_NAME_LEN);
2164 2164 mutex_unlock(&module_mutex);
2165 2165 return 0;
2166 2166 }
... ... @@ -2181,8 +2181,8 @@
2181 2181 *value = mod->symtab[symnum].st_value;
2182 2182 *type = mod->symtab[symnum].st_info;
2183 2183 strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
2184   - KSYM_NAME_LEN + 1);
2185   - strlcpy(module_name, mod->name, MODULE_NAME_LEN + 1);
  2184 + KSYM_NAME_LEN);
  2185 + strlcpy(module_name, mod->name, MODULE_NAME_LEN);
2186 2186 *exported = is_exported(name, mod);
2187 2187 mutex_unlock(&module_mutex);
2188 2188 return 0;
kernel/time/timer_list.c
... ... @@ -38,7 +38,7 @@
38 38  
39 39 static void print_name_offset(struct seq_file *m, void *sym)
40 40 {
41   - char symname[KSYM_NAME_LEN+1];
  41 + char symname[KSYM_NAME_LEN];
42 42  
43 43 if (lookup_symbol_name((unsigned long)sym, symname) < 0)
44 44 SEQ_printf(m, "<%p>", sym);
kernel/time/timer_stats.c
... ... @@ -269,7 +269,7 @@
269 269  
270 270 static void print_name_offset(struct seq_file *m, unsigned long addr)
271 271 {
272   - char symname[KSYM_NAME_LEN+1];
  272 + char symname[KSYM_NAME_LEN];
273 273  
274 274 if (lookup_symbol_name(addr, symname) < 0)
275 275 seq_printf(m, "<%p>", (void *)addr);
... ... @@ -4344,7 +4344,7 @@
4344 4344 {
4345 4345 #ifdef CONFIG_KALLSYMS
4346 4346 unsigned long offset, size;
4347   - char modname[MODULE_NAME_LEN + 1], name[KSYM_NAME_LEN + 1];
  4347 + char modname[MODULE_NAME_LEN], name[KSYM_NAME_LEN];
4348 4348  
4349 4349 if (lookup_symbol_attrs(address, &size, &offset, modname, name) == 0) {
4350 4350 seq_printf(m, "%s+%#lx/%#lx", name, offset, size);
... ... @@ -31,7 +31,7 @@
31 31 #include <string.h>
32 32 #include <ctype.h>
33 33  
34   -#define KSYM_NAME_LEN 127
  34 +#define KSYM_NAME_LEN 128
35 35  
36 36  
37 37 struct sym_entry {
... ... @@ -254,7 +254,7 @@
254 254 unsigned int i, k, off;
255 255 unsigned int best_idx[256];
256 256 unsigned int *markers;
257   - char buf[KSYM_NAME_LEN+1];
  257 + char buf[KSYM_NAME_LEN];
258 258  
259 259 printf("#include <asm/types.h>\n");
260 260 printf("#if BITS_PER_LONG == 64\n");