-
Notifications
You must be signed in to change notification settings - Fork 15
Description
The kernel test robot reported an objtool
warning with this configuration, which it pointed the finger at commit ab4e4380d4e1 ("Bluetooth: Add vhci devcoredump support") a while ago. Depending on the clang version, you will see one of two warnings:
drivers/bluetooth/hci_vhci.o: warning: objtool: .text: unexpected end of section
drivers/bluetooth/hci_vhci.o: warning: objtool: vhci_coredump_hdr() falls through to next function __cfi_vhci_open_timeout()
The body of vhci_coredump_hdr()
:
static void vhci_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb)
{
char buf[80];
snprintf(buf, sizeof(buf), "Controller Name: vhci_ctrl\n");
skb_put_data(skb, buf, strlen(buf));
snprintf(buf, sizeof(buf), "Firmware Version: vhci_fw\n");
skb_put_data(skb, buf, strlen(buf));
snprintf(buf, sizeof(buf), "Driver: vhci_drv\n");
skb_put_data(skb, buf, strlen(buf));
snprintf(buf, sizeof(buf), "Vendor: vhci\n");
skb_put_data(skb, buf, strlen(buf));
}
I bisected the original introduction of this warning to llvm/llvm-project@1f88d80, which looks like a reasonable commit to blame.
My cvise
attempt ended up not producing much, it was long and had overtly undefined behavior.
The diff of the IR from the parent of the problematic change shows that it completely eliminates the body of vhci_coredump_hdr()
, transforming it simply into unreachable
.
@@ -1103,107 +1096,8 @@ entry:
; Function Attrs: noredzone nounwind null_pointer_is_valid ssp
define internal void @vhci_coredump_hdr(ptr nocapture readnone %hdev, ptr noundef %skb) #2 align 16 {
-if.end15.i.i:
- %buf = alloca [80 x i8], align 16
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %buf) #15
- call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(28) %buf, ptr noundef nonnull align 1 dereferenceable(28) @.str.11, i64 28, i1 false)
- %call18.i.i = call i64 @strnlen(ptr noundef nonnull %buf, i64 noundef 80) #14
- %.not.i = icmp ugt i64 %call18.i.i, 80
- br i1 %.not.i, label %do.end36.i.i, label %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i
-
-do.end36.i.i: ; preds = %if.end15.i.i
- %add.i.i = add i64 %call18.i.i, 1
- tail call void @__fortify_panic(i8 noundef zeroext 2, i64 noundef 80, i64 noundef %add.i.i) #18
- unreachable
-
-_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i: ; preds = %if.end15.i.i
- %cmp2.not.i.not = icmp eq i64 %call18.i.i, 80
- br i1 %cmp2.not.i.not, label %do.end15.i, label %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit
-
-do.end15.i: ; preds = %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i
- %add.i = add nuw nsw i64 %call18.i.i, 1
- tail call void @__fortify_panic(i8 noundef zeroext 4, i64 noundef 80, i64 noundef %add.i) #18
- unreachable
-
-_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit: ; preds = %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i
- %conv = trunc i64 %call18.i.i to i32
- %call.i = tail call ptr @skb_put(ptr noundef %skb, i32 noundef %conv) #14
- %0 = tail call i64 asm "", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %call18.i.i) #17, !srcloc !17
- call void @llvm.memcpy.p0.p0.i64(ptr align 1 %call.i, ptr nonnull align 16 %buf, i64 %0, i1 false) #15
- call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(27) %buf, ptr noundef nonnull align 1 dereferenceable(27) @.str.12, i64 27, i1 false)
- %call18.i.i38 = call i64 @strnlen(ptr noundef nonnull %buf, i64 noundef 80) #14
- %.not.i39 = icmp ugt i64 %call18.i.i38, 80
- br i1 %.not.i39, label %do.end36.i.i42, label %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i45
-
-do.end36.i.i42: ; preds = %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit
- %add.i.i41 = add i64 %call18.i.i38, 1
- tail call void @__fortify_panic(i8 noundef zeroext 2, i64 noundef 80, i64 noundef %add.i.i41) #18
- unreachable
-
-_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i45: ; preds = %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit
- %cmp2.not.i44.not = icmp eq i64 %call18.i.i38, 80
- br i1 %cmp2.not.i44.not, label %do.end15.i47, label %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit48
-
-do.end15.i47: ; preds = %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i45
- %add.i46 = add nuw nsw i64 %call18.i.i38, 1
- tail call void @__fortify_panic(i8 noundef zeroext 4, i64 noundef 80, i64 noundef %add.i46) #18
- unreachable
-
-_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit48: ; preds = %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i45
- %conv10 = trunc i64 %call18.i.i38 to i32
- %call.i90 = tail call ptr @skb_put(ptr noundef %skb, i32 noundef %conv10) #14
- %1 = tail call i64 asm "", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %call18.i.i38) #17, !srcloc !17
- call void @llvm.memcpy.p0.p0.i64(ptr align 1 %call.i90, ptr nonnull align 16 %buf, i64 %1, i1 false) #15
- call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(18) %buf, ptr noundef nonnull align 1 dereferenceable(18) @.str.13, i64 18, i1 false)
- %call18.i.i58 = call i64 @strnlen(ptr noundef nonnull %buf, i64 noundef 80) #14
- %.not.i59 = icmp ugt i64 %call18.i.i58, 80
- br i1 %.not.i59, label %do.end36.i.i62, label %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i65
-
-do.end36.i.i62: ; preds = %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit48
- %add.i.i61 = add i64 %call18.i.i58, 1
- tail call void @__fortify_panic(i8 noundef zeroext 2, i64 noundef 80, i64 noundef %add.i.i61) #18
+do.end36.i.i:
unreachable
-
-_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i65: ; preds = %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit48
- %cmp2.not.i64.not = icmp eq i64 %call18.i.i58, 80
- br i1 %cmp2.not.i64.not, label %do.end15.i67, label %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit68
-
-do.end15.i67: ; preds = %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i65
- %add.i66 = add nuw nsw i64 %call18.i.i58, 1
- tail call void @__fortify_panic(i8 noundef zeroext 4, i64 noundef 80, i64 noundef %add.i66) #18
- unreachable
-
-_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit68: ; preds = %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i65
- %conv17 = trunc i64 %call18.i.i58 to i32
- %call.i111 = tail call ptr @skb_put(ptr noundef %skb, i32 noundef %conv17) #14
- %2 = tail call i64 asm "", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %call18.i.i58) #17, !srcloc !17
- call void @llvm.memcpy.p0.p0.i64(ptr align 1 %call.i111, ptr nonnull align 16 %buf, i64 %2, i1 false) #15
- call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(14) %buf, ptr noundef nonnull align 1 dereferenceable(14) @.str.14, i64 14, i1 false)
- %call18.i.i78 = call i64 @strnlen(ptr noundef nonnull %buf, i64 noundef 80) #14
- %.not.i79 = icmp ugt i64 %call18.i.i78, 80
- br i1 %.not.i79, label %do.end36.i.i82, label %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i85
-
-do.end36.i.i82: ; preds = %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit68
- %add.i.i81 = add i64 %call18.i.i78, 1
- tail call void @__fortify_panic(i8 noundef zeroext 2, i64 noundef 80, i64 noundef %add.i.i81) #18
- unreachable
-
-_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i85: ; preds = %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit68
- %cmp2.not.i84.not = icmp eq i64 %call18.i.i78, 80
- br i1 %cmp2.not.i84.not, label %do.end15.i87, label %_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit88
-
-do.end15.i87: ; preds = %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i85
- %add.i86 = add nuw nsw i64 %call18.i.i78, 1
- tail call void @__fortify_panic(i8 noundef zeroext 4, i64 noundef 80, i64 noundef %add.i86) #18
- unreachable
-
-_Z16__fortify_strlenPKcU25pass_dynamic_object_size1.exit88: ; preds = %_Z7strnlenPKcU25pass_dynamic_object_size1m.exit.i85
- %conv24 = trunc i64 %call18.i.i78 to i32
- %call.i132 = tail call ptr @skb_put(ptr noundef %skb, i32 noundef %conv24) #14
- %3 = tail call i64 asm "", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %call18.i.i78) #17, !srcloc !17
- call void @llvm.memcpy.p0.p0.i64(ptr align 1 %call.i132, ptr nonnull align 16 %buf, i64 %3, i1 false) #15
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %buf) #15
- ret void
}
; Function Attrs: noredzone null_pointer_is_valid
@@ -1221,9 +1115,6 @@ declare dso_local i32 @hci_devcd_abort(ptr noundef) local_unnamed_addr #1
; Function Attrs: noredzone null_pointer_is_valid
declare dso_local i64 @_copy_from_user(ptr noundef, ptr noundef, i64 noundef) local_unnamed_addr #1
-; Function Attrs: argmemonly mustprogress nofree noredzone nounwind null_pointer_is_valid readonly willreturn
-declare dso_local i64 @strnlen(ptr nocapture noundef, i64 noundef) local_unnamed_addr #11
-
; Function Attrs: noredzone null_pointer_is_valid
declare dso_local i64 @__msecs_to_jiffies(i32 noundef) local_unnamed_addr #1
This appears related to the fact that __fortify_panic()
is __noreturn
(which introduces the unreachable
instruction implicitly), as I can kill this warning by replacing strlen()
with __builtin_strlen()
in vhci_coredump_hdr()
and it remains present by explicitly calling __fortify_panic()
. It also appears related to this configuration having CONFIG_INIT_STACK_NONE
, as the warning is not present with CONFIG_INIT_STACK_ALL_ZERO
(the default); char buf[80]
is technically uninitialized but there are other functions in drivers/bluetooth
that have the exact same form but no issues. I will see if I can tease out a reproducer on top of defconfig
to see if there are any other obvious factors here.