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 /fs/9p/v9fs.c | |
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 'fs/9p/v9fs.c')
-rw-r--r-- | fs/9p/v9fs.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 9b0f0222e8bb..e307fbd34fa0 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -125,10 +125,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) | |||
125 | v9ses->afid = option; | 125 | v9ses->afid = option; |
126 | break; | 126 | break; |
127 | case Opt_uname: | 127 | case Opt_uname: |
128 | match_strcpy(v9ses->uname, &args[0]); | 128 | match_strlcpy(v9ses->uname, &args[0], PATH_MAX); |
129 | break; | 129 | break; |
130 | case Opt_remotename: | 130 | case Opt_remotename: |
131 | match_strcpy(v9ses->aname, &args[0]); | 131 | match_strlcpy(v9ses->aname, &args[0], PATH_MAX); |
132 | break; | 132 | break; |
133 | case Opt_nodevmap: | 133 | case Opt_nodevmap: |
134 | v9ses->nodev = 1; | 134 | v9ses->nodev = 1; |