diff options
author | Nikolaus Schulz <microschulz@web.de> | 2010-04-01 02:21:10 +0900 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-04-26 07:47:45 -0700 |
commit | 898b5ece63b796443073f505a4403a35906f1b0b (patch) | |
tree | c68bfc4162c2e991707dc080252b0380d3b8c6a8 /fs/fat | |
parent | 5d085d89715692c6b4c918a42ee6638468544812 (diff) | |
download | kernel-crypto-898b5ece63b796443073f505a4403a35906f1b0b.tar.gz kernel-crypto-898b5ece63b796443073f505a4403a35906f1b0b.tar.xz kernel-crypto-898b5ece63b796443073f505a4403a35906f1b0b.zip |
fat: fix buffer overflow in vfat_create_shortname()
commit 30d1872d9eb3663b4cf7bdebcbf5cd465674cced upstream.
When using the string representation of a random counter as part of the base
name, ensure that it is no longer than 4 bytes.
Since we are repeatedly decrementing the counter in a loop until we have found a
unique base name, the counter may wrap around zero; therefore, it is not enough
to mask its higher bits before entering the loop, this must be done inside the
loop.
[hirofumi@mail.parknet.co.jp: use snprintf()]
Signed-off-by: Nikolaus Schulz <microschulz@web.de>
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/fat')
-rw-r--r-- | fs/fat/namei_vfat.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index f565f24019b..72646e2c0f4 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -309,7 +309,7 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls, { struct fat_mount_options *opts = &MSDOS_SB(dir->i_sb)->options; wchar_t *ip, *ext_start, *end, *name_start; - unsigned char base[9], ext[4], buf[8], *p; + unsigned char base[9], ext[4], buf[5], *p; unsigned char charbuf[NLS_MAX_CHARSET_SIZE]; int chl, chi; int sz = 0, extlen, baselen, i, numtail_baselen, numtail2_baselen; @@ -467,7 +467,7 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls, return 0; } - i = jiffies & 0xffff; + i = jiffies; sz = (jiffies >> 16) & 0x7; if (baselen > 2) { baselen = numtail2_baselen; @@ -476,7 +476,7 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls, name_res[baselen + 4] = '~'; name_res[baselen + 5] = '1' + sz; while (1) { - sprintf(buf, "%04X", i); + snprintf(buf, sizeof(buf), "%04X", i & 0xffff); memcpy(&name_res[baselen], buf, 4); if (vfat_find_form(dir, name_res) < 0) break; |