Bug 15236

Summary: [1.36] SIGILL on accessing sha256 on some CPUs
Product: Busybox Reporter: Tonis Tiigi <tonistiigi>
Component: OtherAssignee: unassigned
Status: RESOLVED FIXED    
Severity: normal CC: admwiggin+busyboxbugs, busybox-cvs, vda.linux
Priority: P5    
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Host: Target:
Build:
Attachments: patch which changes the sha extensions detection

Description Tonis Tiigi 2023-01-08 20:30:06 UTC
Since 1.36, accessing sha256sum sometimes errors "illegal instruction". v1.35 seems to work properly.

This can be demonstrated in Github Actions infra, which schedules jobs on different types of CPUs, causing them to fail when they hit the wrong one. Please see https://github.com/tonistiigi/gh-busybox-sigill-debug/actions/runs/3858482123/jobs/6577057476 for logs.

In GH infra:
Good CPUs: 8370C, E5-2673
Bad CPUs: 8171M, 8272CL


Likely regression from https://github.com/mirror/busybox/commit/6472ac942898437e040171cec991de1c0b962f72 but didn't verify.
Comment 2 Ben 2023-03-04 14:38:42 UTC
Created attachment 9521 [details]
patch which changes the sha extensions detection
Comment 3 Ben 2023-03-04 14:40:10 UTC
Intel has a documented C function (with inline assembly) to check for the SHA processor extensions:

<https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sha-extensions.html#inpage-nav-5>

... in their CheckForIntelShaExtensions function after the CPUID call, the relevant bit is:

> // IntelĀ® SHA Extensions feature bit is EBX[29]
> return ((b >> 29) & 1);


BusyBox v1.36.0 seems to perform this check differently:

shaNI = ((ebx >> 29) << 1) - 1;
if (shaNI > 0) ...


I was able to make the sha256sum function work on 8272CL by applying the attached patch.
Comment 4 Jens Maus 2023-05-09 14:22:31 UTC
In one of my projects we recently stumbled for this issue (sha256sum running in Illegal instruction) as well and this project is using buildroot/busybox with latest busybox 1.36.

See here for the related bugreport on github:

https://github.com/jens-maus/RaspberryMatic/issues/2309

Too me this ready like this might be the exact same thing and even thought only affects very rarely some users with some CPU/setup types, I do feel this might be related as well. 

Any chance to get this patch merged if it really solves this issue?
Comment 5 Denys Vlasenko 2023-05-18 22:11:22 UTC
In your patch:

-                       shaNI = ((ebx >> 29) << 1) - 1;
+                       shaNI = ((ebx >> 29) & 1);

This will set shaNI to 0 if bit is not set, instead of -1.
Which will make sha1_begin/sha256_begin check it again on every single call. CPUID insn takes something like 300 cycles.

Fixed in git.

https://git.busybox.net/busybox/commit/?id=bd76b75f72f717150b909e8c64edfda725cabe11

-			shaNI = ((ebx >> 29) << 1) - 1;
+			shaNI = ((ebx >> 28) & 2) - 1; /* bit 29 -> 1 or -1 */

Will be released in June.