public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling
@ 2017-08-01  8:56 Tsimbalist, Igor V
  2017-08-15 14:08 ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Richard Biener
  2017-08-25 21:05 ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Jeff Law
  0 siblings, 2 replies; 24+ messages in thread
From: Tsimbalist, Igor V @ 2017-08-01  8:56 UTC (permalink / raw)
  To: 'gcc-patches@gcc.gnu.org'; +Cc: Tsimbalist, Igor V

[-- Attachment #1: Type: text/plain, Size: 1733 bytes --]

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).

[-- Attachment #2: 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling.patch --]
[-- Type: application/octet-stream, Size: 11535 bytes --]

From 403fc8239fb1f690cc378287b4def57dcc9d25bf Mon Sep 17 00:00:00 2001
From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
Date: Mon, 3 Jul 2017 17:11:58 +0300
Subject: [PATCH 1/9] 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).

gcc/c-family/

	* c-attribs.c (handle_notrack_attribute): New function.
	(c_common_attribute_table): Add 'notrack' handling.

gcc/

	* cfgexpand.c (expand_call_stmt): Set REG_CALL_NOTRACK.
	* combine.c (distribute_notes): Add REG_CALL_NOTRACK handling.
	* common.opt: Add finstrument-control-flow flag.
	* emit-rtl.c (try_split): Add REG_CALL_NOTRACK handling.
	* gimple.c (gimple_build_call_from_tree): Add 'notrack'
	propogation.
	* gimple.h (gf_mask): Add GF_CALL_WITH_NOTRACK.
	(gimple_call_with_notrack_p): function.
	(gimple_call_set_with_notrack): Likewise.
	* recog.c (peep2_attempt): Add REG_CALL_NOTRACK handling.
	* reg-notes.def: Add REG_NOTE (CALL_NOTRACK).
	* toplev.c (process_options): Add flag_instrument_control_flow
	handling.
---
 gcc/c-family/c-attribs.c | 23 +++++++++++++++++++++++
 gcc/cfgexpand.c          | 11 +++++++++++
 gcc/combine.c            |  1 +
 gcc/common.opt           |  5 +++++
 gcc/emit-rtl.c           |  1 +
 gcc/gimple.c             | 17 +++++++++++++++++
 gcc/gimple.h             | 34 ++++++++++++++++++++++++++++++++++
 gcc/recog.c              |  1 +
 gcc/reg-notes.def        |  7 +++++++
 gcc/toplev.c             | 11 +++++++++++
 10 files changed, 111 insertions(+)
---
 gcc/c-family/c-attribs.c | 23 +++++++++++++++++++++++
 gcc/cfgexpand.c          | 11 +++++++++++
 gcc/combine.c            |  1 +
 gcc/common.opt           |  5 +++++
 gcc/emit-rtl.c           |  1 +
 gcc/gimple.c             | 17 +++++++++++++++++
 gcc/gimple.h             | 34 ++++++++++++++++++++++++++++++++++
 gcc/recog.c              |  1 +
 gcc/reg-notes.def        |  7 +++++++
 gcc/toplev.c             | 11 +++++++++++
 10 files changed, 111 insertions(+)

diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 0d9ab2d..4d62f7c 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -65,6 +65,7 @@ static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int,
 static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
 static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
 static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
+static tree handle_notrack_attribute (tree *, tree, tree, int, bool *);
 static tree handle_noicf_attribute (tree *, tree, tree, int, bool *);
 static tree handle_noipa_attribute (tree *, tree, tree, int, bool *);
 static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
@@ -359,6 +360,8 @@ const struct attribute_spec c_common_attribute_table[] =
   { "patchable_function_entry",	1, 2, true, false, false,
 			      handle_patchable_function_entry_attribute,
 			      false },
+  { "notrack",		      0, 0, false, true, true,
+			      handle_notrack_attribute, false },
   { NULL,                     0, 0, false, false, false, NULL, false }
 };
 
@@ -775,6 +778,26 @@ handle_noclone_attribute (tree *node, tree name,
   return NULL_TREE;
 }
 
+/* Handle a "notrack" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_notrack_attribute (tree *node, tree name,
+			  tree ARG_UNUSED (args),
+			  int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_TYPE
+      && TREE_CODE (*node) != METHOD_TYPE
+      && TREE_CODE (*node) != FIELD_DECL
+      && TREE_CODE (*node) != TYPE_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "no_icf" attribute; arguments as in
    struct attribute_spec.handler.  */
 
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index c9d8118..ed344c5 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2657,12 +2657,23 @@ expand_call_stmt (gcall *stmt)
 	  }
     }
 
+  rtx_insn *before_call = get_last_insn ();
   lhs = gimple_call_lhs (stmt);
   if (lhs)
     expand_assignment (lhs, exp, false);
   else
     expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
 
+  /* Find a generated CALL insn to propagate a 'notrack' attribute.  */
+  rtx_insn *last = get_last_insn ();
+  while (!CALL_P (last)
+	 && (last != before_call))
+    last = PREV_INSN (last);
+
+  if (last != before_call
+      && gimple_call_with_notrack_p (stmt))
+    add_reg_note (last, REG_CALL_NOTRACK, const0_rtx);
+
   mark_transaction_restart_calls (stmt);
 }
 
diff --git a/gcc/combine.c b/gcc/combine.c
index 8dc62b5..a9e5e4f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -14029,6 +14029,7 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
 	case REG_SETJMP:
 	case REG_TM:
 	case REG_CALL_DECL:
+	case REG_CALL_NOTRACK:
 	  /* These notes must remain with the call.  It should not be
 	     possible for both I2 and I3 to be a call.  */
 	  if (CALL_P (i3))
