b32a09db4f
match_strcpy() is a somewhat creepy function: the caller needs to make sure that the destination buffer is big enough, and when he screws up or forgets, match_strcpy() happily overruns the buffer. There's exactly one customer: v9fs_parse_options(). I believe it currently can't overflow its buffer, but that's not exactly obvious. The source string is a substing of the mount options. The kernel silently truncates those to PAGE_SIZE bytes, including the terminating zero. See compat_sys_mount() and do_mount(). The destination buffer is obtained from __getname(), which allocates from name_cachep, which is initialized by vfs_caches_init() for size PATH_MAX. We're safe as long as PATH_MAX <= PAGE_SIZE. PATH_MAX is 4096. As far as I know, the smallest PAGE_SIZE is also 4096. Here's a patch that makes the code a bit more obviously correct. It doesn't depend on PATH_MAX <= PAGE_SIZE. Signed-off-by: Markus Armbruster <armbru@redhat.com> Cc: Latchesar Ionkov <lucho@ionkov.net> Cc: Jim Meyering <meyering@redhat.com> Cc: "Randy.Dunlap" <rdunlap@xenotime.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
34 lines
917 B
C
34 lines
917 B
C
/*
|
|
* linux/include/linux/parser.h
|
|
*
|
|
* Header for lib/parser.c
|
|
* Intended use of these functions is parsing filesystem argument lists,
|
|
* but could potentially be used anywhere else that simple option=arg
|
|
* parsing is required.
|
|
*/
|
|
|
|
|
|
/* associates an integer enumerator with a pattern string. */
|
|
struct match_token {
|
|
int token;
|
|
const char *pattern;
|
|
};
|
|
|
|
typedef struct match_token match_table_t[];
|
|
|
|
/* Maximum number of arguments that match_token will find in a pattern */
|
|
enum {MAX_OPT_ARGS = 3};
|
|
|
|
/* Describe the location within a string of a substring */
|
|
typedef struct {
|
|
char *from;
|
|
char *to;
|
|
} substring_t;
|
|
|
|
int match_token(char *, match_table_t table, substring_t args[]);
|
|
int match_int(substring_t *, int *result);
|
|
int match_octal(substring_t *, int *result);
|
|
int match_hex(substring_t *, int *result);
|
|
size_t match_strlcpy(char *, const substring_t *, size_t);
|
|
char *match_strdup(const substring_t *);
|