aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ntfs/ChangeLog3
-rw-r--r--fs/ntfs/unistr.c51
2 files changed, 35 insertions, 19 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 13e70d4e2fdb..41d0381be6ea 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -34,6 +34,9 @@ ToDo/Notes:
34 - Add support for sparse files which have a compression unit of 0. 34 - Add support for sparse files which have a compression unit of 0.
35 - Remove all the make_bad_inode() calls. This should only be called 35 - Remove all the make_bad_inode() calls. This should only be called
36 from read inode and new inode code paths. 36 from read inode and new inode code paths.
37 - Limit name length in fs/ntfs/unistr.c::ntfs_nlstoucs() to maximum
38 allowed by NTFS, i.e. 255 Unicode characters, not including the
39 terminating NULL (which is not stored on disk).
37 40
382.1.26 - Minor bug fixes and updates. 412.1.26 - Minor bug fixes and updates.
39 42
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c
index 0ea887fc859c..b123c0fa6bf6 100644
--- a/fs/ntfs/unistr.c
+++ b/fs/ntfs/unistr.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project. 2 * unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project.
3 * 3 *
4 * Copyright (c) 2001-2005 Anton Altaparmakov 4 * Copyright (c) 2001-2006 Anton Altaparmakov
5 * 5 *
6 * This program/include file is free software; you can redistribute it and/or 6 * This program/include file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as published 7 * modify it under the terms of the GNU General Public License as published
@@ -19,6 +19,8 @@
19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/slab.h>
23
22#include "types.h" 24#include "types.h"
23#include "debug.h" 25#include "debug.h"
24#include "ntfs.h" 26#include "ntfs.h"
@@ -242,7 +244,7 @@ int ntfs_file_compare_values(FILE_NAME_ATTR *file_name_attr1,
242 * map dictates, into a little endian, 2-byte Unicode string. 244 * map dictates, into a little endian, 2-byte Unicode string.
243 * 245 *
244 * This function allocates the string and the caller is responsible for 246 * This function allocates the string and the caller is responsible for
245 * calling kmem_cache_free(ntfs_name_cache, @outs); when finished with it. 247 * calling kmem_cache_free(ntfs_name_cache, *@outs); when finished with it.
246 * 248 *
247 * On success the function returns the number of Unicode characters written to 249 * On success the function returns the number of Unicode characters written to
248 * the output string *@outs (>= 0), not counting the terminating Unicode NULL 250 * the output string *@outs (>= 0), not counting the terminating Unicode NULL
@@ -262,37 +264,48 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins,
262 wchar_t wc; 264 wchar_t wc;
263 int i, o, wc_len; 265 int i, o, wc_len;
264 266
265 /* We don't trust outside sources. */ 267 /* We do not trust outside sources. */
266 if (ins) { 268 if (likely(ins)) {
267 ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); 269 ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS);
268 if (ucs) { 270 if (likely(ucs)) {
269 for (i = o = 0; i < ins_len; i += wc_len) { 271 for (i = o = 0; i < ins_len; i += wc_len) {
270 wc_len = nls->char2uni(ins + i, ins_len - i, 272 wc_len = nls->char2uni(ins + i, ins_len - i,
271 &wc); 273 &wc);
272 if (wc_len >= 0) { 274 if (likely(wc_len >= 0 &&
273 if (wc) { 275 o < NTFS_MAX_NAME_LEN)) {
276 if (likely(wc)) {
274 ucs[o++] = cpu_to_le16(wc); 277 ucs[o++] = cpu_to_le16(wc);
275 continue; 278 continue;
276 } /* else (!wc) */ 279 } /* else if (!wc) */
277 break; 280 break;
278 } /* else (wc_len < 0) */ 281 } /* else if (wc_len < 0 ||
279 goto conversion_err; 282 o >= NTFS_MAX_NAME_LEN) */
283 goto name_err;
280 } 284 }
281 ucs[o] = 0; 285 ucs[o] = 0;
282 *outs = ucs; 286 *outs = ucs;
283 return o; 287 return o;
284 } /* else (!ucs) */ 288 } /* else if (!ucs) */
285 ntfs_error(vol->sb, "Failed to allocate name from " 289 ntfs_error(vol->sb, "Failed to allocate buffer for converted "
286 "ntfs_name_cache!"); 290 "name from ntfs_name_cache.");
287 return -ENOMEM; 291 return -ENOMEM;
288 } /* else (!ins) */ 292 } /* else if (!ins) */
289 ntfs_error(NULL, "Received NULL pointer."); 293 ntfs_error(vol->sb, "Received NULL pointer.");
290 return -EINVAL; 294 return -EINVAL;
291conversion_err: 295name_err:
292 ntfs_error(vol->sb, "Name using character set %s contains characters "
293 "that cannot be converted to Unicode.", nls->charset);
294 kmem_cache_free(ntfs_name_cache, ucs); 296 kmem_cache_free(ntfs_name_cache, ucs);
295 return -EILSEQ; 297 if (wc_len < 0) {
298 ntfs_error(vol->sb, "Name using character set %s contains "
299 "characters that cannot be converted to "
300 "Unicode.", nls->charset);
301 i = -EILSEQ;
302 } else /* if (o >= NTFS_MAX_NAME_LEN) */ {
303 ntfs_error(vol->sb, "Name is too long (maximum length for a "
304 "name on NTFS is %d Unicode characters.",
305 NTFS_MAX_NAME_LEN);
306 i = -ENAMETOOLONG;
307 }
308 return i;
296} 309}
297 310
298/** 311/**