NTFS: Limit name length in fs/ntfs/unistr.c::ntfs_nlstoucs() to maximum
authorAnton Altaparmakov <aia21@cantab.net>
Thu, 23 Mar 2006 16:05:11 +0000 (16:05 +0000)
committerAnton Altaparmakov <aia21@cantab.net>
Thu, 23 Mar 2006 16:05:11 +0000 (16:05 +0000)
      allowed by NTFS, i.e. 255 Unicode characters, not including the
      terminating NULL (which is not stored on disk).

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
fs/ntfs/ChangeLog
fs/ntfs/unistr.c

index 13e70d4e2fdb82d6f3957454f1053aff3b1bca8c..41d0381be6eafb34d902100c6f684d924b436f2f 100644 (file)
@@ -34,6 +34,9 @@ ToDo/Notes:
        - Add support for sparse files which have a compression unit of 0.
        - Remove all the make_bad_inode() calls.  This should only be called
          from read inode and new inode code paths.
+       - Limit name length in fs/ntfs/unistr.c::ntfs_nlstoucs() to maximum
+         allowed by NTFS, i.e. 255 Unicode characters, not including the
+         terminating NULL (which is not stored on disk).
 
 2.1.26 - Minor bug fixes and updates.
 
index 0ea887fc859cc358dca5276f65ea1bcc9bb04e2f..b123c0fa6bf6a4d7b10ad1c7cda1dcd1ec0ddf9c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2005 Anton Altaparmakov
+ * Copyright (c) 2001-2006 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -19,6 +19,8 @@
  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/slab.h>
+
 #include "types.h"
 #include "debug.h"
 #include "ntfs.h"
@@ -242,7 +244,7 @@ int ntfs_file_compare_values(FILE_NAME_ATTR *file_name_attr1,
  * map dictates, into a little endian, 2-byte Unicode string.
  *
  * This function allocates the string and the caller is responsible for
- * calling kmem_cache_free(ntfs_name_cache, @outs); when finished with it.
+ * calling kmem_cache_free(ntfs_name_cache, *@outs); when finished with it.
  *
  * On success the function returns the number of Unicode characters written to
  * 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,
        wchar_t wc;
        int i, o, wc_len;
 
-       /* We don't trust outside sources. */
-       if (ins) {
+       /* We do not trust outside sources. */
+       if (likely(ins)) {
                ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS);
-               if (ucs) {
+               if (likely(ucs)) {
                        for (i = o = 0; i < ins_len; i += wc_len) {
                                wc_len = nls->char2uni(ins + i, ins_len - i,
                                                &wc);
-                               if (wc_len >= 0) {
-                                       if (wc) {
+                               if (likely(wc_len >= 0 &&
+                                               o < NTFS_MAX_NAME_LEN)) {
+                                       if (likely(wc)) {
                                                ucs[o++] = cpu_to_le16(wc);
                                                continue;
-                                       } /* else (!wc) */
+                                       } /* else if (!wc) */
                                        break;
-                               } /* else (wc_len < 0) */
-                               goto conversion_err;
+                               } /* else if (wc_len < 0 ||
+                                               o >= NTFS_MAX_NAME_LEN) */
+                               goto name_err;
                        }
                        ucs[o] = 0;
                        *outs = ucs;
                        return o;
-               } /* else (!ucs) */
-               ntfs_error(vol->sb, "Failed to allocate name from "
-                               "ntfs_name_cache!");
+               } /* else if (!ucs) */
+               ntfs_error(vol->sb, "Failed to allocate buffer for converted "
+                               "name from ntfs_name_cache.");
                return -ENOMEM;
-       } /* else (!ins) */
-       ntfs_error(NULL, "Received NULL pointer.");
+       } /* else if (!ins) */
+       ntfs_error(vol->sb, "Received NULL pointer.");
        return -EINVAL;
-conversion_err:
-       ntfs_error(vol->sb, "Name using character set %s contains characters "
-                       "that cannot be converted to Unicode.", nls->charset);
+name_err:
        kmem_cache_free(ntfs_name_cache, ucs);
-       return -EILSEQ;
+       if (wc_len < 0) {
+               ntfs_error(vol->sb, "Name using character set %s contains "
+                               "characters that cannot be converted to "
+                               "Unicode.", nls->charset);
+               i = -EILSEQ;
+       } else /* if (o >= NTFS_MAX_NAME_LEN) */ {
+               ntfs_error(vol->sb, "Name is too long (maximum length for a "
+                               "name on NTFS is %d Unicode characters.",
+                               NTFS_MAX_NAME_LEN);
+               i = -ENAMETOOLONG;
+       }
+       return i;
 }
 
 /**