Bug 26690 - Aliasing violation in __vfscanf_internal
Summary: Aliasing violation in __vfscanf_internal
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: stdio (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: 2.33
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-10-01 11:53 UTC by Andreas Schwab
Modified: 2020-10-08 17:36 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
glibc-9999-alias.patch (443 bytes, patch)
2020-10-01 21:41 UTC, Sergei Trofimovich
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
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