Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
+2.0.21:
+ These only affect 32-bit architectures:
+ - Check for, and refuse to mount too large volumes (maximum is 2TiB).
+ - Check for, and refuse to open too large files and directories
+ (maximum is 16TiB).
2.0.20:
- Support non-resident directory index bitmaps. This means we now cope
with huge directories without problems.
ToDo:
- Find and fix bugs.
- - W.r.t. s_maxbytes still need to be careful on reading/truncating as
- there are dragons lurking in the details, e.g. read_inode() currently
- does no checks for file size wrt s_maxbytes. So what happens when a
- user open()s a file with i_size > s_maxbytes? Should read_inode()
- truncate the visible i_size? Will the user just get -E2BIG (or
- whatever) on open()? Or will (s)he be able to open() but lseek() and
- read() will fail when s_maxbytes is reached? -> Investigate this.
- Enable NFS exporting of NTFS.
+2.0.21 - Check for, and refuse to work with too large files/directories/volumes.
+
+ - Limit volume size at mount time to 2TiB on architectures where
+ unsigned long is 32-bits (fs/ntfs/super.c::parse_ntfs_boot_sector()).
+ This is the most we can do without overflowing the 32-bit limit of
+ the block device size imposed on us by sb_bread() and sb_getblk()
+ for the time being.
+ - Limit file/directory size at open() time to 16TiB on architectures
+ where unsigned long is 32-bits (fs/ntfs/file.c::ntfs_file_open() and
+ fs/ntfs/dir.c::ntfs_dir_open()). This is the most we can do without
+ overflowing the page cache page index.
+
2.0.20 - Support non-resident directory index bitmaps, fix page leak in readdir.
- Move the directory index bitmap to use an attribute inode instead of
ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.20\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.21\"
ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
return err;
}
+/**
+ * ntfs_dir_open - called when an inode is about to be opened
+ * @vi: inode to be opened
+ * @filp: file structure describing the inode
+ *
+ * Limit directory size to the page cache limit on architectures where unsigned
+ * long is 32-bits. This is the most we can do for now without overflowing the
+ * page cache page index. Doing it this way means we don't run into problems
+ * because of existing too large directories. It would be better to allow the
+ * user to read the accessible part of the directory but I doubt very much
+ * anyone is going to hit this check on a 32-bit architecture, so there is no
+ * point in adding the extra complexity required to support this.
+ *
+ * On 64-bit architectures, the check is hopefully optimized away by the
+ * compiler.
+ */
+static int ntfs_dir_open(struct inode *vi, struct file *filp)
+{
+ if (sizeof(unsigned long) < 8) {
+ if (vi->i_size > MAX_LFS_FILESIZE)
+ return -EFBIG;
+ }
+ return 0;
+}
+
struct file_operations ntfs_dir_ops = {
llseek: generic_file_llseek, /* Seek inside directory. */
read: generic_read_dir, /* Return -EISDIR. */
readdir: ntfs_readdir, /* Read directory contents. */
+ open: ntfs_dir_open, /* Open directory. */
};
#include "ntfs.h"
+/**
+ * ntfs_file_open - called when an inode is about to be opened
+ * @vi: inode to be opened
+ * @filp: file structure describing the inode
+ *
+ * Limit file size to the page cache limit on architectures where unsigned long
+ * is 32-bits. This is the most we can do for now without overflowing the page
+ * cache page index. Doing it this way means we don't run into problems because
+ * of existing too large files. It would be better to allow the user to read
+ * the beginning of the file but I doubt very much anyone is going to hit this
+ * check on a 32-bit architecture, so there is no point in adding the extra
+ * complexity required to support this.
+ *
+ * On 64-bit architectures, the check is hopefully optimized away by the
+ * compiler.
+ *
+ * After the check passes, just call generic_file_open() to do its work.
+ */
+static int ntfs_file_open(struct inode *vi, struct file *filp)
+{
+ if (sizeof(unsigned long) < 8) {
+ if (vi->i_size > MAX_LFS_FILESIZE)
+ return -EFBIG;
+ }
+ return generic_file_open(vi, filp);
+}
+
struct file_operations ntfs_file_ops = {
- llseek: generic_file_llseek, /* Seek inside file. */
- read: generic_file_read, /* Read from file. */
- mmap: generic_file_mmap, /* Mmap file. */
- open: generic_file_open, /* Open file. */
+ llseek: generic_file_llseek, /* Seek inside file. */
+ read: generic_file_read, /* Read from file. */
+ mmap: generic_file_mmap, /* Mmap file. */
+ open: ntfs_file_open, /* Open file. */
};
struct inode_operations ntfs_file_inode_ops = {};
* super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.
*
* Copyright (c) 2001,2002 Anton Altaparmakov.
- * Copyright (C) 2001,2002 Richard Russon.
+ * Copyright (c) 2001,2002 Richard Russon.
*
* 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
}
/**
- * read_boot_sector - read the NTFS boot sector of a device
+ * read_ntfs_boot_sector - read the NTFS boot sector of a device
* @sb: super block of device to read the boot sector from
* @silent: if true, suppress all output
*
}
vol->nr_clusters = ll;
ntfs_debug("vol->nr_clusters = 0x%Lx", (long long)vol->nr_clusters);
+ /*
+ * On an architecture where unsigned long is 32-bits, we restrict the
+ * volume size to 2TiB (2^41). On a 64-bit architecture, the compiler
+ * will hopefully optimize the whole check away.
+ */
+ if (sizeof(unsigned long) < 8) {
+ if ((ll << vol->cluster_size_bits) >= (1ULL << 41)) {
+ ntfs_error(vol->sb, "Volume size (%LuTiB) is too large "
+ "for this architecture. Maximim "
+ "supported is 2TiB. Sorry.",
+ ll >> (40 - vol->cluster_size_bits));
+ return FALSE;
+ }
+ }
ll = sle64_to_cpu(b->mft_lcn);
if (ll >= vol->nr_clusters) {
ntfs_error(vol->sb, "MFT LCN is beyond end of volume. Weird.");