lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <alpine.LSU.2.00.0901172026180.14987@fbirervta.pbzchgretzou.qr>
Date:	Sat, 17 Jan 2009 20:39:17 +0100 (CET)
From:	Jan Engelhardt <jengelh@...ozas.de>
To:	linux-btrfs@...r.kernel.org
cc:	bug-glibc@....org,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: btrfs: readdir problem workaround for 32-bit off_t

Hi,



I am seeing abnormal kernel<->userland interaction for range-exceeding 
offsets during readdir.
A suggested patch for btrfs is below, but I think there could also
be involvement of (read: a bug in) Glibc.
Would the copied parties please have a look, as it may spans both glibc 
and btrfs.


Thanks,
Jan

parent 81841fa96da5597a411f5f274a664f186b2d2549 (v2.6.29-rc2-21-g81841fa)
commit fa8ea6611fedecba8e5fdf2a5dfd82affa5a982e
Author: Jan Engelhardt <jengelh@...ozas.de>
Date:   Sat Jan 17 20:26:25 2009 +0100

btrfs: readdir problem workaround for 32-bit off_t

Kernel is i586, as is the userland.

btrfs sets filp->f_pos == (2^63-1) when it has reached the
end of a directory. This is problematic.

In obtuse 32-bit mode (no _FILE_OFFSET_BITS), readdir(3) will not return 
the last entry.

However, when compiled with -D_FILE_OFFSET_BITS=64, it will return the 
last entry. But telldir() will return (uint32_t)-1, which does not quite 
match up with the 2^63-1.

	$ cat test.c
	#include <dirent.h>
	#include <stdio.h>

	int main(int argc, const char **argv)
	{
		DIR *r = opendir(argv[1]);
		struct dirent *de;

		while ((de = readdir(r)) != NULL)
			printf("%lld %s\n", (long long)telldir(r), de->d_name);
		return 0;
	}
	$ gcc test.c -o test -ggdb3
	$ ./test /tmp/z
	2 .
	2 ..
	3 a
	4 b
	5 lib

	$ gcc test.c -o test -ggdb3 -D_FILE_OFFSET_BITS=64
	$ ./test /tmp/z
	2 .
	2 ..
	3 a
	4 b
	5 lib
	4294967295 strace.log

This has deep effects and my boot hangs. (Got btrfs as the root fs.)

I have no idea who exactly of Glibc and btrfs is at fault with what,
but this change makes btrfs usable for the moment.

Signed-off-by: Jan Engelhardt <jengelh@...ozas.de>
---
 fs/btrfs/inode.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8adfe05..901be02 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3264,10 +3264,7 @@ skip:
 	}
 
 	/* Reached end of directory/root. Bump pos past the last item. */
-	if (key_type == BTRFS_DIR_INDEX_KEY)
-		filp->f_pos = INT_LIMIT(typeof(filp->f_pos));
-	else
-		filp->f_pos++;
+	filp->f_pos++;
 nopos:
 	ret = 0;
 err:
-- 
# Created with git-export-patch

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