Although *lookup* APIs are safe, but better to pass size as an argument rather than using define KSYM_NAME_LEN. Because it can cause issue if called with lesser array size. Co-developed-by: Onkarnath <onkarnath.1@xxxxxxxxxxx> Signed-off-by: Onkarnath <onkarnath.1@xxxxxxxxxxx> Signed-off-by: Maninder Singh <maninder1.s@xxxxxxxxxxx> --- arch/hexagon/kernel/traps.c | 2 +- arch/powerpc/xmon/xmon.c | 4 ++-- fs/proc/base.c | 2 +- include/linux/kallsyms.h | 8 ++++---- include/linux/module.h | 8 ++++---- kernel/debug/kdb/kdb_support.c | 2 +- kernel/kallsyms.c | 24 ++++++++++++------------ kernel/kprobes.c | 4 ++-- kernel/locking/lockdep.c | 8 ++++---- kernel/locking/lockdep_internals.h | 2 +- kernel/locking/lockdep_proc.c | 4 ++-- kernel/module/kallsyms.c | 8 ++++---- kernel/trace/ftrace.c | 9 +++++---- kernel/trace/trace_kprobe.c | 2 +- kernel/trace/trace_output.c | 2 +- kernel/trace/trace_syscalls.c | 2 +- 16 files changed, 46 insertions(+), 45 deletions(-) diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c index 65b30b6ea226..a0306e96e82c 100644 --- a/arch/hexagon/kernel/traps.c +++ b/arch/hexagon/kernel/traps.c @@ -118,7 +118,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp, for (i = 0; i < kstack_depth_to_print; i++) { - name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr); + name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr, KSYM_NAME_LEN); printk("%s[%p] 0x%lx: %s + 0x%lx", loglvl, fp, ip, name, offset); if (((unsigned long) fp < low) || (high < (unsigned long) fp)) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 3441fc70ac92..183e2a55ba5c 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -1710,7 +1710,7 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp, if (setjmp(bus_error_jmp) == 0) { catch_memory_errors = 1; sync(); - name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr); + name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr, KSYM_NAME_LEN); if (name != NULL) { *startp = pc - offset; *endp = pc - offset + size; @@ -3730,7 +3730,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid, catch_memory_errors = 1; sync(); name = kallsyms_lookup(address, &size, &offset, &modname, - tmpstr); + tmpstr, KSYM_NAME_LEN); sync(); /* wait a little while to see if we get a machine check */ __delay(200); diff --git a/fs/proc/base.c b/fs/proc/base.c index 617816168748..939006f3b2b0 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -392,7 +392,7 @@ static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns, goto print0; wchan = get_wchan(task); - if (wchan && !lookup_symbol_name(wchan, symname)) { + if (wchan && !lookup_symbol_name(wchan, symname, KSYM_NAME_LEN)) { seq_puts(m, symname); return 0; } diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 598ff08c72d6..8fe535fd848a 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -81,7 +81,7 @@ extern int kallsyms_lookup_size_offset(unsigned long addr, const char *kallsyms_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, - char **modname, char *namebuf); + char **modname, char *namebuf, size_t size); /* Look up a kernel symbol and return it in a text buffer. */ extern int sprint_symbol(char *buffer, size_t size, unsigned long address); @@ -90,7 +90,7 @@ extern int sprint_symbol_no_offset(char *buffer, size_t size, unsigned long addr extern int sprint_backtrace(char *buffer, size_t size, unsigned long address); extern int sprint_backtrace_build_id(char *buffer, size_t size, unsigned long address); -int lookup_symbol_name(unsigned long addr, char *symname); +int lookup_symbol_name(unsigned long addr, char *symname, size_t size); int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name); /* How and when do we show kallsyms values? */ @@ -113,7 +113,7 @@ static inline int kallsyms_lookup_size_offset(unsigned long addr, static inline const char *kallsyms_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, - char **modname, char *namebuf) + char **modname, char *namebuf, size_t size) { return NULL; } @@ -148,7 +148,7 @@ static inline int sprint_backtrace_build_id(char *buffer, size_t size, unsigned return 0; } -static inline int lookup_symbol_name(unsigned long addr, char *symname) +static inline int lookup_symbol_name(unsigned long addr, char *symname, size_t size) { return -ERANGE; } diff --git a/include/linux/module.h b/include/linux/module.h index abd9fa916b7d..9b91209d615f 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -656,8 +656,8 @@ const char *module_address_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char **modname, const unsigned char **modbuildid, - char *namebuf); -int lookup_module_symbol_name(unsigned long addr, char *symname); + char *namebuf, size_t buf_size); +int lookup_module_symbol_name(unsigned long addr, char *symname, size_t size); int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name); int register_module_notifier(struct notifier_block *nb); @@ -756,12 +756,12 @@ static inline const char *module_address_lookup(unsigned long addr, unsigned long *offset, char **modname, const unsigned char **modbuildid, - char *namebuf) + char *namebuf, size_t buf_size) { return NULL; } -static inline int lookup_module_symbol_name(unsigned long addr, char *symname) +static inline int lookup_module_symbol_name(unsigned long addr, char *symname, size_t size) { return -ERANGE; } diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c index 0a39497140bf..bf19e9587c23 100644 --- a/kernel/debug/kdb/kdb_support.c +++ b/kernel/debug/kdb/kdb_support.c @@ -92,7 +92,7 @@ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) goto out; symtab->sym_name = kallsyms_lookup(addr, &symbolsize , &offset, - (char **)(&symtab->mod_name), namebuf); + (char **)(&symtab->mod_name), namebuf, KSYM_NAME_LEN); if (offset > 8*1024*1024) { symtab->sym_name = NULL; addr = offset = symbolsize = 0; diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 9e4316fe0ba1..d6efce28505d 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -342,18 +342,18 @@ int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, get_symbol_pos(addr, symbolsize, offset); return 1; } - return !!module_address_lookup(addr, symbolsize, offset, NULL, NULL, namebuf) || + return !!module_address_lookup(addr, symbolsize, offset, NULL, NULL, namebuf, KSYM_NAME_LEN) || !!__bpf_address_lookup(addr, symbolsize, offset, namebuf); } static const char *kallsyms_lookup_buildid(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char **modname, - const unsigned char **modbuildid, char *namebuf) + const unsigned char **modbuildid, char *namebuf, size_t size) { const char *ret; - namebuf[KSYM_NAME_LEN - 1] = 0; + namebuf[size - 1] = 0; namebuf[0] = 0; if (is_ksym_addr(addr)) { @@ -362,7 +362,7 @@ static const char *kallsyms_lookup_buildid(unsigned long addr, pos = get_symbol_pos(addr, symbolsize, offset); /* Grab name */ kallsyms_expand_symbol(get_symbol_offset(pos), - namebuf, KSYM_NAME_LEN); + namebuf, size); if (modname) *modname = NULL; if (modbuildid) @@ -374,7 +374,7 @@ static const char *kallsyms_lookup_buildid(unsigned long addr, /* See if it's in a module or a BPF JITed image. */ ret = module_address_lookup(addr, symbolsize, offset, - modname, modbuildid, namebuf); + modname, modbuildid, namebuf, size); if (!ret) ret = bpf_address_lookup(addr, symbolsize, offset, modname, namebuf); @@ -398,18 +398,18 @@ static const char *kallsyms_lookup_buildid(unsigned long addr, const char *kallsyms_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, - char **modname, char *namebuf) + char **modname, char *namebuf, size_t size) { return kallsyms_lookup_buildid(addr, symbolsize, offset, modname, - NULL, namebuf); + NULL, namebuf, size); } -int lookup_symbol_name(unsigned long addr, char *symname) +int lookup_symbol_name(unsigned long addr, char *symname, size_t size) { int res; symname[0] = '\0'; - symname[KSYM_NAME_LEN - 1] = '\0'; + symname[size - 1] = '\0'; if (is_ksym_addr(addr)) { unsigned long pos; @@ -417,11 +417,11 @@ int lookup_symbol_name(unsigned long addr, char *symname) pos = get_symbol_pos(addr, NULL, NULL); /* Grab name */ kallsyms_expand_symbol(get_symbol_offset(pos), - symname, KSYM_NAME_LEN); + symname, size); goto found; } /* See if it's in a module. */ - res = lookup_module_symbol_name(addr, symname); + res = lookup_module_symbol_name(addr, symname, size); if (res) return res; @@ -470,7 +470,7 @@ static int __sprint_symbol(char *buffer, size_t buf_size, unsigned long address, address += symbol_offset; name = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid, - buffer); + buffer, buf_size); if (!name) return scnprintf(buffer, buf_size, "0x%lx", address - symbol_offset); diff --git a/kernel/kprobes.c b/kernel/kprobes.c index dd58c0be9ce2..3b362b70e72b 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1478,7 +1478,7 @@ bool within_kprobe_blacklist(unsigned long addr) return true; /* Check if the address is on a suffixed-symbol */ - if (!lookup_symbol_name(addr, symname)) { + if (!lookup_symbol_name(addr, symname, KSYM_NAME_LEN)) { p = strchr(symname, '.'); if (!p) return false; @@ -2806,7 +2806,7 @@ static int show_kprobe_addr(struct seq_file *pi, void *v) preempt_disable(); hlist_for_each_entry_rcu(p, head, hlist) { sym = kallsyms_lookup((unsigned long)p->addr, NULL, - &offset, &modname, namebuf); + &offset, &modname, namebuf, KSYM_NAME_LEN); if (kprobe_aggrprobe(p)) { list_for_each_entry_rcu(kp, &p->list, list) report_probe(pi, kp, sym, offset, modname, p); diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 81e87280513e..c74bbf90fdfb 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -659,9 +659,9 @@ static const char *usage_str[] = }; #endif -const char *__get_key_name(const struct lockdep_subclass_key *key, char *str) +const char *__get_key_name(const struct lockdep_subclass_key *key, char *str, size_t size) { - return kallsyms_lookup((unsigned long)key, NULL, NULL, NULL, str); + return kallsyms_lookup((unsigned long)key, NULL, NULL, NULL, str, size); } static inline unsigned long lock_flag(enum lock_usage_bit bit) @@ -715,7 +715,7 @@ static void __print_lock_name(struct lock_class *class) name = class->name; if (!name) { - name = __get_key_name(class->key, str); + name = __get_key_name(class->key, str, KSYM_NAME_LEN); printk(KERN_CONT "%s", name); } else { printk(KERN_CONT "%s", name); @@ -746,7 +746,7 @@ static void print_lockdep_cache(struct lockdep_map *lock) name = lock->name; if (!name) - name = __get_key_name(lock->key->subkeys, str); + name = __get_key_name(lock->key->subkeys, str, KSYM_NAME_LEN); printk(KERN_CONT "%s", name); } diff --git a/kernel/locking/lockdep_internals.h b/kernel/locking/lockdep_internals.h index bbe9000260d0..ab32ee6a0c87 100644 --- a/kernel/locking/lockdep_internals.h +++ b/kernel/locking/lockdep_internals.h @@ -129,7 +129,7 @@ extern void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS]); extern const char *__get_key_name(const struct lockdep_subclass_key *key, - char *str); + char *str, size_t size); struct lock_class *lock_chain_get_class(struct lock_chain *chain, int i); diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index 15fdc7fa5c68..bf4ca5ec109e 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c @@ -63,7 +63,7 @@ static void print_name(struct seq_file *m, struct lock_class *class) const char *name = class->name; if (!name) { - name = __get_key_name(class->key, str); + name = __get_key_name(class->key, str, KSYM_NAME_LEN); seq_printf(m, "%s", name); } else{ seq_printf(m, "%s", name); @@ -485,7 +485,7 @@ static void seq_stats(struct seq_file *m, struct lock_stat_data *data) char str[KSYM_NAME_LEN]; const char *key_name; - key_name = __get_key_name(ckey, str); + key_name = __get_key_name(ckey, str, KSYM_NAME_LEN); snprintf(name, namelen, "%s", key_name); } else { snprintf(name, namelen, "%s", cname); diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c index 3e11523bc6f6..c982860405c6 100644 --- a/kernel/module/kallsyms.c +++ b/kernel/module/kallsyms.c @@ -320,7 +320,7 @@ const char *module_address_lookup(unsigned long addr, unsigned long *offset, char **modname, const unsigned char **modbuildid, - char *namebuf) + char *namebuf, size_t buf_size) { const char *ret = NULL; struct module *mod; @@ -342,7 +342,7 @@ const char *module_address_lookup(unsigned long addr, } /* Make a copy in here where it's safe */ if (ret) { - strncpy(namebuf, ret, KSYM_NAME_LEN - 1); + strncpy(namebuf, ret, buf_size - 1); ret = namebuf; } preempt_enable(); @@ -350,7 +350,7 @@ const char *module_address_lookup(unsigned long addr, return ret; } -int lookup_module_symbol_name(unsigned long addr, char *symname) +int lookup_module_symbol_name(unsigned long addr, char *symname, size_t size) { struct module *mod; @@ -365,7 +365,7 @@ int lookup_module_symbol_name(unsigned long addr, char *symname) if (!sym) goto out; - strscpy(symname, sym, KSYM_NAME_LEN); + strscpy(symname, sym, size); preempt_enable(); return 0; } diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index c12bcd26cb17..4d9a8621eaac 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -520,7 +520,7 @@ static int function_stat_show(struct seq_file *m, void *v) goto out; #endif - kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); + kallsyms_lookup(rec->ip, NULL, NULL, NULL, str, KSYM_SYMBOL_LEN); seq_printf(m, " %-30.30s %10lu", str, rec->counter); #ifdef CONFIG_FUNCTION_GRAPH_TRACER @@ -3980,7 +3980,7 @@ ftrace_match_record(struct dyn_ftrace *rec, struct ftrace_glob *func_g, char str[KSYM_SYMBOL_LEN]; char *modname; - kallsyms_lookup(rec->ip, NULL, NULL, &modname, str); + kallsyms_lookup(rec->ip, NULL, NULL, &modname, str, KSYM_SYMBOL_LEN); if (mod_g) { int mod_matches = (modname) ? ftrace_match(modname, mod_g) : 0; @@ -4738,7 +4738,7 @@ unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr, if (func_g.search) { kallsyms_lookup(entry->ip, NULL, NULL, - NULL, str); + NULL, str, KSYM_SYMBOL_LEN); if (!ftrace_match(str, &func_g)) continue; } @@ -6846,7 +6846,8 @@ static void save_ftrace_mod_rec(struct ftrace_mod_map *mod_map, char *modname; const char *ret; - ret = kallsyms_lookup(rec->ip, &symsize, &offset, &modname, str); + ret = kallsyms_lookup(rec->ip, &symsize, &offset, &modname, + str, KSYM_SYMBOL_LEN); if (!ret) return; diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 47cebef78532..8a1d2a0dc2dc 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -456,7 +456,7 @@ static bool within_notrace_func(struct trace_kprobe *tk) return false; /* Check if the address is on a suffixed-symbol */ - if (!lookup_symbol_name(addr, symname)) { + if (!lookup_symbol_name(addr, symname, KSYM_NAME_LEN)) { p = strchr(symname, '.'); if (!p) return true; diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 2a6ec049cab5..0d3e1c9b59fb 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -364,7 +364,7 @@ trace_seq_print_sym(struct trace_seq *s, unsigned long address, bool offset) if (offset) sprint_symbol(str, KSYM_SYMBOL_LEN, address); else - kallsyms_lookup(address, NULL, NULL, NULL, str); + kallsyms_lookup(address, NULL, NULL, NULL, str, KSYM_SYMBOL_LEN); name = kretprobed(str, address); if (name && strlen(name)) { diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index f755bde42fd0..3a67877ce658 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -89,7 +89,7 @@ find_syscall_meta(unsigned long syscall) start = __start_syscalls_metadata; stop = __stop_syscalls_metadata; - kallsyms_lookup(syscall, NULL, NULL, NULL, str); + kallsyms_lookup(syscall, NULL, NULL, NULL, str, KSYM_SYMBOL_LEN); if (arch_syscall_match_sym_name(str, "sys_ni_syscall")) return NULL; -- 2.17.1