llvm.org GIT mirror llvm / 202ed57
Asan use-after-scope: don't poison allocas if there were untraced lifetime intrinsics in the function (PR41481) If there are any intrinsics that cannot be traced back to an alloca, we might have missed the start of a variable's scope, leading to false error reports if the variable is poisoned at function entry. Instead, if there are some intrinsics that can't be traced, fail safe and don't poison the variables in that function. Differential revision: https://reviews.llvm.org/D60686 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358478 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 6 months ago
2 changed file(s) with 50 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
883883 };
884884 SmallVector DynamicAllocaPoisonCallVec;
885885 SmallVector StaticAllocaPoisonCallVec;
886 bool HasUntracedLifetimeIntrinsic = false;
886887
887888 SmallVector DynamicAllocaVec;
888889 SmallVector StackRestoreVec;
916917 if (AllocaVec.empty() && DynamicAllocaVec.empty()) return false;
917918
918919 initializeCallbacks(*F.getParent());
920
921 if (HasUntracedLifetimeIntrinsic) {
922 // If there are lifetime intrinsics which couldn't be traced back to an
923 // alloca, we may not know exactly when a variable enters scope, and
924 // therefore should "fail safe" by not poisoning them.
925 StaticAllocaPoisonCallVec.clear();
926 DynamicAllocaPoisonCallVec.clear();
927 }
919928
920929 processDynamicAllocas();
921930 processStaticAllocas();
10391048 // Find alloca instruction that corresponds to llvm.lifetime argument.
10401049 AllocaInst *AI =
10411050 llvm::findAllocaForValue(II.getArgOperand(1), AllocaForValue);
1051 if (!AI) {
1052 HasUntracedLifetimeIntrinsic = true;
1053 return;
1054 }
10421055 // We're interested only in allocas we can handle.
1043 if (!AI || !ASan.isInterestingAlloca(*AI))
1056 if (!ASan.isInterestingAlloca(*AI))
10441057 return;
10451058 bool DoPoison = (ID == Intrinsic::lifetime_end);
10461059 AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison};
208208 ; CHECK: ret void
209209 }
210210
211 declare void @foo(i32*)
212 define void @PR41481(i1 %b) sanitize_address {
213 ; CHECK-LABEL: @PR41481
214 entry:
215 %p1 = alloca i32
216 %p2 = alloca i32
217 %q1 = bitcast i32* %p1 to i8*
218 %q2 = bitcast i32* %p2 to i8*
219 br label %bb1
220
221 ; Since we cannot account for all lifetime intrinsics in this function, we
222 ; might have missed a lifetime.start one and therefore shouldn't poison the
223 ; allocas at function entry.
224 ; ENTRY: store i64 -935356719533264399
225 ; ENTRY-UAS: store i64 -935356719533264399
226
227 bb1:
228 %p = select i1 %b, i32* %p1, i32* %p2
229 %q = select i1 %b, i8* %q1, i8* %q2
230 call void @llvm.lifetime.start.p0i8(i64 4, i8* %q)
231 call void @foo(i32* %p)
232 br i1 %b, label %bb2, label %bb3
233
234 bb2:
235 call void @llvm.lifetime.end.p0i8(i64 4, i8* %q1)
236 br label %end
237
238 bb3:
239 call void @llvm.lifetime.end.p0i8(i64 4, i8* %q2)
240 br label %end
241
242 end:
243 ret void
244 }
245
246
211247 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
212248 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
213249