[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] x86/mm: avoid undefined behavior in IS_NIL()

Since pointer overflow is undefined behavior in C, some compilers such
as clang optimize away the check !((ptr) + 1) in the macro IS_NIL().

This patch fixes the issue by casting the pointer type to uintptr_t,
the operations of which are well-defined.

Signed-off-by: Xi Wang <xi@xxxxxxx>
Try the simplified code below.

#define IS_NIL(ptr) (!((ptr) + 1))
void bar(void);
void foo(char *p)
        if (p) {
                if (IS_NIL(p))

$ clang -S -o - t.c -O2
foo:                                    # @foo
# BB#0:                                 # %entry
        .size   foo, .Ltmp0-foo

Clearly, clang optimizes away the check.
 xen/include/asm-x86/mm.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
index fd9d654..8f0f78a 100644
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -574,7 +574,7 @@ int donate_page(
 int map_ldt_shadow_page(unsigned int);
 #define NIL(type) ((type *)NULL - 1)
-#define IS_NIL(ptr) (!((ptr) + 1))
+#define IS_NIL(ptr) (!((uintptr_t)(ptr) + sizeof(*(ptr))))
 int create_perdomain_mapping(struct domain *, unsigned long va,
                              unsigned int nr, l1_pgentry_t **,

Xen-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.