<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW " title="NEW --- - When both asan and ubsan are enabled, use asan to detect address validity for ubsan checks" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D24069&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=C2Fm_oKp7E5jii00IyG8MgCGo5rL0dXnBU3N2mYLC6Y&s=aZuJ3J8jrihXLRtguR-rLh0MopBACfMb5N6K8V0KBY0&e=">24069</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>When both asan and ubsan are enabled, use asan to detect address validity for ubsan checks
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>LLVM Codegen
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>richard-llvm@metafoo.co.uk
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Similar to PR19811: when asan and ubsan are both enabled, and ubsan emits a
type-check for some pointer, it should also query asan's shadow map to
determine whether the pointer points to addressable storage.
More specifically, in CodeGenFunction::EmitTypeCheck, around where we emit a
call to the llvm.objectsize intrinsic, we should emit something else that the
asan instrumentation can lower into a size check.
One possibility: replace the call to llvm.objectsize with a call to a new "i1
@llvm.objectsize.atleast.i64(i8* %0, i64 %1)" that determines whether %0 is
known to point to an object of size at least %1 bytes (returning i1 true if
unknown); asan can lower that to a shadow map check, and llvm can otherwise
lower it to @llvm.objectsize plus a comparison.
Some sample cases that we should be able to catch with this change:
* Reference-binding, member access, pointer cast after free:
struct S { void f() {} int n; }; struct T : S {};
S *p = new S;
delete p;
S &r = *p; // #1
int *k = &p->n; // #2
p->f(); // #3
T *q = (T*)p; // #4
(and so on, for each case that the ubsan objectsize / null sanitizers catch
today).
* Bad downcasts where the target type is too large:
struct A { int n; };
struct B : A { int m; };
A *f() { return new A; } // assume not inlined
B *p = (B*)f(); // catch this because we can't address 8 bytes from f().
* Placement new on insufficient storage:
char arr[8];
struct A { int x, y, z; A() {} };
new (arr) A;</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>