diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig.debug | 4 | ||||
-rw-r--r-- | lib/bootconfig.c | 40 | ||||
-rw-r--r-- | lib/dynamic_debug.c | 82 | ||||
-rw-r--r-- | lib/glob.c | 2 | ||||
-rw-r--r-- | lib/kobject.c | 9 | ||||
-rw-r--r-- | lib/memregion.c | 1 | ||||
-rw-r--r-- | lib/random32.c | 2 | ||||
-rw-r--r-- | lib/string.c | 24 | ||||
-rw-r--r-- | lib/test_firmware.c | 9 | ||||
-rw-r--r-- | lib/test_rhashtable.c | 2 | ||||
-rw-r--r-- | lib/vsprintf.c | 7 | ||||
-rw-r--r-- | lib/xz/xz_dec_lzma2.c | 4 | ||||
-rw-r--r-- | lib/xz/xz_dec_stream.c | 16 | ||||
-rw-r--r-- | lib/zstd/decompress.c | 10 |
14 files changed, 133 insertions, 79 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index e068c3c7189a..0c781f912f9f 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -520,8 +520,8 @@ config DEBUG_FS_ALLOW_NONE endchoice source "lib/Kconfig.kgdb" - source "lib/Kconfig.ubsan" +source "lib/Kconfig.kcsan" endmenu @@ -1620,8 +1620,6 @@ config PROVIDE_OHCI1394_DMA_INIT source "samples/Kconfig" -source "lib/Kconfig.kcsan" - config ARCH_HAS_DEVMEM_IS_ALLOWED bool diff --git a/lib/bootconfig.c b/lib/bootconfig.c index a5f701161f6b..649ed44f199c 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -31,6 +31,8 @@ static size_t xbc_data_size __initdata; static struct xbc_node *last_parent __initdata; static const char *xbc_err_msg __initdata; static int xbc_err_pos __initdata; +static int open_brace[XBC_DEPTH_MAX] __initdata; +static int brace_index __initdata; static int __init xbc_parse_error(const char *msg, const char *p) { @@ -431,27 +433,27 @@ static char *skip_spaces_until_newline(char *p) return p; } -static int __init __xbc_open_brace(void) +static int __init __xbc_open_brace(char *p) { - /* Mark the last key as open brace */ - last_parent->next = XBC_NODE_MAX; + /* Push the last key as open brace */ + open_brace[brace_index++] = xbc_node_index(last_parent); + if (brace_index >= XBC_DEPTH_MAX) + return xbc_parse_error("Exceed max depth of braces", p); return 0; } static int __init __xbc_close_brace(char *p) { - struct xbc_node *node; - - if (!last_parent || last_parent->next != XBC_NODE_MAX) + brace_index--; + if (!last_parent || brace_index < 0 || + (open_brace[brace_index] != xbc_node_index(last_parent))) return xbc_parse_error("Unexpected closing brace", p); - node = last_parent; - node->next = 0; - do { - node = xbc_node_get_parent(node); - } while (node && node->next != XBC_NODE_MAX); - last_parent = node; + if (brace_index == 0) + last_parent = NULL; + else + last_parent = &xbc_nodes[open_brace[brace_index - 1]]; return 0; } @@ -492,8 +494,8 @@ static int __init __xbc_parse_value(char **__v, char **__n) break; } if (strchr(",;\n#}", c)) { - v = strim(v); *p++ = '\0'; + v = strim(v); break; } } @@ -661,7 +663,7 @@ static int __init xbc_open_brace(char **k, char *n) return ret; *k = n; - return __xbc_open_brace(); + return __xbc_open_brace(n - 1); } static int __init xbc_close_brace(char **k, char *n) @@ -681,6 +683,13 @@ static int __init xbc_verify_tree(void) int i, depth, len, wlen; struct xbc_node *n, *m; + /* Brace closing */ + if (brace_index) { + n = &xbc_nodes[open_brace[brace_index]]; + return xbc_parse_error("Brace is not closed", + xbc_node_get_data(n)); + } + /* Empty tree */ if (xbc_node_num == 0) { xbc_parse_error("Empty config", xbc_data); @@ -745,6 +754,7 @@ void __init xbc_destroy_all(void) xbc_node_num = 0; memblock_free(__pa(xbc_nodes), sizeof(struct xbc_node) * XBC_NODE_MAX); xbc_nodes = NULL; + brace_index = 0; } /** @@ -817,7 +827,7 @@ int __init xbc_init(char *buf, const char **emsg, int *epos) q - 2); break; } - /* Fall through */ + /* fall through */ case '=': ret = xbc_parse_kv(&p, q, c); break; diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 1d012e597cc3..2d4dfd44b0fa 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -353,8 +353,7 @@ static int check_set(const char **dest, char *src, char *name) /* * Parse words[] as a ddebug query specification, which is a series - * of (keyword, value) pairs or combined keyword=value terms, - * chosen from these possibilities: + * of (keyword, value) pairs chosen from these possibilities: * * func <function-name> * file <full-pathname> @@ -373,34 +372,22 @@ static int ddebug_parse_query(char *words[], int nwords, unsigned int i; int rc = 0; char *fline; - char *keyword, *arg; + + /* check we have an even number of words */ + if (nwords % 2 != 0) { + pr_err("expecting pairs of match-spec <value>\n"); + return -EINVAL; + } if (modname) /* support $modname.dyndbg=<multiple queries> */ query->module = modname; - for (i = 0; i < nwords; i++) { - /* accept keyword=arg */ - vpr_info("%d w:%s\n", i, words[i]); - - keyword = words[i]; - arg = strchr(keyword, '='); - if (arg) { - *arg++ = '\0'; - } else { - i++; /* next word is arg */ - if (!(i < nwords)) { - pr_err("missing arg to keyword: %s\n", keyword); - return -EINVAL; - } - arg = words[i]; - } - vpr_info("%d key:%s arg:%s\n", i, keyword, arg); - - if (!strcmp(keyword, "func")) { - rc = check_set(&query->function, arg, "func"); - } else if (!strcmp(keyword, "file")) { - if (check_set(&query->filename, arg, "file")) + for (i = 0; i < nwords; i += 2) { + if (!strcmp(words[i], "func")) { + rc = check_set(&query->function, words[i+1], "func"); + } else if (!strcmp(words[i], "file")) { + if (check_set(&query->filename, words[i+1], "file")) return -EINVAL; /* tail :$info is function or line-range */ @@ -416,18 +403,18 @@ static int ddebug_parse_query(char *words[], int nwords, if (parse_linerange(query, fline)) return -EINVAL; } - } else if (!strcmp(keyword, "module")) { - rc = check_set(&query->module, arg, "module"); - } else if (!strcmp(keyword, "format")) { - string_unescape_inplace(arg, UNESCAPE_SPACE | + } else if (!strcmp(words[i], "module")) { + rc = check_set(&query->module, words[i+1], "module"); + } else if (!strcmp(words[i], "format")) { + string_unescape_inplace(words[i+1], UNESCAPE_SPACE | UNESCAPE_OCTAL | UNESCAPE_SPECIAL); - rc = check_set(&query->format, arg, "format"); - } else if (!strcmp(keyword, "line")) { - if (parse_linerange(query, arg)) + rc = check_set(&query->format, words[i+1], "format"); + } else if (!strcmp(words[i], "line")) { + if (parse_linerange(query, words[i+1])) return -EINVAL; } else { - pr_err("unknown keyword \"%s\"\n", keyword); + pr_err("unknown keyword \"%s\"\n", words[i]); return -EINVAL; } if (rc) @@ -525,7 +512,7 @@ static int ddebug_exec_query(char *query_string, const char *modname) last error or number of matching callsites. Module name is either in param (for boot arg) or perhaps in query string. */ -int ddebug_exec_queries(char *query, const char *modname) +static int ddebug_exec_queries(char *query, const char *modname) { char *split; int i, errs = 0, exitcode = 0, rc, nfound = 0; @@ -557,7 +544,30 @@ int ddebug_exec_queries(char *query, const char *modname) return exitcode; return nfound; } -EXPORT_SYMBOL_GPL(ddebug_exec_queries); + +/** + * dynamic_debug_exec_queries - select and change dynamic-debug prints + * @query: query-string described in admin-guide/dynamic-debug-howto + * @modname: string containing module name, usually &module.mod_name + * + * This uses the >/proc/dynamic_debug/control reader, allowing module + * authors to modify their dynamic-debug callsites. The modname is + * canonically struct module.mod_name, but can also be null or a + * module-wildcard, for example: "drm*". + */ +int dynamic_debug_exec_queries(const char *query, const char *modname) +{ + int rc; + char *qry = kstrndup(query, PAGE_SIZE, GFP_KERNEL); + + if (!query) + return -ENOMEM; + + rc = ddebug_exec_queries(qry, modname); + kfree(qry); + return rc; +} +EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries); #define PREFIX_SIZE 64 @@ -947,7 +957,7 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, list_add(&dt->link, &ddebug_tables); mutex_unlock(&ddebug_lock); - v2pr_info("%u debug prints in module %s\n", n, dt->mod_name); + v2pr_info("%3u debug prints in module %s\n", n, dt->mod_name); return 0; } diff --git a/lib/glob.c b/lib/glob.c index 0ba3ea86b546..52e3ed7e4a9b 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -102,7 +102,7 @@ bool __pure glob_match(char const *pat, char const *str) break; case '\\': d = *pat++; - /*FALLTHROUGH*/ + /* fall through */ default: /* Literal character */ literal: if (c == d) { diff --git a/lib/kobject.c b/lib/kobject.c index 3afb939f2a1c..ea53b30cf483 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -604,9 +604,6 @@ static void __kobject_del(struct kobject *kobj) struct kernfs_node *sd; const struct kobj_type *ktype; - if (!kobj) - return; - sd = kobj->sd; ktype = get_ktype(kobj); @@ -637,8 +634,12 @@ static void __kobject_del(struct kobject *kobj) */ void kobject_del(struct kobject *kobj) { - struct kobject *parent = kobj->parent; + struct kobject *parent; + + if (!kobj) + return; + parent = kobj->parent; __kobject_del(kobj); kobject_put(parent); } diff --git a/lib/memregion.c b/lib/memregion.c index 77c85b5251da..be5cfa5a3b57 100644 --- a/lib/memregion.c +++ b/lib/memregion.c @@ -2,6 +2,7 @@ /* identifiers for device / performance-differentiated memory regions */ #include <linux/idr.h> #include <linux/types.h> +#include <linux/memregion.h> static DEFINE_IDA(memregion_ids); diff --git a/lib/random32.c b/lib/random32.c index 932345323af0..dfb9981ab798 100644 --- a/lib/random32.c +++ b/lib/random32.c @@ -49,7 +49,7 @@ static inline void prandom_state_selftest(void) } #endif -DEFINE_PER_CPU(struct rnd_state, net_rand_state); +DEFINE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy; /** * prandom_u32_state - seeded pseudo-random number generator. diff --git a/lib/string.c b/lib/string.c index 6012c385fb31..4288e0158d47 100644 --- a/lib/string.c +++ b/lib/string.c @@ -272,6 +272,30 @@ ssize_t strscpy_pad(char *dest, const char *src, size_t count) } EXPORT_SYMBOL(strscpy_pad); +/** + * stpcpy - copy a string from src to dest returning a pointer to the new end + * of dest, including src's %NUL-terminator. May overrun dest. + * @dest: pointer to end of string being copied into. Must be large enough + * to receive copy. + * @src: pointer to the beginning of string being copied from. Must not overlap + * dest. + * + * stpcpy differs from strcpy in a key way: the return value is a pointer + * to the new %NUL-terminating character in @dest. (For strcpy, the return + * value is a pointer to the start of @dest). This interface is considered + * unsafe as it doesn't perform bounds checking of the inputs. As such it's + * not recommended for usage. Instead, its definition is provided in case + * the compiler lowers other libcalls to stpcpy. + */ +char *stpcpy(char *__restrict__ dest, const char *__restrict__ src); +char *stpcpy(char *__restrict__ dest, const char *__restrict__ src) +{ + while ((*dest++ = *src++) != '\0') + /* nothing */; + return --dest; +} +EXPORT_SYMBOL(stpcpy); + #ifndef __HAVE_ARCH_STRCAT /** * strcat - Append one %NUL-terminated string to another diff --git a/lib/test_firmware.c b/lib/test_firmware.c index 9fee2b93a8d1..06c955057756 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -26,6 +26,8 @@ #include <linux/vmalloc.h> #include <linux/efi_embedded_fw.h> +MODULE_IMPORT_NS(TEST_FIRMWARE); + #define TEST_FIRMWARE_NAME "test-firmware.bin" #define TEST_FIRMWARE_NUM_REQS 4 #define TEST_FIRMWARE_BUF_SIZE SZ_1K @@ -489,6 +491,9 @@ out: static DEVICE_ATTR_WO(trigger_request); #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE +extern struct list_head efi_embedded_fw_list; +extern bool efi_embedded_fw_checked; + static ssize_t trigger_request_platform_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -501,6 +506,7 @@ static ssize_t trigger_request_platform_store(struct device *dev, }; struct efi_embedded_fw efi_embedded_fw; const struct firmware *firmware = NULL; + bool saved_efi_embedded_fw_checked; char *name; int rc; @@ -513,6 +519,8 @@ static ssize_t trigger_request_platform_store(struct device *dev, efi_embedded_fw.data = (void *)test_data; efi_embedded_fw.length = sizeof(test_data); list_add(&efi_embedded_fw.list, &efi_embedded_fw_list); + saved_efi_embedded_fw_checked = efi_embedded_fw_checked; + efi_embedded_fw_checked = true; pr_info("loading '%s'\n", name); rc = firmware_request_platform(&firmware, name, dev); @@ -530,6 +538,7 @@ static ssize_t trigger_request_platform_store(struct device *dev, rc = count; out: + efi_embedded_fw_checked = saved_efi_embedded_fw_checked; release_firmware(firmware); list_del(&efi_embedded_fw.list); kfree(name); diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c index c5a6fef7b45d..76c607ee6db5 100644 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c @@ -434,7 +434,7 @@ static int __init test_rhltable(unsigned int entries) } else { if (WARN(err != -ENOENT, "removed non-existent element, error %d not %d", err, -ENOENT)) - continue; + continue; } } diff --git a/lib/vsprintf.c b/lib/vsprintf.c index c155769559ab..afb9521ddf91 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1681,7 +1681,8 @@ char *uuid_string(char *buf, char *end, const u8 *addr, switch (*(++fmt)) { case 'L': - uc = true; /* fall-through */ + uc = true; + /* fall through */ case 'l': index = guid_index; break; @@ -2218,7 +2219,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, case 'S': case 's': ptr = dereference_symbol_descriptor(ptr); - /* Fallthrough */ + /* fall through */ case 'B': return symbol_string(buf, end, ptr, spec, fmt); case 'R': @@ -2467,7 +2468,7 @@ qualifier: * utility, treat it as any other invalid or * unsupported format specifier. */ - /* Fall-through */ + /* fall through */ default: WARN_ONCE(1, "Please remove unsupported %%%c in format string\n", *fmt); diff --git a/lib/xz/xz_dec_lzma2.c b/lib/xz/xz_dec_lzma2.c index 9f336bc07ed6..65a1aad8c223 100644 --- a/lib/xz/xz_dec_lzma2.c +++ b/lib/xz/xz_dec_lzma2.c @@ -1043,7 +1043,7 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, s->lzma2.sequence = SEQ_LZMA_PREPARE; - /* Fall through */ + /* fall through */ case SEQ_LZMA_PREPARE: if (s->lzma2.compressed < RC_INIT_BYTES) @@ -1055,7 +1055,7 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, s->lzma2.compressed -= RC_INIT_BYTES; s->lzma2.sequence = SEQ_LZMA_RUN; - /* Fall through */ + /* fall through */ case SEQ_LZMA_RUN: /* diff --git a/lib/xz/xz_dec_stream.c b/lib/xz/xz_dec_stream.c index bd1d182419d7..32ab2a08b7cb 100644 --- a/lib/xz/xz_dec_stream.c +++ b/lib/xz/xz_dec_stream.c @@ -583,7 +583,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) if (ret != XZ_OK) return ret; - /* Fall through */ + /* fall through */ case SEQ_BLOCK_START: /* We need one byte of input to continue. */ @@ -608,7 +608,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->temp.pos = 0; s->sequence = SEQ_BLOCK_HEADER; - /* Fall through */ + /* fall through */ case SEQ_BLOCK_HEADER: if (!fill_temp(s, b)) @@ -620,7 +620,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_BLOCK_UNCOMPRESS; - /* Fall through */ + /* fall through */ case SEQ_BLOCK_UNCOMPRESS: ret = dec_block(s, b); @@ -629,7 +629,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_BLOCK_PADDING; - /* Fall through */ + /* fall through */ case SEQ_BLOCK_PADDING: /* @@ -651,7 +651,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_BLOCK_CHECK; - /* Fall through */ + /* fall through */ case SEQ_BLOCK_CHECK: if (s->check_type == XZ_CHECK_CRC32) { @@ -675,7 +675,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_INDEX_PADDING; - /* Fall through */ + /* fall through */ case SEQ_INDEX_PADDING: while ((s->index.size + (b->in_pos - s->in_start)) @@ -699,7 +699,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_INDEX_CRC32; - /* Fall through */ + /* fall through */ case SEQ_INDEX_CRC32: ret = crc32_validate(s, b); @@ -709,7 +709,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->temp.size = STREAM_HEADER_SIZE; s->sequence = SEQ_STREAM_FOOTER; - /* Fall through */ + /* fall through */ case SEQ_STREAM_FOOTER: if (!fill_temp(s, b)) diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c index 269ee9a796c1..db6761ea4deb 100644 --- a/lib/zstd/decompress.c +++ b/lib/zstd/decompress.c @@ -442,7 +442,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx *dctx, const void *src, size_t srcSize case set_repeat: if (dctx->litEntropy == 0) return ERROR(dictionary_corrupted); - /* fall-through */ + /* fall through */ case set_compressed: if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */ @@ -2309,7 +2309,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inB switch (zds->stage) { case zdss_init: ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */ - /* fall-through */ + /* fall through */ case zdss_loadHeader: { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize); @@ -2376,7 +2376,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inB } zds->stage = zdss_read; } - /* fall through */ + /* fall through */ case zdss_read: { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx); @@ -2405,7 +2405,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inB zds->stage = zdss_load; /* pass-through */ } - /* fall through */ + /* fall through */ case zdss_load: { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx); @@ -2438,7 +2438,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inB /* pass-through */ } } - /* fall through */ + /* fall through */ case zdss_flush: { size_t const toFlushSize = zds->outEnd - zds->outStart; |