linux-stable/include/linux/string_helpers.h
J. Bruce Fields ea053e164c nfsd: escape high characters in binary data
I'm exposing some information about NFS clients in pseudofiles.  I
expect to eventually have simple tools to help read those pseudofiles.

But it's also helpful if the raw files are human-readable to the extent
possible.  It aids debugging and makes them usable on systems that don't
have the latest nfs-utils.

A minor challenge there is opaque client-generated protocol objects like
state owners and client identifiers.  Some clients generate those to
include handy information in plain ascii.  But they may also include
arbitrary byte sequences.

I think the simplest approach is to limit to isprint(c) && isascii(c)
and escape everything else.

That means you can just cat the file and get something that looks OK.
Also, I'm trying to keep these files legal YAML, which requires them to
UTF-8, and this is a simple way to guarantee that.

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2019-07-03 17:52:50 -04:00

82 lines
2.3 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_STRING_HELPERS_H_
#define _LINUX_STRING_HELPERS_H_
#include <linux/types.h>
struct file;
struct task_struct;
/* Descriptions of the types of units to
* print in */
enum string_size_units {
STRING_UNITS_10, /* use powers of 10^3 (standard SI) */
STRING_UNITS_2, /* use binary powers of 2^10 */
};
void string_get_size(u64 size, u64 blk_size, enum string_size_units units,
char *buf, int len);
#define UNESCAPE_SPACE 0x01
#define UNESCAPE_OCTAL 0x02
#define UNESCAPE_HEX 0x04
#define UNESCAPE_SPECIAL 0x08
#define UNESCAPE_ANY \
(UNESCAPE_SPACE | UNESCAPE_OCTAL | UNESCAPE_HEX | UNESCAPE_SPECIAL)
int string_unescape(char *src, char *dst, size_t size, unsigned int flags);
static inline int string_unescape_inplace(char *buf, unsigned int flags)
{
return string_unescape(buf, buf, 0, flags);
}
static inline int string_unescape_any(char *src, char *dst, size_t size)
{
return string_unescape(src, dst, size, UNESCAPE_ANY);
}
static inline int string_unescape_any_inplace(char *buf)
{
return string_unescape_any(buf, buf, 0);
}
#define ESCAPE_SPACE 0x01
#define ESCAPE_SPECIAL 0x02
#define ESCAPE_NULL 0x04
#define ESCAPE_OCTAL 0x08
#define ESCAPE_ANY \
(ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_SPECIAL | ESCAPE_NULL)
#define ESCAPE_NP 0x10
#define ESCAPE_ANY_NP (ESCAPE_ANY | ESCAPE_NP)
#define ESCAPE_HEX 0x20
int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
unsigned int flags, const char *only);
int string_escape_mem_ascii(const char *src, size_t isz, char *dst,
size_t osz);
static inline int string_escape_mem_any_np(const char *src, size_t isz,
char *dst, size_t osz, const char *only)
{
return string_escape_mem(src, isz, dst, osz, ESCAPE_ANY_NP, only);
}
static inline int string_escape_str(const char *src, char *dst, size_t sz,
unsigned int flags, const char *only)
{
return string_escape_mem(src, strlen(src), dst, sz, flags, only);
}
static inline int string_escape_str_any_np(const char *src, char *dst,
size_t sz, const char *only)
{
return string_escape_str(src, dst, sz, ESCAPE_ANY_NP, only);
}
char *kstrdup_quotable(const char *src, gfp_t gfp);
char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp);
char *kstrdup_quotable_file(struct file *file, gfp_t gfp);
#endif