]> granicus.if.org Git - zfs/commitdiff
sysmacros: Make P2ROUNDUP not trigger int overflow
authorJason Zaman <jason@perfinion.com>
Sat, 24 Oct 2015 06:01:08 +0000 (14:01 +0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 17 Nov 2015 00:10:07 +0000 (16:10 -0800)
The original P2ROUNDUP and P2ROUNDUP_TYPED macros contain -x which
triggers PaX's integer overflow detection for unsigned integers.
Replace the macros with an equivalent version that does not trigger
the overflow.

Axioms:
A. (-(x)) === (~((x) - 1)) === (~(x) + 1) under two's complement.
B. ~(x & y) === ((~(x)) | (~(y))) under De Morgan's law.
C. ~(~x) === x under the law of excluded middle.

Proof:
0. (-(-(x) & -(align))) original
1. (~(-(x) & -(align)) + 1) by A
2. (((~(-(x))) | (~(-(align)))) + 1) by B
3. (((~(~((x) - 1))) | (~(~((align) - 1)))) + 1) by A
4. (((((x) - 1)) | (((align) - 1))) + 1) by C
Q.E.D.

Signed-off-by: Jason Zaman <jason@perfinion.com>
Reviewed-by: Chris Dunlop <chris@onthe.net.au>
Reviewed-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #3949

lib/libspl/include/sys/sysmacros.h

index 698b0a7a34fedb50587ef6fd5e3431002b31925a..5d10657be582867113809b8ecf7b69e1cce726d2 100644 (file)
@@ -49,9 +49,7 @@
  */
 #define        P2ALIGN(x, align)       ((x) & -(align))
 #define        P2CROSS(x, y, align)    (((x) ^ (y)) > (align) - 1)
-#define        P2ROUNDUP(x, align)     (-(-(x) & -(align)))
-#define        P2ROUNDUP_TYPED(x, align, type) \
-                               (-(-(type)(x) & -(type)(align)))
+#define        P2ROUNDUP(x, align)     ((((x) - 1) | ((align) - 1)) + 1)
 #define        P2BOUNDARY(off, len, align) \
                                (((off) ^ ((off) + (len) - 1)) > (align) - 1)
 #define        P2PHASE(x, align)       ((x) & ((align) - 1))
@@ -79,7 +77,7 @@
 #define        P2NPHASE_TYPED(x, align, type)          \
        (-(type)(x) & ((type)(align) - 1))
 #define        P2ROUNDUP_TYPED(x, align, type)         \
-       (-(-(type)(x) & -(type)(align)))
+       ((((type)(x) - 1) | ((type)(align) - 1)) + 1)
 #define        P2END_TYPED(x, align, type)             \
        (-(~(type)(x) & -(type)(align)))
 #define        P2PHASEUP_TYPED(x, align, phase, type)  \