<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/106593>106593</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang] KCFI hash mismatches with anonymous structs and qualified typedefs
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
cme
</td>
</tr>
</table>
<pre>
Compiling the following files with `-fsanitize=kcfi` enabled incorrectly causes a KCFI violation, on current `main` as well as llvm16:
`kcfi_anon_struct.h`:
```c
typedef volatile struct { int a; int b; } A;
```
`kcfi_anon_struct_a.c`:
```c
typedef volatile struct { int a; int b; } B;
#include "kcfi_anon_struct.h"
B getB() { B v = { 0, 0 }; return v; }
extern void (*callee)(A *a);
int main(int argc, char *argv[]) {
A a;
callee(&a);
B b = getB();
b.a = a.a;
return 0;
}
```
`kcfi_anon_struct_b.c`:
```c
#include "kcfi_anon_struct.h"
void f(A *a) {
a->b = a->a + 8;
}
void (*callee)(A *a) = f;
```
Compiling with
```sh
clang -fsanitize=kcfi kcfi_anon_struct_a.c kcfi_anon_struct_b.c
```
will produce an executable that fails with a KCFI hash mismatch.
This happens because the name mangling used to create the KCFI typeid hash uses '$_*id*' with a compilation-unique integer identifier in place of the anonymous struct. In compiling `kcfi_anon_struct_a.c`, `B` gets the identified `$_0` and `A` gets the identifier `$_1` so mangling the type for `callee` gets the string `_ZTSFvPV3$_1E`. In compiling `kcfi_anon_struct_b.c` there's no definition of `B` so `A` gets theidentified `$_0` and so the mangled type for `callee` is `_ZTSFvPV3$_0E`, the typeid hashes differ between `main()` and `f()` and a trap is hit when it's executed.
When there's an *unqualified* typedef of an anonymous struct, say
```c
typedef struct { int a; int b; } A;
```
the type name is used in the mangled name, retrieved by `TagDecl::getTypedefNameForAnonDecl()`. Qualified types fail the hasExtInfo() check here and so return `nullptr`.
Presumably the same issue exists if anonymous structs are used without any typedef.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVt1u4zYTfRr6ZhCDofynC1_IcQwsPuDDFg1aoDcBRY0kdinSS1JO3KcvhpJiZ5Nmg6KAIVPiaOacMz-UDEE3FnHLlju23M9kH1vnt6rDWemq8_bOdUdttG0gtgi1M8Y90V2tDQZ40rEFtuI3dZBWR_0Xsmz_TdWarTiglaXBCrRVzntU0ZxByT5gAAn_uzt8gZN2RkbtLBN34Cyo3nu0kTx2UltyIgM8oTH0b8ypu12xrGB8z_h0XXGK9yits48h-l7FectW_GK24sNPDffxfMQKazil0AZheAnYegfaRpAsGxYlLdh6DwXLdj_4-gmCRzlX_y2G3QWDyLRVpq8QmBDvcBfiGt0OGow7JjZM5Mn_Dk7Asn1ac9KdUwCK4zH23sJpjHntBZ8j0pbTFSRfhZLGIDKRM7EpgIlC0voFZLoSg5RHsUmsfKMooGqlT2_45jRU3YhteAugSAJMd1OkDROrV0EAdlAmLheKV5vlXKZNOb_2NpLkF6gvTD-b3PLj5H46QUnN-lq_iwiM5_KGZfcDv7SUwMQONm-B_ywryUX9cRFf2pxa-gfDMD5QRtoG3vQ6vFf-bx-SbP8M4EkbA0fvql4hSAv4jKqPNEAgtjJCLbUZ5804PFoZWuh06GRU7fxV0tL1odUBWnk8og1QYpo8aYhZ2SF00jaJbx-wguhAeZRxMEjuqUd1NURJM4uJNROLRyYKXTFRMLGe4KgkXhpkN73V33uk5sUGPegKbdS1pqWFo5EKwdUpCmlz7lwfxu6fwxc7uiJcH4wVcUe7OxqPDcaQvL0EqiCZLB55Gp823Rfv2_rJ9pb2g7uoQmakANQuGY2Fde0lRD_ifPzj4dfD6etvWXJ1z1b8E1yGLiJPHplYB7AOKqw1lZazJNLEMbg3FD5gG1xCl5hQZt8locMb3Px-lHaiPiYfA1S6rtFDifEJ0b6cTsPAuYhcv34iIXp5pFCtjvDUogUdE9OhtrF6VbS_k8FFDWmpfXv7vZcmEWWigOnccDXt_1hABD7I88dHzr8_7V5KIvWPDkPnaPtKbtojHB6j13jCCsozafMgmz0qQ0MzKxqMDwOc_8sOD84X1tm0PQk4h18m3ilmSP2fIrUy3D_HL7Z246GmWlTfgISb8j_OeLbitjfmGD15vNb6q8fQd7I056GSB0KhR8BnHWIAXb9RN4D0OHCmtnd9BGnPU0rms2qbVXmWyxlub9dikS-zJc9m7Vbydc5xvdnIepFhna1Q8KXKq8UiW_B6iTO9FVws-Ebkt-vFkt_OpahKtc6zLK-XG1wgW3DspDZz-gCaO9_MEtbtLV8t82xmZIkmpO83IdKIphNmuZ_5Lb1wU_ZNYAtuiNjFRdTRpI--4Y3l_p2hOn3gvSOFreD7qwxVWIdZ7822jfEYKM_iwMSh0bHty7lyHRMHCj7-3Ry9-xOpZg-JTGDiMPI5bcXfAQAA__-6yzn0">