melver created this revision.
melver added reviewers: jfb, pcc, glider.
melver requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

When `-ftrivial-auto-var-init=` is enabled, allocas unconditionally
receive auto-initialization since [1].

In certain cases, it turns out, this is causing problems. For example,
when using alloca to add a random stack offset, as the Linux kernel does
on syscall entry [2]. In this case, none of the alloca'd stack memory is
ever used, and initializing it should be controllable; furthermore, it
is not always possible to safely call memset (see [2]).

Introduce `__builtin_alloca_uninitialized()`, which never performs
initialization when `-ftrivial-auto-var-init=` is enabled.

[1] https://reviews.llvm.org/D60548
[2] https://lkml.kernel.org/r/ybhtkujeejzcl...@elver.google.com


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115440

Files:
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGenCXX/trivial-auto-var-init.cpp
  clang/test/Sema/warn-alloca.c


Index: clang/test/Sema/warn-alloca.c
===================================================================
--- clang/test/Sema/warn-alloca.c
+++ clang/test/Sema/warn-alloca.c
@@ -18,3 +18,10 @@
   // expected-warning@-2 {{use of function '__builtin_alloca_with_align' is 
discouraged; there is no way to check for failure but failure may still occur, 
resulting in a possibly exploitable security vulnerability}}
 #endif
 }
+
+void test3(int a) {
+  __builtin_alloca_uninitialized(a);
+#ifndef SILENCE
+  // expected-warning@-2 {{use of function '__builtin_alloca_uninitialized' is 
discouraged; there is no way to check for failure but failure may still occur, 
resulting in a possibly exploitable security vulnerability}}
+#endif
+}
Index: clang/test/CodeGenCXX/trivial-auto-var-init.cpp
===================================================================
--- clang/test/CodeGenCXX/trivial-auto-var-init.cpp
+++ clang/test/CodeGenCXX/trivial-auto-var-init.cpp
@@ -201,6 +201,20 @@
   used(ptr);
 }
 
+// UNINIT-LABEL:  test_alloca_uninitialized(
+// ZERO-LABEL:    test_alloca_uninitialized(
+// ZERO:          %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// ZERO-NEXT:     %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align 
[[ALIGN:[0-9]+]]
+// ZERO-NOT:      call void @llvm.memset
+// PATTERN-LABEL: test_alloca_uninitialized(
+// PATTERN:       %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// PATTERN-NEXT:  %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align 
[[ALIGN:[0-9]+]]
+// PATTERN-NOT:   call void @llvm.memset
+void test_alloca_uninitialized(int size) {
+  void *ptr = __builtin_alloca_uninitialized(size);
+  used(ptr);
+}
+
 // UNINIT-LABEL:  test_struct_vla(
 // ZERO-LABEL:    test_struct_vla(
 // ZERO:  %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1686,6 +1686,7 @@
     if (SemaBuiltinAllocaWithAlign(TheCall))
       return ExprError();
     LLVM_FALLTHROUGH;
+  case Builtin::BI__builtin_alloca_uninitialized:
   case Builtin::BI__builtin_alloca:
     Diag(TheCall->getBeginLoc(), diag::warn_alloca)
         << TheCall->getDirectCallee();
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -3417,6 +3417,7 @@
 
   case Builtin::BIalloca:
   case Builtin::BI_alloca:
+  case Builtin::BI__builtin_alloca_uninitialized:
   case Builtin::BI__builtin_alloca: {
     Value *Size = EmitScalarExpr(E->getArg(0));
     const TargetInfo &TI = getContext().getTargetInfo();
@@ -3427,7 +3428,8 @@
             .getAsAlign();
     AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
     AI->setAlignment(SuitableAlignmentInBytes);
-    initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes);
+    if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized)
+      initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes);
     return RValue::get(AI);
   }
 
