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: <20685.53075.403265.997210@pilspetsen.it.uu.se>
Date:	Sun, 16 Dec 2012 14:40:35 +0100
From:	Mikael Pettersson <mikpe@...uu.se>
To:	linux-ext4@...r.kernel.org
Cc:	Mikael Pettersson <mikpe@...uu.se>
Subject: [PATCH] e2fsprogs: m68k bitops fixes

This patch fixes two problems with the m68k-specific bitops
in e2fsprogs.

The first problem is that tst_bitops SEGVs:

LD_LIBRARY_PATH=../../lib DYLD_LIBRARY_PATH=../../lib ./tst_bitops
make[1]: *** [check] Segmentation fault

Post-mortem debugging shows that this occurs in the m68k-specific
ext2fs_set_bit() when called with BIG_TEST_BIT as bit number:

Core was generated by `./tst_bitops'.
Program terminated with signal 11, Segmentation fault.
#0  0x80000820 in ext2fs_set_bit (addr=0xc01ba008, nr=2147483690) at ../../lib/ext2fs/bitops.h:357
357             __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
(gdb) bt
#0  0x80000820 in ext2fs_set_bit (addr=0xc01ba008, nr=2147483690) at ../../lib/ext2fs/bitops.h:357
#1  main (argc=1, argv=0xefc31174) at tst_bitops.c:112
(gdb) up
#1  main (argc=1, argv=0xefc31174) at tst_bitops.c:112
112             ext2fs_set_bit(BIG_TEST_BIT, bigarray);

The SEGV occurs because bfset et al interpret the bit number as a
_signed_ value, so 2147483690 is actually -2147483606, causing an
access to a location about 1/4 GB before 'bigarray'.

To fix this I adjust the base address to point to the correct byte,
and limit the bit number to be within that byte, before performing
the bfset (and likewise in the clear_bit and test_bit functions).
This is similar to what the x86-specific bitops do.

With this in place the SEGV is gone and the tests pass, but there
is still some strange output from tst_bitops:

big bit number (2147483690) test: 0, expected 4
big bit number (2147483690) test: 4, expected 0
ext2fs_set_bit big_test successful

The test and expected values differ, yet the test case doesn't fail.

A second look at the m68k bitop asm() statements makes the reason clear:
there are _no_ dependencies whatsoever between the asm()s and the
memory locations being accessed (a dependency on the address isn't
enough to create a dependency on memory locations reachable from it,
and __volatile__ doesn't create memory dependencies either).  The
simplest fix is to add "memory" clobbers (the kernel's bitops also
have memory clobbers), and with those in place the tests still pass
and the debug output looks sane:

big bit number (2147483690) test: 4, expected 4
big bit number (2147483690) test: 0, expected 0
ext2fs_set_bit big_test successful

Tested on m68k-linux with e2fsprogs-1.42.6 and gcc-4.6.3.

Signed-off-by: Mikael Pettersson <mikpe@...uu.se>
---
The Linux/m68k kernel's bfset et al bitops may also be broken,
but that depends on whether they can ever be applied to large
enough bitmaps to make the bit numbers negative.  I'll raise
the issue on the linux-m68k list at vger.

 lib/ext2fs/bitops.h |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

--- e2fsprogs-1.42.6/lib/ext2fs/bitops.h.~1~	2012-09-10 04:53:00.000000000 +0200
+++ e2fsprogs-1.42.6/lib/ext2fs/bitops.h	2012-12-16 13:39:46.000000000 +0100
@@ -354,8 +354,9 @@ _INLINE_ int ext2fs_set_bit(unsigned int
 {
 	char retval;
 
+	addr = (void *) ((unsigned char *) addr + (nr >> 3));
 	__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^7), "a" (addr));
+	     : "=d" (retval) : "d" ((nr & 7) ^ 7), "a" (addr) : "memory");
 
 	return retval;
 }
@@ -364,8 +365,9 @@ _INLINE_ int ext2fs_clear_bit(unsigned i
 {
 	char retval;
 
+	addr = (void *) ((unsigned char *) addr + (nr >> 3));
 	__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^7), "a" (addr));
+	     : "=d" (retval) : "d" ((nr & 7) ^ 7), "a" (addr) : "memory");
 
 	return retval;
 }
@@ -374,8 +376,9 @@ _INLINE_ int ext2fs_test_bit(unsigned in
 {
 	char retval;
 
+	addr = (const void *) ((const unsigned char *) addr + (nr >> 3));
 	__asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^7), "a" (addr));
+	     : "=d" (retval) : "d" ((nr & 7) ^ 7), "a" (addr) : "memory");
 
 	return retval;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