All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] e2fsprogs: Fix the overflow in e4defrag with 2GB over file
@ 2010-03-30  6:35 Akira Fujita
  2010-03-30 16:14 ` Greg Freemyer
  2010-12-17  4:13 ` Ted Ts'o
  0 siblings, 2 replies; 5+ messages in thread
From: Akira Fujita @ 2010-03-30  6:35 UTC (permalink / raw)
  To: Theodore Tso; +Cc: ext4 development

e2fsprogs: Fix the overflow in e4defrag with 2GB over file

From: Akira Fujita <a-fujita@rs.jp.nec.com>

In e4defrag, we use locally defined posix_fallocate interface.
And its "offset" and "len" are defined as off_t (long) type,
their upper limit is 2GB -1 byte.
Thus if we run e4defrag to the file whose size is 2GB over,
the overflow occurs at calling fallocate syscall.

To fix this issue, I add new define _FILE_OFFSET_BITS 64 to use
64bit offset for filesystem related syscalls in e4defrag.c.
(Also this patch includes open mode fix which has been
released but not been merged e2fsprogs git tree yet.
http://lists.openwall.net/linux-ext4/2010/01/19/3)

Reported-by: David Calinski <david@fullrecall.com>
Signed-off-by: Akira Fujita <a-fujita@rs.jp.nec.com>
---
  e4defrag.c |   60 +++++++++++++++++++++++++++---------------------------------
  1 file changed, 27 insertions(+), 33 deletions(-)
diff --git a/misc/e4defrag.c b/misc/e4defrag.c
index 82e3868..243949b 100644
--- a/misc/e4defrag.c
+++ b/misc/e4defrag.c
@@ -7,13 +7,7 @@
   *         Takashi Sato	<t-sato@yk.jp.nec.com>
   */

-#ifndef _LARGEFILE_SOURCE
-#define _LARGEFILE_SOURCE
-#endif
-
-#ifndef _LARGEFILE64_SOURCE
-#define _LARGEFILE64_SOURCE
-#endif
+#define _FILE_OFFSET_BITS 64

  #ifndef _GNU_SOURCE
  #define _GNU_SOURCE
@@ -403,7 +397,7 @@ static int is_ext4(const char *file)
  	const char	*mtab = MOUNTED;
  	char	file_path[PATH_MAX + 1];
  	struct mntent	*mnt = NULL;
-	struct statfs64	fsbuf;
+	struct statfs	fsbuf;

  	/* Get full path */
  	if (realpath(file, file_path) == NULL) {
@@ -412,7 +406,7 @@ static int is_ext4(const char *file)
  		return -1;
  	}

-	if (statfs64(file_path, &fsbuf) < 0) {
+	if (statfs(file_path, &fsbuf) < 0) {
  		perror("Failed to get filesystem information");
  		PRINT_FILE_NAME(file);
  		return -1;
@@ -470,7 +464,7 @@ static int is_ext4(const char *file)
   * @ftwbuf:		the pointer of a struct FTW.
   */
  static int calc_entry_counts(const char *file EXT2FS_ATTR((unused)),
-		const struct stat64 *buf, int flag EXT2FS_ATTR((unused)),
+		const struct stat *buf, int flag EXT2FS_ATTR((unused)),
  		struct FTW *ftwbuf EXT2FS_ATTR((unused)))
  {
  	if (S_ISREG(buf->st_mode))
@@ -580,15 +574,15 @@ static int defrag_fadvise(int fd, struct move_extent defrag_data,
   *
   * @fd:			defrag target file's descriptor.
   * @file:		file name.
- * @buf:		the pointer of the struct stat64.
+ * @buf:		the pointer of the struct stat.
   */
-static int check_free_size(int fd, const char *file, const struct stat64 *buf)
+static int check_free_size(int fd, const char *file, const struct stat *buf)
  {
  	ext4_fsblk_t	blk_count;
  	ext4_fsblk_t	free_blk_count;
-	struct statfs64	fsbuf;
+	struct statfs	fsbuf;

-	if (fstatfs64(fd, &fsbuf) < 0) {
+	if (fstatfs(fd, &fsbuf) < 0) {
  		if (mode_flag & DETAIL) {
  			PRINT_FILE_NAME(file);
  			PRINT_ERR_MSG_WITH_ERRNO(
@@ -641,11 +635,11 @@ static int file_frag_count(int fd)
   * file_check() -	Check file's attributes.
   *
   * @fd:			defrag target file's descriptor.
- * @buf:		a pointer of the struct stat64.
+ * @buf:		a pointer of the struct stat.
   * @file:		the file's name.
   * @extents:		the file's extents.
   */
-static int file_check(int fd, const struct stat64 *buf, const char *file,
+static int file_check(int fd, const struct stat *buf, const char *file,
  		int extents)
  {
  	int	ret;
@@ -1151,14 +1145,14 @@ static int get_superblock_info(const char *file, struct ext4_super_block *sb)
  				strnlen(mnt->mnt_fsname, PATH_MAX));
  	}

-	fd = open64(dev_name, O_RDONLY);
+	fd = open(dev_name, O_RDONLY);
  	if (fd < 0) {
  		ret = -1;
  		goto out;
  	}

  	/* Set offset to read superblock */
-	ret = lseek64(fd, SUPERBLOCK_OFFSET, SEEK_SET);
+	ret = lseek(fd, SUPERBLOCK_OFFSET, SEEK_SET);
  	if (ret < 0)
  		goto out;

@@ -1200,11 +1194,11 @@ static int get_best_count(ext4_fsblk_t block_count)
   * file_statistic() -	Get statistic info of the file's fragments.
   *
   * @file:		the file's name.
- * @buf:		the pointer of the struct stat64.
+ * @buf:		the pointer of the struct stat.
   * @flag:		file type.
   * @ftwbuf:		the pointer of a struct FTW.
   */
-static int file_statistic(const char *file, const struct stat64 *buf,
+static int file_statistic(const char *file, const struct stat *buf,
  			int flag EXT2FS_ATTR((unused)),
  			struct FTW *ftwbuf EXT2FS_ATTR((unused)))
  {
@@ -1275,7 +1269,7 @@ static int file_statistic(const char *file, const struct stat64 *buf,
  		return 0;
  	}

-	fd = open64(file, O_RDONLY);
+	fd = open(file, O_RDONLY);
  	if (fd < 0) {
  		if (mode_flag & DETAIL) {
  			PRINT_FILE_NAME(file);
@@ -1447,11 +1441,11 @@ static void print_progress(const char *file, loff_t start, loff_t file_size)
   * @fd:			target file descriptor.
   * @donor_fd:		donor file descriptor.
   * @file:			target file name.
- * @buf:			pointer of the struct stat64.
+ * @buf:			pointer of the struct stat.
   * @ext_list_head:	head of the extent list.
   */
  static int call_defrag(int fd, int donor_fd, const char *file,
-	const struct stat64 *buf, struct fiemap_extent_list *ext_list_head)
+	const struct stat *buf, struct fiemap_extent_list *ext_list_head)
  {
  	loff_t	start = 0;
  	unsigned int	page_num;
@@ -1541,11 +1535,11 @@ static int call_defrag(int fd, int donor_fd, const char *file,
   * file_defrag() -		Check file attributes and call ioctl to defrag.
   *
   * @file:		the file's name.
- * @buf:		the pointer of the struct stat64.
+ * @buf:		the pointer of the struct stat.
   * @flag:		file type.
   * @ftwbuf:		the pointer of a struct FTW.
   */
-static int file_defrag(const char *file, const struct stat64 *buf,
+static int file_defrag(const char *file, const struct stat *buf,
  			int flag EXT2FS_ATTR((unused)),
  			struct FTW *ftwbuf EXT2FS_ATTR((unused)))
  {
@@ -1605,7 +1599,7 @@ static int file_defrag(const char *file, const struct stat64 *buf,
  		return 0;
  	}

-	fd = open64(file, O_RDONLY);
+	fd = open(file, O_RDWR);
  	if (fd < 0) {
  		if (mode_flag & DETAIL) {
  			PRINT_FILE_NAME(file);
@@ -1675,7 +1669,7 @@ static int file_defrag(const char *file, const struct stat64 *buf,
  	memset(tmp_inode_name, 0, PATH_MAX + 8);
  	sprintf(tmp_inode_name, "%.*s.defrag",
  				(int)strnlen(file, PATH_MAX), file);
-	donor_fd = open64(tmp_inode_name, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR);
+	donor_fd = open(tmp_inode_name, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR);
  	if (donor_fd < 0) {
  		if (mode_flag & DETAIL) {
  			PRINT_FILE_NAME(file);
@@ -1822,7 +1816,7 @@ int main(int argc, char *argv[])
  	int	arg_type = -1;
  	int	success_flag = 0;
  	char	dir_name[PATH_MAX + 1];
-	struct stat64	buf;
+	struct stat	buf;
  	struct ext4_super_block sb;

  	/* Parse arguments */
@@ -1876,7 +1870,7 @@ int main(int argc, char *argv[])
  		continue;
  #endif

-		if (lstat64(argv[i], &buf) < 0) {
+		if (lstat(argv[i], &buf) < 0) {
  			perror(NGMSG_FILE_INFO);
  			PRINT_FILE_NAME(argv[i]);
  			continue;
@@ -1886,7 +1880,7 @@ int main(int argc, char *argv[])
  			/* Block device */
  			if (get_mount_point(argv[i], dir_name, PATH_MAX) < 0)
  				continue;
-			if (lstat64(dir_name, &buf) < 0) {
+			if (lstat(dir_name, &buf) < 0) {
  				perror(NGMSG_FILE_INFO);
  				PRINT_FILE_NAME(argv[i]);
  				continue;
@@ -1987,7 +1981,7 @@ int main(int argc, char *argv[])
  							   PATH_MAX));
  			}

-			nftw64(dir_name, calc_entry_counts, FTW_OPEN_FD, flags);
+			nftw(dir_name, calc_entry_counts, FTW_OPEN_FD, flags);

  			if (mode_flag & STATISTIC) {
  				if (mode_flag & DETAIL)
@@ -2000,7 +1994,7 @@ int main(int argc, char *argv[])
  					continue;
  				}

-				nftw64(dir_name, file_statistic,
+				nftw(dir_name, file_statistic,
  							FTW_OPEN_FD, flags);

  				if (succeed_cnt != 0 &&
@@ -2034,7 +2028,7 @@ int main(int argc, char *argv[])
  				break;
  			}
  			/* File tree walk */
-			nftw64(dir_name, file_defrag, FTW_OPEN_FD, flags);
+			nftw(dir_name, file_defrag, FTW_OPEN_FD, flags);
  			printf("\n\tSuccess:\t\t\t[ %u/%u ]\n", succeed_cnt,
  				total_count);
  			printf("\tFailure:\t\t\t[ %u/%u ]\n",

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-12-17  8:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-30  6:35 [PATCH] e2fsprogs: Fix the overflow in e4defrag with 2GB over file Akira Fujita
2010-03-30 16:14 ` Greg Freemyer
2010-04-01  8:27   ` Akira Fujita
2010-12-17  4:13 ` Ted Ts'o
2010-12-17  8:35   ` Akira Fujita

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.