Index: clang/include/clang/Basic/Builtins.def
===================================================================
--- clang/include/clang/Basic/Builtins.def
+++ clang/include/clang/Basic/Builtins.def
@@ -640,6 +640,7 @@
 BUILTIN(__builtin_shufflevector, "v."   , "nct")
 BUILTIN(__builtin_convertvector, "v."   , "nct")
 BUILTIN(__builtin_alloca, "v*z"   , "Fn")
+BUILTIN(__builtin_alloca_uninitialized, "v*z", "Fn")
 BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn")
 BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
 


Index: clang/test/Sema/warn-alloca.c
===================================================================
--- clang/test/Sema/warn-alloca.c
+++ clang/test/Sema/warn-alloca.c
@@ -18,3 +18,10 @@
   // expected-warning@-2 {{use of function '__builtin_alloca_with_align' is discouraged; there is no way to check for failure but failure may still occur, resulting in a possibly exploitable security vulnerability}}
 #endif
 }
+
+void test3(int a) {
+  __builtin_alloca_uninitialized(a);
+#ifndef SILENCE
+  // expected-warning@-2 {{use of function '__builtin_alloca_uninitialized' is discouraged; there is no way to check for failure but failure may still occur, resulting in a possibly exploitable security vulnerability}}
+#endif
+}
Index: clang/test/CodeGenCXX/trivial-auto-var-init.cpp
===================================================================
--- clang/test/CodeGenCXX/trivial-auto-var-init.cpp
+++ clang/test/CodeGenCXX/trivial-auto-var-init.cpp
@@ -201,6 +201,20 @@
   used(ptr);
 }
 
+// UNINIT-LABEL:  test_alloca_uninitialized(
+// ZERO-LABEL:    test_alloca_uninitialized(
+// ZERO:          %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// ZERO-NEXT:     %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align [[ALIGN:[0-9]+]]
+// ZERO-NOT:      call void @llvm.memset
+// PATTERN-LABEL: test_alloca_uninitialized(
+// PATTERN:       %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// PATTERN-NEXT:  %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align [[ALIGN:[0-9]+]]
+// PATTERN-NOT:   call void @llvm.memset
+void test_alloca_uninitialized(int size) {
+  void *ptr = __builtin_alloca_uninitialized(size);
+  used(ptr);
+}
+
 // UNINIT-LABEL:  test_struct_vla(
 // ZERO-LABEL:    test_struct_vla(
 // ZERO:  %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1686,6 +1686,7 @@
     if (SemaBuiltinAllocaWithAlign(TheCall))
       return ExprError();
     LLVM_FALLTHROUGH;
+  case Builtin::BI__builtin_alloca_uninitialized:
   case Builtin::BI__builtin_alloca:
     Diag(TheCall->getBeginLoc(), diag::warn_alloca)
         << TheCall->getDirectCallee();
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -3417,6 +3417,7 @@
 
   case Builtin::BIalloca:
   case Builtin::BI_alloca:
+  case Builtin::BI__builtin_alloca_uninitialized:
   case Builtin::BI__builtin_alloca: {
     Value *Size = EmitScalarExpr(E->getArg(0));
     const TargetInfo &TI = getContext().getTargetInfo();
@@ -3427,7 +3428,8 @@
             .getAsAlign();
     AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
     AI->setAlignment(SuitableAlignmentInBytes);
-    initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes);
+    if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized)
+      initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes);
     return RValue::get(AI);
   }
 
Index: clang/include/clang/Basic/Builtins.def
===================================================================
--- clang/include/clang/Basic/Builtins.def
+++ clang/include/clang/Basic/Builtins.def
@@ -640,6 +640,7 @@
 BUILTIN(__builtin_shufflevector, "v."   , "nct")
 BUILTIN(__builtin_convertvector, "v."   , "nct")
 BUILTIN(__builtin_alloca, "v*z"   , "Fn")
+BUILTIN(__builtin_alloca_uninitialized, "v*z", "Fn")
 BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn")
 BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to