diff --git a/gcc/common.opt b/gcc/common.opt
index 78cfa56..21069bb 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1602,6 +1602,11 @@ finline-atomics
 Common Report Var(flag_inline_atomics) Init(1) Optimization
 Inline __atomic operations when a lock free instruction sequence is available.
 
+finstrument-control-flow
+Common Report Var(flag_instrument_control_flow) Init(-1)
+Instrument functions with checks to verify jump/call control-flow transfer
+instructions have valid targets.
+
 finstrument-functions
 Common Report Var(flag_instrument_function_entry_exit)
 Instrument function entry and exit with profiling calls.
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 2bc5d56..b8744fb 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3780,6 +3780,7 @@ try_split (rtx pat, rtx_insn *trial, int last)
 	case REG_NORETURN:
 	case REG_SETJMP:
 	case REG_TM:
+	case REG_CALL_NOTRACK:
 	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
 	    {
 	      if (CALL_P (insn))
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);
+	}
+    }
+
   return call;
 }
 
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 2d81eed..afd38f0 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -148,6 +148,7 @@ enum gf_mask {
     GF_CALL_WITH_BOUNDS 	= 1 << 8,
     GF_CALL_MUST_TAIL_CALL	= 1 << 9,
     GF_CALL_BY_DESCRIPTOR	= 1 << 10,
+    GF_CALL_WITH_NOTRACK 	= 1 << 11,
     GF_OMP_PARALLEL_COMBINED	= 1 << 0,
     GF_OMP_PARALLEL_GRID_PHONY = 1 << 1,
     GF_OMP_TASK_TASKLOOP	= 1 << 0,
@@ -2898,6 +2899,39 @@ gimple_call_set_with_bounds (gimple *gs, bool with_bounds)
 }
 
 
+/* Return true if call GS is marked as no-track.  */
+
+static inline bool
+gimple_call_with_notrack_p (const gcall *gs)
+{
+  return (gs->subcode & GF_CALL_WITH_NOTRACK) != 0;
+}
+
+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);
+}
+
+/* Mark statement GS as no-track call.  */
+
+static inline void
+gimple_call_set_with_notrack (gcall *gs, bool with_notrack)
+{
+  if (with_notrack)
+    gs->subcode |= GF_CALL_WITH_NOTRACK;
+  else
+    gs->subcode &= ~GF_CALL_WITH_NOTRACK;
+}
+
+static inline void
+gimple_call_set_with_notrack (gimple *gs, bool with_notrack)
+{
+  gcall *gc = GIMPLE_CHECK2<gcall *> (gs);
+  gimple_call_set_with_notrack (gc, with_notrack);
+}
+
 /* Return the target of internal call GS.  */
 
 static inline enum internal_fn
diff --git a/gcc/recog.c b/gcc/recog.c
index fd4e460..f2af977 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3387,6 +3387,7 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
 	  case REG_NORETURN:
 	  case REG_SETJMP:
 	  case REG_TM:
+	  case REG_CALL_NOTRACK:
 	    add_reg_note (new_insn, REG_NOTE_KIND (note),
 			  XEXP (note, 0));
 	    break;
diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def
index 943eff4..f02bcc9 100644
--- a/gcc/reg-notes.def
+++ b/gcc/reg-notes.def
@@ -228,3 +228,10 @@ REG_NOTE (RETURNED)
    The decl might not be available in the call due to splitting of the call
    insn.  This note is a SYMBOL_REF.  */
 REG_NOTE (CALL_DECL)
+
+/* Indicate that a call is a NOTRACK call.  The target address of the call
+   is assumed as a valid address and no check to validate the target
+   address is needed.  The call is marked when a called function has a
+   'notrack' attribute.  This note is used by the compiler when the option
+   -finstrument-control-flow is specified.  */
+REG_NOTE (CALL_NOTRACK)
diff --git a/gcc/toplev.c b/gcc/toplev.c
index b28f184..c20a6ea 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1283,6 +1283,17 @@ process_options (void)
 	   "-floop-parallelize-all)");
 #endif
 
+  if (flag_instrument_control_flow == -1)
+    flag_instrument_control_flow = 0;
+  else if (flag_instrument_control_flow > 0
+	   && flag_instrument_control_flow != 2)
+    {
+      error_at (UNKNOWN_LOCATION,
+		"%<-finstrument-control-flow%> is not supported for this "
+		"target");
+      flag_instrument_control_flow = 0;
+    }
+
   if (flag_check_pointer_bounds)
     {
       if (targetm.chkp_bound_mode () == VOIDmode)
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2017-10-12 15:10 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-01  8:56 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-08-15 14:08 ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Richard Biener
2017-08-18 14:01   ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-08-18 14:06     ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Richard Biener
2017-08-18 14:58       ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-09-12 15:34       ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-09-15 11:12       ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-09-15 12:14         ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Richard Biener
2017-09-19 13:39           ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-09-28 22:44             ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Jeff Law
2017-09-29 14:31               ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-09-29 16:04                 ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-10-05 10:20                   ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-10-12  6:26                     ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Jeff Law
2017-10-12  8:33                       ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-10-12 15:15                         ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Jeff Law
2017-08-25 21:03   ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Jeff Law
2017-09-12 15:40     ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-09-13 19:05       ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Jeff Law
2017-08-25 21:05 ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Jeff Law
2017-09-12 15:59   ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-09-13 18:56     ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Jeff Law
2017-09-13 17:08   ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Tsimbalist, Igor V
2017-09-13 19:01     ` 0001-Part-1.-Add-generic-part-for-Intel-CET-enabling Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).