diff options
| author | Ingo Molnar <mingo@kernel.org> | 2016-06-08 09:26:46 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2016-06-08 09:26:46 +0200 | 
| commit | 616d1c1b98ac79f30216a57a170dd7cea19b3df3 (patch) | |
| tree | 6f244c2e5a7160190e73bc82b4cd7fa7bb22ee31 /lib/string_helpers.c | |
| parent | a4f144ebbdf6f7807c477bce8e136047ed27321f (diff) | |
| parent | c8ae067f2635be0f8c7e5db1bb74b757d623e05b (diff) | |
Merge branch 'linus' into perf/core, to refresh the branch
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib/string_helpers.c')
| -rw-r--r-- | lib/string_helpers.c | 92 | 
1 files changed, 92 insertions, 0 deletions
diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 5c88204b6f1f..ecaac2c0526f 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -10,6 +10,10 @@  #include <linux/export.h>  #include <linux/ctype.h>  #include <linux/errno.h> +#include <linux/fs.h> +#include <linux/limits.h> +#include <linux/mm.h> +#include <linux/slab.h>  #include <linux/string.h>  #include <linux/string_helpers.h> @@ -534,3 +538,91 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,  	return p - dst;  }  EXPORT_SYMBOL(string_escape_mem); + +/* + * Return an allocated string that has been escaped of special characters + * and double quotes, making it safe to log in quotes. + */ +char *kstrdup_quotable(const char *src, gfp_t gfp) +{ +	size_t slen, dlen; +	char *dst; +	const int flags = ESCAPE_HEX; +	const char esc[] = "\f\n\r\t\v\a\e\\\""; + +	if (!src) +		return NULL; +	slen = strlen(src); + +	dlen = string_escape_mem(src, slen, NULL, 0, flags, esc); +	dst = kmalloc(dlen + 1, gfp); +	if (!dst) +		return NULL; + +	WARN_ON(string_escape_mem(src, slen, dst, dlen, flags, esc) != dlen); +	dst[dlen] = '\0'; + +	return dst; +} +EXPORT_SYMBOL_GPL(kstrdup_quotable); + +/* + * Returns allocated NULL-terminated string containing process + * command line, with inter-argument NULLs replaced with spaces, + * and other special characters escaped. + */ +char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp) +{ +	char *buffer, *quoted; +	int i, res; + +	buffer = kmalloc(PAGE_SIZE, GFP_TEMPORARY); +	if (!buffer) +		return NULL; + +	res = get_cmdline(task, buffer, PAGE_SIZE - 1); +	buffer[res] = '\0'; + +	/* Collapse trailing NULLs, leave res pointing to last non-NULL. */ +	while (--res >= 0 && buffer[res] == '\0') +		; + +	/* Replace inter-argument NULLs. */ +	for (i = 0; i <= res; i++) +		if (buffer[i] == '\0') +			buffer[i] = ' '; + +	/* Make sure result is printable. */ +	quoted = kstrdup_quotable(buffer, gfp); +	kfree(buffer); +	return quoted; +} +EXPORT_SYMBOL_GPL(kstrdup_quotable_cmdline); + +/* + * Returns allocated NULL-terminated string containing pathname, + * with special characters escaped, able to be safely logged. If + * there is an error, the leading character will be "<". + */ +char *kstrdup_quotable_file(struct file *file, gfp_t gfp) +{ +	char *temp, *pathname; + +	if (!file) +		return kstrdup("<unknown>", gfp); + +	/* We add 11 spaces for ' (deleted)' to be appended */ +	temp = kmalloc(PATH_MAX + 11, GFP_TEMPORARY); +	if (!temp) +		return kstrdup("<no_memory>", gfp); + +	pathname = file_path(file, temp, PATH_MAX + 11); +	if (IS_ERR(pathname)) +		pathname = kstrdup("<too_long>", gfp); +	else +		pathname = kstrdup_quotable(pathname, gfp); + +	kfree(temp); +	return pathname; +} +EXPORT_SYMBOL_GPL(kstrdup_quotable_file);  | 
