diff options
author | Markus Armbruster <armbru@redhat.com> | 2008-02-26 10:57:11 -0500 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@opteron.9grid.us> | 2008-05-14 20:23:25 -0400 |
commit | b32a09db4fb9a87246ba4e7726a979ac4709ad97 (patch) | |
tree | b84cf43745c329ccbcbd2671da91e729db8132ca /lib | |
parent | dd286422fefdcff784e8d336deeb88ce817e14db (diff) |
add match_strlcpy() us it to make v9fs make uname and remotename parsing more robust
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>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/parser.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/lib/parser.c b/lib/parser.c index 703c8c13b346..4f0cbc03e0e8 100644 --- a/lib/parser.c +++ b/lib/parser.c | |||
@@ -182,18 +182,25 @@ int match_hex(substring_t *s, int *result) | |||
182 | } | 182 | } |
183 | 183 | ||
184 | /** | 184 | /** |
185 | * match_strcpy: - copies the characters from a substring_t to a string | 185 | * match_strlcpy: - Copy the characters from a substring_t to a sized buffer |
186 | * @to: string to copy characters to. | 186 | * @dest: where to copy to |
187 | * @s: &substring_t to copy | 187 | * @src: &substring_t to copy |
188 | * @size: size of destination buffer | ||
188 | * | 189 | * |
189 | * Description: Copies the set of characters represented by the given | 190 | * Description: Copy the characters in &substring_t @src to the |
190 | * &substring_t @s to the c-style string @to. Caller guarantees that @to is | 191 | * c-style string @dest. Copy no more than @size - 1 characters, plus |
191 | * large enough to hold the characters of @s. | 192 | * the terminating NUL. Return length of @src. |
192 | */ | 193 | */ |
193 | void match_strcpy(char *to, const substring_t *s) | 194 | size_t match_strlcpy(char *dest, const substring_t *src, size_t size) |
194 | { | 195 | { |
195 | memcpy(to, s->from, s->to - s->from); | 196 | size_t ret = src->to - src->from; |
196 | to[s->to - s->from] = '\0'; | 197 | |
198 | if (size) { | ||
199 | size_t len = ret >= size ? size - 1 : ret; | ||
200 | memcpy(dest, src->from, len); | ||
201 | dest[len] = '\0'; | ||
202 | } | ||
203 | return ret; | ||
197 | } | 204 | } |
198 | 205 | ||
199 | /** | 206 | /** |
@@ -206,9 +213,10 @@ void match_strcpy(char *to, const substring_t *s) | |||
206 | */ | 213 | */ |
207 | char *match_strdup(const substring_t *s) | 214 | char *match_strdup(const substring_t *s) |
208 | { | 215 | { |
209 | char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL); | 216 | size_t sz = s->to - s->from + 1; |
217 | char *p = kmalloc(sz, GFP_KERNEL); | ||
210 | if (p) | 218 | if (p) |
211 | match_strcpy(p, s); | 219 | match_strlcpy(p, s, sz); |
212 | return p; | 220 | return p; |
213 | } | 221 | } |
214 | 222 | ||
@@ -216,5 +224,5 @@ EXPORT_SYMBOL(match_token); | |||
216 | EXPORT_SYMBOL(match_int); | 224 | EXPORT_SYMBOL(match_int); |
217 | EXPORT_SYMBOL(match_octal); | 225 | EXPORT_SYMBOL(match_octal); |
218 | EXPORT_SYMBOL(match_hex); | 226 | EXPORT_SYMBOL(match_hex); |
219 | EXPORT_SYMBOL(match_strcpy); | 227 | EXPORT_SYMBOL(match_strlcpy); |
220 | EXPORT_SYMBOL(match_strdup); | 228 | EXPORT_SYMBOL(match_strdup); |