[ubsan] nonnull and returns_nonnull sanitization

Jakub Jelinek jakub at redhat.com
Fri Jun 27 00:33:36 PDT 2014


Hi!

I wrote yesterday undefined behavior sanitization for nonnull and
returns_nonnull attributes for GCC, see
http://gcc.gnu.org/ml/gcc-patches/2014-06/msg02181.html
Users ran into issues with calling e.g. memset with NULL argument
(and zero length), or similarly for qsort, the C99 standard says that is
undefined behavior.
We are using the compiler-rt libubsan library and AFAIK clang also added
the nonnull and returns_nonnull attributes, therefore I wonder if you are
interested in accepting this into compiler-rt libubsan (and reserve
-fsanitize=nonnull and -fsanitize=returns-nonnull for command line
compatibility if you want).

If there is no interest in these, we could perhaps add GCC owned files
to libsanitize/ubsan/, but then the two libraries would start to diverge.

--- compiler-rt/lib/ubsan/ubsan_handlers.h.jj	2013-11-12 19:35:28.899621282 +0100
+++ compiler-rt/lib/ubsan/ubsan_handlers.h	2014-06-27 09:18:27.856015669 +0200
@@ -121,6 +121,20 @@ RECOVERABLE(function_type_mismatch,
             FunctionTypeMismatchData *Data,
             ValueHandle Val)
 
+struct NonNullArgData {
+  SourceLocation Loc;
+};
+
+/// \brief Handle passing null to function argument with nonnull attribute.
+RECOVERABLE(nonnull_arg, NonNullArgData *Data, uptr ArgNo)
+
+struct NonNullRetData {
+  SourceLocation Loc;
+};
+
+/// \brief Handle returning null from function with returns_nonnull attribute.
+RECOVERABLE(nonnull_return, NonNullRetData *Data)
+
 }
 
 #endif // UBSAN_HANDLERS_H
--- compiler-rt/lib/ubsan/ubsan_handlers.cc.jj	2013-11-12 19:35:28.954620998 +0100
+++ compiler-rt/lib/ubsan/ubsan_handlers.cc	2014-06-27 09:18:27.856015669 +0200
@@ -279,3 +279,31 @@ void __ubsan::__ubsan_handle_function_ty
   __ubsan_handle_function_type_mismatch(Data, Function);
   Die();
 }
+
+void __ubsan::__ubsan_handle_nonnull_arg(NonNullArgData *Data, uptr ArgNo) {
+  SourceLocation Loc = Data->Loc.acquire();
+  if (Loc.isDisabled())
+    return;
+
+  Diag(Loc, DL_Error, "null argument where non-null required "
+		      "(argument %0)") << ArgNo;
+}
+
+void __ubsan::__ubsan_handle_nonnull_arg_abort(NonNullArgData *Data,
+					       uptr ArgNo) {
+  __ubsan::__ubsan_handle_nonnull_arg(Data, ArgNo);
+  Die();
+}
+
+void __ubsan::__ubsan_handle_nonnull_return(NonNullRetData *Data) {
+  SourceLocation Loc = Data->Loc.acquire();
+  if (Loc.isDisabled())
+    return;
+
+  Diag(Loc, DL_Error, "null return value where non-null required");
+}
+
+void __ubsan::__ubsan_handle_nonnull_return_abort(NonNullRetData *Data) {
+  __ubsan::__ubsan_handle_nonnull_return(Data);
+  Die();
+}

	Jakub



More information about the llvm-commits mailing list