On Tue, Aug 1, 2017 at 10:56 AM, Tsimbalist, Igor V
<igor.v.tsimbal...@intel.com> wrote:
> Part#1. Add generic part for Intel CET enabling.
>
> The spec is available at
>
> https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
>
> High-level design.
> ------------------
>
> A proposal is to introduce a target independent flag
> -finstrument-control-flow with a semantic to instrument a code to
> control validness or integrity of control-flow transfers using jump
> and call instructions. The main goal is to detect and block a possible
> malware execution through transfer the execution to unknown target
> address. Implementation could be either software or target based. Any
> target platforms can provide their implementation for instrumentation
> under this option.
>
> When the -finstrument-control-flow flag is set each implementation has
> to check if a support exists for a target platform and report an error
> if no support is found.
>
> The compiler should instrument any control-flow transfer points in a
> program (ex. call/jmp/ret) as well as any landing pads, which are
> targets of for control-flow transfers.
>
> A new 'notrack' attribute is introduced to provide hand tuning support.
> The attribute directs the compiler to skip a call to a function and a
> function's landing pad from instrumentation (tracking). The attribute
> can be used for function and pointer to function types, otherwise it
> will be ignored. The attribute is saved in a type and propagated to a
> GIMPLE call statement and later to a call instruction.
>
> Currently all platforms except i386 will report the error and do no
> instrumentation. i386 will provide the implementation based on a
> specification published by Intel for a new technology called
> Control-flow Enforcement Technology (CET).

diff --git a/gcc/gimple.c b/gcc/gimple.c
index 479f90c..2e4ab2d 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -378,6 +378,23 @@ gimple_build_call_from_tree (tree t)
   gimple_set_no_warning (call, TREE_NO_WARNING (t));
   gimple_call_set_with_bounds (call, CALL_WITH_BOUNDS_P (t));

+  if (fndecl == NULL_TREE)
+    {
+      /* Find the type of an indirect call.  */
+      tree addr = CALL_EXPR_FN (t);
+      if (TREE_CODE (addr) != FUNCTION_DECL)
+       {
+         tree fntype = TREE_TYPE (addr);
+         gcc_assert (POINTER_TYPE_P (fntype));
+         fntype = TREE_TYPE (fntype);
+
+         /* Check if its type has the no-track attribute and propagate
+            it to the CALL insn.  */
+         if (lookup_attribute ("notrack", TYPE_ATTRIBUTES (fntype)))
+           gimple_call_set_with_notrack (call, TRUE);
+       }
+    }

this means notrack is not recognized if fndecl is not NULL.  Note that only
the two callers know the real function type in effect (they call
gimple_call_set_fntype with it).  I suggest to pass down that type
to gimple_build_call_from_tree and move the gimple_call_set_fntype
call there as well.  And simply use the type for the above.

+static inline bool
+gimple_call_with_notrack_p (const gimple *gs)
+{
+  const gcall *gc = GIMPLE_CHECK2<const gcall *> (gs);
+  return gimple_call_with_notrack_p (gc);
+}

please do not add gimple * overloads for new APIs, instead make
sure to pass down gcalls at callers.

Please change the names to omit 'with_', thus just notrack
and GF_CALL_NOTRACK.

I think 'notrack' is somewhat unspecific of a name, what prevented
you to use 'nocet'?

Any idea how to implement a software-based solution efficiently?
Creating a table of valid destination addresses in a special section
should be possible without too much work, am I right in that only
indirect control transfer is checked?  Thus CET assumes the
code itself cannot be changed (and thus the stack isn't executable)?

Thanks,
Richard.

Reply via email to