* [PATCH v2] [RISC-V] Add support for TLS stack protector canary access
@ 2020-07-13 8:15 cooper
2020-07-20 2:03 ` cooper
0 siblings, 1 reply; 7+ messages in thread
From: cooper @ 2020-07-13 8:15 UTC (permalink / raw)
To: gcc-patches, jimw; +Cc: guoren, cooper
gcc/
* config/riscv/riscv-opts.h (stack_protector_guard): New enum.
* config/riscv/riscv.c (riscv_option_override): Handle
the new options.
* config/riscv/riscv.md (stack_protect_set): New pattern to handle
flexible stack protector guard settings.
(stack_protect_set_<mode>): Ditto.
(stack_protect_test): Ditto.
(stack_protect_test_<mode>): Ditto.
* config/riscv/riscv.opt (mstack-protector-guard=,
mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
options.
* doc/invoke.texi (Option Summary) [RISC-V Options]:
Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
-mstack-protector-guard-offset=.
(RISC-V Options): Ditto.
Signed-off-by: cooper <cooper.qu@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
gcc/config/riscv/riscv-opts.h | 6 +++
gcc/config/riscv/riscv.c | 47 ++++++++++++++++++++
gcc/config/riscv/riscv.md | 80 +++++++++++++++++++++++++++++++++++
gcc/config/riscv/riscv.opt | 28 ++++++++++++
gcc/doc/invoke.texi | 22 +++++++++-
5 files changed, 182 insertions(+), 1 deletion(-)
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 8f12e50b9f1..2a3f9d9eef5 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -51,4 +51,10 @@ enum riscv_align_data {
riscv_align_data_type_natural
};
+/* Where to get the canary for the stack protector. */
+enum stack_protector_guard {
+ SSP_TLS, /* per-thread canary in TLS block */
+ SSP_GLOBAL /* global canary */
+};
+
#endif /* ! GCC_RISCV_OPTS_H */
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index bfb3885ed08..63b0c3877b0 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -4775,6 +4775,53 @@ riscv_option_override (void)
" [%<-mriscv-attribute%>]");
#endif
+ if (riscv_stack_protector_guard == SSP_GLOBAL
+ && global_options_set.x_riscv_stack_protector_guard_offset_str)
+ {
+ error ("incompatible options %<-mstack-protector-guard=global%> and "
+ "%<-mstack-protector-guard-offset=%s%>",
+ riscv_stack_protector_guard_offset_str);
+ }
+
+ if (riscv_stack_protector_guard == SSP_TLS
+ && !(global_options_set.x_riscv_stack_protector_guard_offset_str
+ && global_options_set.x_riscv_stack_protector_guard_reg_str))
+ {
+ error ("both %<-mstack-protector-guard-offset%> and "
+ "%<-mstack-protector-guard-reg%> must be used "
+ "with %<-mstack-protector-guard=sysreg%>");
+ }
+
+ if (global_options_set.x_riscv_stack_protector_guard_reg_str)
+ {
+ const char *str = riscv_stack_protector_guard_reg_str;
+ int reg = decode_reg_name (str);
+
+ if (!IN_RANGE (reg, GP_REG_FIRST + 1, GP_REG_LAST))
+ error ("%qs is not a valid base register in %qs", str,
+ "-mstack-protector-guard-reg=");
+
+ riscv_stack_protector_guard_reg = reg;
+ }
+
+ if (global_options_set.x_riscv_stack_protector_guard_offset_str)
+ {
+ char *end;
+ const char *str = riscv_stack_protector_guard_offset_str;
+ errno = 0;
+ long offs = strtol (riscv_stack_protector_guard_offset_str, &end, 0);
+
+ if (!*str || *end || errno)
+ error ("%qs is not a valid number in %qs", str,
+ "-mstack-protector-guard-offset=");
+
+ if (!SMALL_OPERAND (offs))
+ error ("%qs is not a valid offset in %qs", str,
+ "-mstack-protector-guard-offset=");
+
+ riscv_stack_protector_guard_offset = offs;
+ }
+
}
/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 95a02ecaa34..f15bad3b29e 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -65,6 +65,10 @@
UNSPECV_BLOCKAGE
UNSPECV_FENCE
UNSPECV_FENCE_I
+
+ ;; Stack Smash Protector
+ UNSPEC_SSP_SET
+ UNSPEC_SSP_TEST
])
(define_constants
@@ -2523,6 +2527,82 @@
""
{})
+;; Named patterns for stack smashing protection.
+
+(define_expand "stack_protect_set"
+ [(match_operand 0 "memory_operand")
+ (match_operand 1 "memory_operand")]
+ ""
+{
+ machine_mode mode = GET_MODE (operands[0]);
+ if (riscv_stack_protector_guard == SSP_TLS)
+ {
+ rtx reg = gen_rtx_REG (Pmode, riscv_stack_protector_guard_reg);
+ rtx offset = GEN_INT (riscv_stack_protector_guard_offset);
+ rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
+ operands[1] = gen_rtx_MEM (Pmode, addr);
+ }
+
+ emit_insn ((mode == DImode
+ ? gen_stack_protect_set_di
+ : gen_stack_protect_set_si) (operands[0], operands[1]));
+ DONE;
+})
+
+;; DO NOT SPLIT THIS PATTERN. It is important for security reasons that the
+;; canary value does not live beyond the life of this sequence.
+(define_insn "stack_protect_set_<mode>"
+ [(set (match_operand:GPR 0 "memory_operand" "=m")
+ (unspec:GPR [(match_operand:GPR 1 "memory_operand" "m")]
+ UNSPEC_SSP_SET))
+ (set (match_scratch:GPR 2 "=&r") (const_int 0))]
+ ""
+ "<load>\\t%2, %1\;<store>\\t%2, %0\;li\t%2, 0"
+ [(set_attr "length" "12")])
+
+(define_expand "stack_protect_test"
+ [(match_operand 0 "memory_operand")
+ (match_operand 1 "memory_operand")
+ (match_operand 2)]
+ ""
+{
+ rtx result;
+ machine_mode mode = GET_MODE (operands[0]);
+
+ result = gen_reg_rtx(mode);
+ if (riscv_stack_protector_guard == SSP_TLS)
+ {
+ rtx reg = gen_rtx_REG (Pmode, riscv_stack_protector_guard_reg);
+ rtx offset = GEN_INT (riscv_stack_protector_guard_offset);
+ rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
+ operands[1] = gen_rtx_MEM (Pmode, addr);
+ }
+ emit_insn ((mode == DImode
+ ? gen_stack_protect_test_di
+ : gen_stack_protect_test_si) (result,
+ operands[0],
+ operands[1]));
+
+ if (mode == DImode)
+ emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
+ result, const0_rtx, operands[2]));
+ else
+ emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
+ result, const0_rtx, operands[2]));
+
+ DONE;
+})
+
+(define_insn "stack_protect_test_<mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=r")
+ (unspec:GPR [(match_operand:GPR 1 "memory_operand" "m")
+ (match_operand:GPR 2 "memory_operand" "m")]
+ UNSPEC_SSP_TEST))
+ (clobber (match_scratch:GPR 3 "=&r"))]
+ ""
+ "<load>\t%3, %1\;<load>\t%0, %2\;xor\t%0, %3, %0\;li\t%3, 0"
+ [(set_attr "length" "12")])
+
(include "sync.md")
(include "peephole.md")
(include "pic.md")
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index e4bfcb86f51..f01d3ab79c3 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -151,3 +151,31 @@ Enum(riscv_align_data) String(xlen) Value(riscv_align_data_type_xlen)
EnumValue
Enum(riscv_align_data) String(natural) Value(riscv_align_data_type_natural)
+
+mstack-protector-guard=
+Target RejectNegative Joined Enum(stack_protector_guard) Var(riscv_stack_protector_guard) Init(SSP_GLOBAL)
+Use given stack-protector guard.
+
+Enum
+Name(stack_protector_guard) Type(enum stack_protector_guard)
+Valid arguments to -mstack-protector-guard=:
+
+EnumValue
+Enum(stack_protector_guard) String(tls) Value(SSP_TLS)
+
+EnumValue
+Enum(stack_protector_guard) String(global) Value(SSP_GLOBAL)
+
+mstack-protector-guard-reg=
+Target RejectNegative Joined Var(riscv_stack_protector_guard_reg_str)
+Use the given base register for addressing the stack-protector guard.
+
+TargetVariable
+int riscv_stack_protector_guard_reg = 0
+
+mstack-protector-guard-offset=
+Target RejectNegative Joined Integer Var(riscv_stack_protector_guard_offset_str)
+Use the given offset for addressing the stack-protector guard.
+
+TargetVariable
+long riscv_stack_protector_guard_offset = 0
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 09bcc5b0f78..3bb124ae6ed 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1138,7 +1138,9 @@ See RS/6000 and PowerPC Options.
-mexplicit-relocs -mno-explicit-relocs @gol
-mrelax -mno-relax @gol
-mriscv-attribute -mmo-riscv-attribute @gol
--malign-data=@var{type}}
+-malign-data=@var{type} @gol
++-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol
++-mstack-protector-guard-offset=@var{offset}}
@emph{RL78 Options}
@gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs @gol
@@ -25723,6 +25725,24 @@ Control how GCC aligns variables and constants of array, structure, or union
types. Supported values for @var{type} are @samp{xlen} which uses x register
width as the alignment value, and @samp{natural} which uses natural alignment.
@samp{xlen} is the default.
+
+@item -mstack-protector-guard=@var{guard}
+@itemx -mstack-protector-guard-reg=@var{reg}
+@itemx -mstack-protector-guard-offset=@var{offset}
+@opindex mstack-protector-guard
+@opindex mstack-protector-guard-reg
+@opindex mstack-protector-guard-offset
+Generate stack protection code using canary at @var{guard}. Supported
+locations are @samp{global} for a global canary or @samp{tls} for per-thread
+canary in the TLS block.
+
+With the latter choice the options
+@option{-mstack-protector-guard-reg=@var{reg}} and
+@option{-mstack-protector-guard-offset=@var{offset}} furthermore specify
+which register to use as base register for reading the canary,
+and from what offset from that base register. There is no default
+register or offset as this is entirely for use within the Linux
+kernel.
@end table
@node RL78 Options
--
2.26.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] [RISC-V] Add support for TLS stack protector canary access
2020-07-13 8:15 [PATCH v2] [RISC-V] Add support for TLS stack protector canary access cooper
@ 2020-07-20 2:03 ` cooper
2020-07-21 8:14 ` Kito Cheng
2020-07-27 22:54 ` Jim Wilson
0 siblings, 2 replies; 7+ messages in thread
From: cooper @ 2020-07-20 2:03 UTC (permalink / raw)
To: gcc-patches, jimw; +Cc: guoren
Ping
On 2020/7/13 下午4:15, cooper wrote:
> gcc/
> * config/riscv/riscv-opts.h (stack_protector_guard): New enum.
> * config/riscv/riscv.c (riscv_option_override): Handle
> the new options.
> * config/riscv/riscv.md (stack_protect_set): New pattern to handle
> flexible stack protector guard settings.
> (stack_protect_set_<mode>): Ditto.
> (stack_protect_test): Ditto.
> (stack_protect_test_<mode>): Ditto.
> * config/riscv/riscv.opt (mstack-protector-guard=,
> mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
> options.
> * doc/invoke.texi (Option Summary) [RISC-V Options]:
> Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
> -mstack-protector-guard-offset=.
> (RISC-V Options): Ditto.
>
> Signed-off-by: cooper <cooper.qu@linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
> gcc/config/riscv/riscv-opts.h | 6 +++
> gcc/config/riscv/riscv.c | 47 ++++++++++++++++++++
> gcc/config/riscv/riscv.md | 80 +++++++++++++++++++++++++++++++++++
> gcc/config/riscv/riscv.opt | 28 ++++++++++++
> gcc/doc/invoke.texi | 22 +++++++++-
> 5 files changed, 182 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
> index 8f12e50b9f1..2a3f9d9eef5 100644
> --- a/gcc/config/riscv/riscv-opts.h
> +++ b/gcc/config/riscv/riscv-opts.h
> @@ -51,4 +51,10 @@ enum riscv_align_data {
> riscv_align_data_type_natural
> };
>
> +/* Where to get the canary for the stack protector. */
> +enum stack_protector_guard {
> + SSP_TLS, /* per-thread canary in TLS block */
> + SSP_GLOBAL /* global canary */
> +};
> +
> #endif /* ! GCC_RISCV_OPTS_H */
> diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
> index bfb3885ed08..63b0c3877b0 100644
> --- a/gcc/config/riscv/riscv.c
> +++ b/gcc/config/riscv/riscv.c
> @@ -4775,6 +4775,53 @@ riscv_option_override (void)
> " [%<-mriscv-attribute%>]");
> #endif
>
> + if (riscv_stack_protector_guard == SSP_GLOBAL
> + && global_options_set.x_riscv_stack_protector_guard_offset_str)
> + {
> + error ("incompatible options %<-mstack-protector-guard=global%> and "
> + "%<-mstack-protector-guard-offset=%s%>",
> + riscv_stack_protector_guard_offset_str);
> + }
> +
> + if (riscv_stack_protector_guard == SSP_TLS
> + && !(global_options_set.x_riscv_stack_protector_guard_offset_str
> + && global_options_set.x_riscv_stack_protector_guard_reg_str))
> + {
> + error ("both %<-mstack-protector-guard-offset%> and "
> + "%<-mstack-protector-guard-reg%> must be used "
> + "with %<-mstack-protector-guard=sysreg%>");
> + }
> +
> + if (global_options_set.x_riscv_stack_protector_guard_reg_str)
> + {
> + const char *str = riscv_stack_protector_guard_reg_str;
> + int reg = decode_reg_name (str);
> +
> + if (!IN_RANGE (reg, GP_REG_FIRST + 1, GP_REG_LAST))
> + error ("%qs is not a valid base register in %qs", str,
> + "-mstack-protector-guard-reg=");
> +
> + riscv_stack_protector_guard_reg = reg;
> + }
> +
> + if (global_options_set.x_riscv_stack_protector_guard_offset_str)
> + {
> + char *end;
> + const char *str = riscv_stack_protector_guard_offset_str;
> + errno = 0;
> + long offs = strtol (riscv_stack_protector_guard_offset_str, &end, 0);
> +
> + if (!*str || *end || errno)
> + error ("%qs is not a valid number in %qs", str,
> + "-mstack-protector-guard-offset=");
> +
> + if (!SMALL_OPERAND (offs))
> + error ("%qs is not a valid offset in %qs", str,
> + "-mstack-protector-guard-offset=");
> +
> + riscv_stack_protector_guard_offset = offs;
> + }
> +
> }
>
> /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
> diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
> index 95a02ecaa34..f15bad3b29e 100644
> --- a/gcc/config/riscv/riscv.md
> +++ b/gcc/config/riscv/riscv.md
> @@ -65,6 +65,10 @@
> UNSPECV_BLOCKAGE
> UNSPECV_FENCE
> UNSPECV_FENCE_I
> +
> + ;; Stack Smash Protector
> + UNSPEC_SSP_SET
> + UNSPEC_SSP_TEST
> ])
>
> (define_constants
> @@ -2523,6 +2527,82 @@
> ""
> {})
>
> +;; Named patterns for stack smashing protection.
> +
> +(define_expand "stack_protect_set"
> + [(match_operand 0 "memory_operand")
> + (match_operand 1 "memory_operand")]
> + ""
> +{
> + machine_mode mode = GET_MODE (operands[0]);
> + if (riscv_stack_protector_guard == SSP_TLS)
> + {
> + rtx reg = gen_rtx_REG (Pmode, riscv_stack_protector_guard_reg);
> + rtx offset = GEN_INT (riscv_stack_protector_guard_offset);
> + rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
> + operands[1] = gen_rtx_MEM (Pmode, addr);
> + }
> +
> + emit_insn ((mode == DImode
> + ? gen_stack_protect_set_di
> + : gen_stack_protect_set_si) (operands[0], operands[1]));
> + DONE;
> +})
> +
> +;; DO NOT SPLIT THIS PATTERN. It is important for security reasons that the
> +;; canary value does not live beyond the life of this sequence.
> +(define_insn "stack_protect_set_<mode>"
> + [(set (match_operand:GPR 0 "memory_operand" "=m")
> + (unspec:GPR [(match_operand:GPR 1 "memory_operand" "m")]
> + UNSPEC_SSP_SET))
> + (set (match_scratch:GPR 2 "=&r") (const_int 0))]
> + ""
> + "<load>\\t%2, %1\;<store>\\t%2, %0\;li\t%2, 0"
> + [(set_attr "length" "12")])
> +
> +(define_expand "stack_protect_test"
> + [(match_operand 0 "memory_operand")
> + (match_operand 1 "memory_operand")
> + (match_operand 2)]
> + ""
> +{
> + rtx result;
> + machine_mode mode = GET_MODE (operands[0]);
> +
> + result = gen_reg_rtx(mode);
> + if (riscv_stack_protector_guard == SSP_TLS)
> + {
> + rtx reg = gen_rtx_REG (Pmode, riscv_stack_protector_guard_reg);
> + rtx offset = GEN_INT (riscv_stack_protector_guard_offset);
> + rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
> + operands[1] = gen_rtx_MEM (Pmode, addr);
> + }
> + emit_insn ((mode == DImode
> + ? gen_stack_protect_test_di
> + : gen_stack_protect_test_si) (result,
> + operands[0],
> + operands[1]));
> +
> + if (mode == DImode)
> + emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
> + result, const0_rtx, operands[2]));
> + else
> + emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
> + result, const0_rtx, operands[2]));
> +
> + DONE;
> +})
> +
> +(define_insn "stack_protect_test_<mode>"
> + [(set (match_operand:GPR 0 "register_operand" "=r")
> + (unspec:GPR [(match_operand:GPR 1 "memory_operand" "m")
> + (match_operand:GPR 2 "memory_operand" "m")]
> + UNSPEC_SSP_TEST))
> + (clobber (match_scratch:GPR 3 "=&r"))]
> + ""
> + "<load>\t%3, %1\;<load>\t%0, %2\;xor\t%0, %3, %0\;li\t%3, 0"
> + [(set_attr "length" "12")])
> +
> (include "sync.md")
> (include "peephole.md")
> (include "pic.md")
> diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
> index e4bfcb86f51..f01d3ab79c3 100644
> --- a/gcc/config/riscv/riscv.opt
> +++ b/gcc/config/riscv/riscv.opt
> @@ -151,3 +151,31 @@ Enum(riscv_align_data) String(xlen) Value(riscv_align_data_type_xlen)
>
> EnumValue
> Enum(riscv_align_data) String(natural) Value(riscv_align_data_type_natural)
> +
> +mstack-protector-guard=
> +Target RejectNegative Joined Enum(stack_protector_guard) Var(riscv_stack_protector_guard) Init(SSP_GLOBAL)
> +Use given stack-protector guard.
> +
> +Enum
> +Name(stack_protector_guard) Type(enum stack_protector_guard)
> +Valid arguments to -mstack-protector-guard=:
> +
> +EnumValue
> +Enum(stack_protector_guard) String(tls) Value(SSP_TLS)
> +
> +EnumValue
> +Enum(stack_protector_guard) String(global) Value(SSP_GLOBAL)
> +
> +mstack-protector-guard-reg=
> +Target RejectNegative Joined Var(riscv_stack_protector_guard_reg_str)
> +Use the given base register for addressing the stack-protector guard.
> +
> +TargetVariable
> +int riscv_stack_protector_guard_reg = 0
> +
> +mstack-protector-guard-offset=
> +Target RejectNegative Joined Integer Var(riscv_stack_protector_guard_offset_str)
> +Use the given offset for addressing the stack-protector guard.
> +
> +TargetVariable
> +long riscv_stack_protector_guard_offset = 0
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 09bcc5b0f78..3bb124ae6ed 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -1138,7 +1138,9 @@ See RS/6000 and PowerPC Options.
> -mexplicit-relocs -mno-explicit-relocs @gol
> -mrelax -mno-relax @gol
> -mriscv-attribute -mmo-riscv-attribute @gol
> --malign-data=@var{type}}
> +-malign-data=@var{type} @gol
> ++-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol
> ++-mstack-protector-guard-offset=@var{offset}}
>
> @emph{RL78 Options}
> @gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs @gol
> @@ -25723,6 +25725,24 @@ Control how GCC aligns variables and constants of array, structure, or union
> types. Supported values for @var{type} are @samp{xlen} which uses x register
> width as the alignment value, and @samp{natural} which uses natural alignment.
> @samp{xlen} is the default.
> +
> +@item -mstack-protector-guard=@var{guard}
> +@itemx -mstack-protector-guard-reg=@var{reg}
> +@itemx -mstack-protector-guard-offset=@var{offset}
> +@opindex mstack-protector-guard
> +@opindex mstack-protector-guard-reg
> +@opindex mstack-protector-guard-offset
> +Generate stack protection code using canary at @var{guard}. Supported
> +locations are @samp{global} for a global canary or @samp{tls} for per-thread
> +canary in the TLS block.
> +
> +With the latter choice the options
> +@option{-mstack-protector-guard-reg=@var{reg}} and
> +@option{-mstack-protector-guard-offset=@var{offset}} furthermore specify
> +which register to use as base register for reading the canary,
> +and from what offset from that base register. There is no default
> +register or offset as this is entirely for use within the Linux
> +kernel.
> @end table
>
> @node RL78 Options
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] [RISC-V] Add support for TLS stack protector canary access
2020-07-20 2:03 ` cooper
@ 2020-07-21 8:14 ` Kito Cheng
2020-07-27 22:54 ` Jim Wilson
1 sibling, 0 replies; 7+ messages in thread
From: Kito Cheng @ 2020-07-21 8:14 UTC (permalink / raw)
To: cooper; +Cc: GCC Patches, Jim Wilson, guoren
Hi Cooper:
Could you add testcases like ppc[3-4]?
[3] https://github.com/gcc-mirror/gcc/blob/master/gcc/testsuite/gcc.target/powerpc/ssp-1.c
[4] https://github.com/gcc-mirror/gcc/blob/master/gcc/testsuite/gcc.target/powerpc/ssp-2.c
On Mon, Jul 20, 2020 at 10:04 AM cooper via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Ping
>
> On 2020/7/13 下午4:15, cooper wrote:
> > gcc/
> > * config/riscv/riscv-opts.h (stack_protector_guard): New enum.
> > * config/riscv/riscv.c (riscv_option_override): Handle
> > the new options.
> > * config/riscv/riscv.md (stack_protect_set): New pattern to handle
> > flexible stack protector guard settings.
> > (stack_protect_set_<mode>): Ditto.
> > (stack_protect_test): Ditto.
> > (stack_protect_test_<mode>): Ditto.
> > * config/riscv/riscv.opt (mstack-protector-guard=,
> > mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
> > options.
> > * doc/invoke.texi (Option Summary) [RISC-V Options]:
> > Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
> > -mstack-protector-guard-offset=.
> > (RISC-V Options): Ditto.
> >
> > Signed-off-by: cooper <cooper.qu@linux.alibaba.com>
> > Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> > ---
> > gcc/config/riscv/riscv-opts.h | 6 +++
> > gcc/config/riscv/riscv.c | 47 ++++++++++++++++++++
> > gcc/config/riscv/riscv.md | 80 +++++++++++++++++++++++++++++++++++
> > gcc/config/riscv/riscv.opt | 28 ++++++++++++
> > gcc/doc/invoke.texi | 22 +++++++++-
> > 5 files changed, 182 insertions(+), 1 deletion(-)
> >
> > diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
> > index 8f12e50b9f1..2a3f9d9eef5 100644
> > --- a/gcc/config/riscv/riscv-opts.h
> > +++ b/gcc/config/riscv/riscv-opts.h
> > @@ -51,4 +51,10 @@ enum riscv_align_data {
> > riscv_align_data_type_natural
> > };
> >
> > +/* Where to get the canary for the stack protector. */
> > +enum stack_protector_guard {
> > + SSP_TLS, /* per-thread canary in TLS block */
> > + SSP_GLOBAL /* global canary */
> > +};
> > +
> > #endif /* ! GCC_RISCV_OPTS_H */
> > diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
> > index bfb3885ed08..63b0c3877b0 100644
> > --- a/gcc/config/riscv/riscv.c
> > +++ b/gcc/config/riscv/riscv.c
> > @@ -4775,6 +4775,53 @@ riscv_option_override (void)
> > " [%<-mriscv-attribute%>]");
> > #endif
> >
> > + if (riscv_stack_protector_guard == SSP_GLOBAL
> > + && global_options_set.x_riscv_stack_protector_guard_offset_str)
> > + {
> > + error ("incompatible options %<-mstack-protector-guard=global%> and "
> > + "%<-mstack-protector-guard-offset=%s%>",
> > + riscv_stack_protector_guard_offset_str);
> > + }
> > +
> > + if (riscv_stack_protector_guard == SSP_TLS
> > + && !(global_options_set.x_riscv_stack_protector_guard_offset_str
> > + && global_options_set.x_riscv_stack_protector_guard_reg_str))
> > + {
> > + error ("both %<-mstack-protector-guard-offset%> and "
> > + "%<-mstack-protector-guard-reg%> must be used "
> > + "with %<-mstack-protector-guard=sysreg%>");
> > + }
> > +
> > + if (global_options_set.x_riscv_stack_protector_guard_reg_str)
> > + {
> > + const char *str = riscv_stack_protector_guard_reg_str;
> > + int reg = decode_reg_name (str);
> > +
> > + if (!IN_RANGE (reg, GP_REG_FIRST + 1, GP_REG_LAST))
> > + error ("%qs is not a valid base register in %qs", str,
> > + "-mstack-protector-guard-reg=");
> > +
> > + riscv_stack_protector_guard_reg = reg;
> > + }
> > +
> > + if (global_options_set.x_riscv_stack_protector_guard_offset_str)
> > + {
> > + char *end;
> > + const char *str = riscv_stack_protector_guard_offset_str;
> > + errno = 0;
> > + long offs = strtol (riscv_stack_protector_guard_offset_str, &end, 0);
> > +
> > + if (!*str || *end || errno)
> > + error ("%qs is not a valid number in %qs", str,
> > + "-mstack-protector-guard-offset=");
> > +
> > + if (!SMALL_OPERAND (offs))
> > + error ("%qs is not a valid offset in %qs", str,
> > + "-mstack-protector-guard-offset=");
> > +
> > + riscv_stack_protector_guard_offset = offs;
> > + }
> > +
> > }
> >
> > /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
> > diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
> > index 95a02ecaa34..f15bad3b29e 100644
> > --- a/gcc/config/riscv/riscv.md
> > +++ b/gcc/config/riscv/riscv.md
> > @@ -65,6 +65,10 @@
> > UNSPECV_BLOCKAGE
> > UNSPECV_FENCE
> > UNSPECV_FENCE_I
> > +
> > + ;; Stack Smash Protector
> > + UNSPEC_SSP_SET
> > + UNSPEC_SSP_TEST
> > ])
> >
> > (define_constants
> > @@ -2523,6 +2527,82 @@
> > ""
> > {})
> >
> > +;; Named patterns for stack smashing protection.
> > +
> > +(define_expand "stack_protect_set"
> > + [(match_operand 0 "memory_operand")
> > + (match_operand 1 "memory_operand")]
> > + ""
> > +{
> > + machine_mode mode = GET_MODE (operands[0]);
> > + if (riscv_stack_protector_guard == SSP_TLS)
> > + {
> > + rtx reg = gen_rtx_REG (Pmode, riscv_stack_protector_guard_reg);
> > + rtx offset = GEN_INT (riscv_stack_protector_guard_offset);
> > + rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
> > + operands[1] = gen_rtx_MEM (Pmode, addr);
> > + }
> > +
> > + emit_insn ((mode == DImode
> > + ? gen_stack_protect_set_di
> > + : gen_stack_protect_set_si) (operands[0], operands[1]));
> > + DONE;
> > +})
> > +
> > +;; DO NOT SPLIT THIS PATTERN. It is important for security reasons that the
> > +;; canary value does not live beyond the life of this sequence.
> > +(define_insn "stack_protect_set_<mode>"
> > + [(set (match_operand:GPR 0 "memory_operand" "=m")
> > + (unspec:GPR [(match_operand:GPR 1 "memory_operand" "m")]
> > + UNSPEC_SSP_SET))
> > + (set (match_scratch:GPR 2 "=&r") (const_int 0))]
> > + ""
> > + "<load>\\t%2, %1\;<store>\\t%2, %0\;li\t%2, 0"
> > + [(set_attr "length" "12")])
> > +
> > +(define_expand "stack_protect_test"
> > + [(match_operand 0 "memory_operand")
> > + (match_operand 1 "memory_operand")
> > + (match_operand 2)]
> > + ""
> > +{
> > + rtx result;
> > + machine_mode mode = GET_MODE (operands[0]);
> > +
> > + result = gen_reg_rtx(mode);
> > + if (riscv_stack_protector_guard == SSP_TLS)
> > + {
> > + rtx reg = gen_rtx_REG (Pmode, riscv_stack_protector_guard_reg);
> > + rtx offset = GEN_INT (riscv_stack_protector_guard_offset);
> > + rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
> > + operands[1] = gen_rtx_MEM (Pmode, addr);
> > + }
> > + emit_insn ((mode == DImode
> > + ? gen_stack_protect_test_di
> > + : gen_stack_protect_test_si) (result,
> > + operands[0],
> > + operands[1]));
> > +
> > + if (mode == DImode)
> > + emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
> > + result, const0_rtx, operands[2]));
> > + else
> > + emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
> > + result, const0_rtx, operands[2]));
> > +
> > + DONE;
> > +})
> > +
> > +(define_insn "stack_protect_test_<mode>"
> > + [(set (match_operand:GPR 0 "register_operand" "=r")
> > + (unspec:GPR [(match_operand:GPR 1 "memory_operand" "m")
> > + (match_operand:GPR 2 "memory_operand" "m")]
> > + UNSPEC_SSP_TEST))
> > + (clobber (match_scratch:GPR 3 "=&r"))]
> > + ""
> > + "<load>\t%3, %1\;<load>\t%0, %2\;xor\t%0, %3, %0\;li\t%3, 0"
> > + [(set_attr "length" "12")])
> > +
> > (include "sync.md")
> > (include "peephole.md")
> > (include "pic.md")
> > diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
> > index e4bfcb86f51..f01d3ab79c3 100644
> > --- a/gcc/config/riscv/riscv.opt
> > +++ b/gcc/config/riscv/riscv.opt
> > @@ -151,3 +151,31 @@ Enum(riscv_align_data) String(xlen) Value(riscv_align_data_type_xlen)
> >
> > EnumValue
> > Enum(riscv_align_data) String(natural) Value(riscv_align_data_type_natural)
> > +
> > +mstack-protector-guard=
> > +Target RejectNegative Joined Enum(stack_protector_guard) Var(riscv_stack_protector_guard) Init(SSP_GLOBAL)
> > +Use given stack-protector guard.
> > +
> > +Enum
> > +Name(stack_protector_guard) Type(enum stack_protector_guard)
> > +Valid arguments to -mstack-protector-guard=:
> > +
> > +EnumValue
> > +Enum(stack_protector_guard) String(tls) Value(SSP_TLS)
> > +
> > +EnumValue
> > +Enum(stack_protector_guard) String(global) Value(SSP_GLOBAL)
> > +
> > +mstack-protector-guard-reg=
> > +Target RejectNegative Joined Var(riscv_stack_protector_guard_reg_str)
> > +Use the given base register for addressing the stack-protector guard.
> > +
> > +TargetVariable
> > +int riscv_stack_protector_guard_reg = 0
> > +
> > +mstack-protector-guard-offset=
> > +Target RejectNegative Joined Integer Var(riscv_stack_protector_guard_offset_str)
> > +Use the given offset for addressing the stack-protector guard.
> > +
> > +TargetVariable
> > +long riscv_stack_protector_guard_offset = 0
> > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> > index 09bcc5b0f78..3bb124ae6ed 100644
> > --- a/gcc/doc/invoke.texi
> > +++ b/gcc/doc/invoke.texi
> > @@ -1138,7 +1138,9 @@ See RS/6000 and PowerPC Options.
> > -mexplicit-relocs -mno-explicit-relocs @gol
> > -mrelax -mno-relax @gol
> > -mriscv-attribute -mmo-riscv-attribute @gol
> > --malign-data=@var{type}}
> > +-malign-data=@var{type} @gol
> > ++-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol
> > ++-mstack-protector-guard-offset=@var{offset}}
> >
> > @emph{RL78 Options}
> > @gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs @gol
> > @@ -25723,6 +25725,24 @@ Control how GCC aligns variables and constants of array, structure, or union
> > types. Supported values for @var{type} are @samp{xlen} which uses x register
> > width as the alignment value, and @samp{natural} which uses natural alignment.
> > @samp{xlen} is the default.
> > +
> > +@item -mstack-protector-guard=@var{guard}
> > +@itemx -mstack-protector-guard-reg=@var{reg}
> > +@itemx -mstack-protector-guard-offset=@var{offset}
> > +@opindex mstack-protector-guard
> > +@opindex mstack-protector-guard-reg
> > +@opindex mstack-protector-guard-offset
> > +Generate stack protection code using canary at @var{guard}. Supported
> > +locations are @samp{global} for a global canary or @samp{tls} for per-thread
> > +canary in the TLS block.
> > +
> > +With the latter choice the options
> > +@option{-mstack-protector-guard-reg=@var{reg}} and
> > +@option{-mstack-protector-guard-offset=@var{offset}} furthermore specify
> > +which register to use as base register for reading the canary,
> > +and from what offset from that base register. There is no default
> > +register or offset as this is entirely for use within the Linux
> > +kernel.
> > @end table
> >
> > @node RL78 Options
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] [RISC-V] Add support for TLS stack protector canary access
2020-07-20 2:03 ` cooper
2020-07-21 8:14 ` Kito Cheng
@ 2020-07-27 22:54 ` Jim Wilson
2020-07-28 1:23 ` Kito Cheng
1 sibling, 1 reply; 7+ messages in thread
From: Jim Wilson @ 2020-07-27 22:54 UTC (permalink / raw)
To: cooper, Kito Cheng; +Cc: GCC Patches, guoren
On Sun, Jul 19, 2020 at 7:04 PM cooper <cooper.qu@linux.alibaba.com> wrote:
> Ping
>
> On 2020/7/13 下午4:15, cooper wrote:
> > gcc/
> > * config/riscv/riscv-opts.h (stack_protector_guard): New enum.
> > * config/riscv/riscv.c (riscv_option_override): Handle
> > the new options.
> > * config/riscv/riscv.md (stack_protect_set): New pattern to handle
> > flexible stack protector guard settings.
> > (stack_protect_set_<mode>): Ditto.
> > (stack_protect_test): Ditto.
> > (stack_protect_test_<mode>): Ditto.
> > * config/riscv/riscv.opt (mstack-protector-guard=,
> > mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
> > options.
> > * doc/invoke.texi (Option Summary) [RISC-V Options]:
> > Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
> > -mstack-protector-guard-offset=.
> > (RISC-V Options): Ditto.
The v2 patch looks fine to me. Meanwhile, Kito asked for testcases
which would be nice to have but I don't think is critical considering
that this has already been tested with a kernel build. Maybe the
testcases can be a follow on patch? I'd like to see forward movement
on this, even if we accept a patch without the testcases.
Jim
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] [RISC-V] Add support for TLS stack protector canary access
2020-07-27 22:54 ` Jim Wilson
@ 2020-07-28 1:23 ` Kito Cheng
2020-07-29 12:34 ` Cooper Qu
0 siblings, 1 reply; 7+ messages in thread
From: Kito Cheng @ 2020-07-28 1:23 UTC (permalink / raw)
To: Jim Wilson; +Cc: cooper, guoren, GCC Patches
Add testcase later is OK to me.
On Tue, Jul 28, 2020 at 6:55 AM Jim Wilson <jimw@sifive.com> wrote:
>
> On Sun, Jul 19, 2020 at 7:04 PM cooper <cooper.qu@linux.alibaba.com> wrote:
> > Ping
> >
> > On 2020/7/13 下午4:15, cooper wrote:
> > > gcc/
> > > * config/riscv/riscv-opts.h (stack_protector_guard): New enum.
> > > * config/riscv/riscv.c (riscv_option_override): Handle
> > > the new options.
> > > * config/riscv/riscv.md (stack_protect_set): New pattern to handle
> > > flexible stack protector guard settings.
> > > (stack_protect_set_<mode>): Ditto.
> > > (stack_protect_test): Ditto.
> > > (stack_protect_test_<mode>): Ditto.
> > > * config/riscv/riscv.opt (mstack-protector-guard=,
> > > mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
> > > options.
> > > * doc/invoke.texi (Option Summary) [RISC-V Options]:
> > > Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
> > > -mstack-protector-guard-offset=.
> > > (RISC-V Options): Ditto.
>
> The v2 patch looks fine to me. Meanwhile, Kito asked for testcases
> which would be nice to have but I don't think is critical considering
> that this has already been tested with a kernel build. Maybe the
> testcases can be a follow on patch? I'd like to see forward movement
> on this, even if we accept a patch without the testcases.
>
> Jim
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] [RISC-V] Add support for TLS stack protector canary access
2020-07-28 1:23 ` Kito Cheng
@ 2020-07-29 12:34 ` Cooper Qu
2020-07-30 16:40 ` Kito Cheng
0 siblings, 1 reply; 7+ messages in thread
From: Cooper Qu @ 2020-07-29 12:34 UTC (permalink / raw)
To: Kito Cheng, Jim Wilson; +Cc: guoren, GCC Patches
Sorry for later replay, I will add testcases on a following patch if the
patch is accepted.
Regards,
Cooper
On 2020/7/28 上午9:23, Kito Cheng wrote:
> Add testcase later is OK to me.
>
> On Tue, Jul 28, 2020 at 6:55 AM Jim Wilson <jimw@sifive.com> wrote:
>> On Sun, Jul 19, 2020 at 7:04 PM cooper <cooper.qu@linux.alibaba.com> wrote:
>>> Ping
>>>
>>> On 2020/7/13 下午4:15, cooper wrote:
>>>> gcc/
>>>> * config/riscv/riscv-opts.h (stack_protector_guard): New enum.
>>>> * config/riscv/riscv.c (riscv_option_override): Handle
>>>> the new options.
>>>> * config/riscv/riscv.md (stack_protect_set): New pattern to handle
>>>> flexible stack protector guard settings.
>>>> (stack_protect_set_<mode>): Ditto.
>>>> (stack_protect_test): Ditto.
>>>> (stack_protect_test_<mode>): Ditto.
>>>> * config/riscv/riscv.opt (mstack-protector-guard=,
>>>> mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
>>>> options.
>>>> * doc/invoke.texi (Option Summary) [RISC-V Options]:
>>>> Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
>>>> -mstack-protector-guard-offset=.
>>>> (RISC-V Options): Ditto.
>> The v2 patch looks fine to me. Meanwhile, Kito asked for testcases
>> which would be nice to have but I don't think is critical considering
>> that this has already been tested with a kernel build. Maybe the
>> testcases can be a follow on patch? I'd like to see forward movement
>> on this, even if we accept a patch without the testcases.
>>
>> Jim
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] [RISC-V] Add support for TLS stack protector canary access
2020-07-29 12:34 ` Cooper Qu
@ 2020-07-30 16:40 ` Kito Cheng
0 siblings, 0 replies; 7+ messages in thread
From: Kito Cheng @ 2020-07-30 16:40 UTC (permalink / raw)
To: Cooper Qu; +Cc: Jim Wilson, guoren, GCC Patches
Hi Cooper:
Thanks for your patch! committed to trunk.
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=c931e8d5a96463427040b0d11f9c4352ac22b2b0
On Wed, Jul 29, 2020 at 8:34 PM Cooper Qu via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Sorry for later replay, I will add testcases on a following patch if the
> patch is accepted.
>
>
> Regards,
>
> Cooper
>
> On 2020/7/28 上午9:23, Kito Cheng wrote:
> > Add testcase later is OK to me.
> >
> > On Tue, Jul 28, 2020 at 6:55 AM Jim Wilson <jimw@sifive.com> wrote:
> >> On Sun, Jul 19, 2020 at 7:04 PM cooper <cooper.qu@linux.alibaba.com> wrote:
> >>> Ping
> >>>
> >>> On 2020/7/13 下午4:15, cooper wrote:
> >>>> gcc/
> >>>> * config/riscv/riscv-opts.h (stack_protector_guard): New enum.
> >>>> * config/riscv/riscv.c (riscv_option_override): Handle
> >>>> the new options.
> >>>> * config/riscv/riscv.md (stack_protect_set): New pattern to handle
> >>>> flexible stack protector guard settings.
> >>>> (stack_protect_set_<mode>): Ditto.
> >>>> (stack_protect_test): Ditto.
> >>>> (stack_protect_test_<mode>): Ditto.
> >>>> * config/riscv/riscv.opt (mstack-protector-guard=,
> >>>> mstack-protector-guard-reg=, mstack-protector-guard-offset=): New
> >>>> options.
> >>>> * doc/invoke.texi (Option Summary) [RISC-V Options]:
> >>>> Add -mstack-protector-guard=, -mstack-protector-guard-reg=, and
> >>>> -mstack-protector-guard-offset=.
> >>>> (RISC-V Options): Ditto.
> >> The v2 patch looks fine to me. Meanwhile, Kito asked for testcases
> >> which would be nice to have but I don't think is critical considering
> >> that this has already been tested with a kernel build. Maybe the
> >> testcases can be a follow on patch? I'd like to see forward movement
> >> on this, even if we accept a patch without the testcases.
> >>
> >> Jim
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-07-30 16:41 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-13 8:15 [PATCH v2] [RISC-V] Add support for TLS stack protector canary access cooper
2020-07-20 2:03 ` cooper
2020-07-21 8:14 ` Kito Cheng
2020-07-27 22:54 ` Jim Wilson
2020-07-28 1:23 ` Kito Cheng
2020-07-29 12:34 ` Cooper Qu
2020-07-30 16:40 ` Kito Cheng
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).