Issue 97459
Summary The linux kernel expects initializers to FULLY initialize variables". Padding, other union members
Labels new issue
Assignees
Reporter yabinc
    This is a bug first reported in https://github.com/llvm/llvm-project/issues/78034#issuecomment-2183233517.
But fork it here to be clear it's not related to c23 standard.

The problem is about using {} to initialize a static variable with union type in the linux kernel (https://github.com/torvalds/linux/blob/master/net/xfrm/xfrm_state.c#L1142):

typedef union {
	__be32		a4;
	__be32		a6[4];
	struct in6_addr	in6;
} xfrm_address_t;

struct xfrm_state* xfrm_state_find() {
  static xfrm_address_t saddr_wildcard = {};
}

Then the code uses all bytes of saddr_wildcard to generate a hash value.

But in llvm IR, saddr_wildcard only has its first field zero initialized, left bits are marked as undef.

@saddr_wildcard = internal global { i32, [12 x i8] } { i32 0, [12 x i8] undef }, align 4, !dbg !9

With some optimization flags (like -O2 with always_inline attribute), clang decides to replace the undef part of saddr_wildcard with undef or poison values (GlobalOptPass), remove instructions for using undef and poison values (InstCombinePass), and give a wrong hash result.

I also reported this problem to the linux kernel. Here is what Linus Torvalds replied in https://www.spinics.net/lists/netdev/msg1007244.html:

> In the kernel, we do expect initializers that always initialize the
whole variable fully.

> This is literally about "the linux kernel expects initializers to
FULLY initialize variables". Padding, other union members, you name
it.

> If clang doesn't do that, then clang is buggy as far as the kernel is
concerned, and no amount of standards reading is relevant.

> And in particular, no amount of "but empty initializer" is relevant.

In my understanding, the Linux kernel expects:
1) When an initailizer is used for variable, it expects all unspecified bytes (including padding) are initialized to zero.
2) It's not limited to union, but also other aggregate types: struct, array.


_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to