Bug 26690

Summary: Aliasing violation in __vfscanf_internal
Product: glibc Reporter: Andreas Schwab <schwab>
Component: stdioAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: nsz, slyich, tuliom
Priority: P2    
Version: 2.25   
Target Milestone: 2.33   
Host: Target:
Build: Last reconfirmed:
Attachments: glibc-9999-alias.patch

Description Andreas Schwab 2020-10-01 11:53:45 UTC
As noted in <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97264>, the cast
in the call to the read_int function in __vfscanf_internal is an aliasing violation.
Comment 1 Andreas Schwab 2020-10-01 11:55:52 UTC
Introduced in commit 726d48ec96.
Comment 2 Sergei Trofimovich 2020-10-01 21:41:34 UTC
Created attachment 12883 [details]
glibc-9999-alias.patch

To add more color on the breakage: gcc-11 added new -fipa-modref optimization (enabled by default on -O and above) which is able to eliminate "dead" stores on pointers of incompatible types.

Attaching glibc-9999-alias.patch as a proof of concept fix that happens to unbreak glibc on gcc-11 for me.
Comment 3 Szabolcs Nagy 2020-10-06 09:56:07 UTC
i'm seeing this on aarch64 too: crypt/cert test case
does not finish reading the input and fills up the disk:

$ ./testrun.sh crypt/cert < $glibcsrc/crypt/cert.input
 K: 0000000000000000 P: 0000000000000000 C: 0000000000000000 Encrypt FAIL
 K: 0000000000000000 P: 0000000000000000 C: 0000000000000000 Encrypt FAIL
 K: 0000000000000000 P: 0000000000000000 C: 0000000000000000 Encrypt FAIL
 K: 0000000000000000 P: 0000000000000000 C: 0000000000000000 Encrypt FAIL
 K: 0000000000000000 P: 0000000000000000 C: 0000000000000000 Encrypt FAIL
...

a cut down test case:

#include <stdio.h>
int main()
{
        int r,t;
        r = sscanf("01", "%2x", &t);
        printf("scanf: %d  %02x\n", r, t);
        return 0;
}

with new gcc it prints

scanf: 0  00

with the patch from #c2 i get the expected

scanf: 1  01
Comment 4 Andreas Schwab 2020-10-08 08:16:33 UTC
Fixed in 2.33.
Comment 5 Sergei Trofimovich 2020-10-08 17:36:42 UTC
Thank you!

Linking fix here for posterity: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=c0e9ddf59e73e21afe15fca4e94cf7b4b7359bf2