|
|
44c692 |
From af92b565250adce354d1af936c0013d0175a5b81 Mon Sep 17 00:00:00 2001
|
|
|
44c692 |
From: Jitka Plesnikova <jplesnik@redhat.com>
|
|
|
44c692 |
Date: Mon, 1 Jun 2020 18:33:56 +0200
|
|
|
44c692 |
Subject: [PATCH 4/4] study_chunk: extract rck_elide_nothing
|
|
|
44c692 |
|
|
|
44c692 |
(CVE-2020-10878)
|
|
|
44c692 |
---
|
|
|
44c692 |
embed.fnc | 1 +
|
|
|
44c692 |
embed.h | 1 +
|
|
|
44c692 |
proto.h | 4 ++++
|
|
|
44c692 |
regcomp.c | 70 ++++++++++++++++++++++++++++++++++---------------------
|
|
|
44c692 |
4 files changed, 49 insertions(+), 27 deletions(-)
|
|
|
44c692 |
|
|
|
44c692 |
diff --git a/embed.fnc b/embed.fnc
|
|
|
44c692 |
index 9546555..aa6c886 100644
|
|
|
44c692 |
--- a/embed.fnc
|
|
|
44c692 |
+++ b/embed.fnc
|
|
|
44c692 |
@@ -1952,6 +1952,7 @@ Es |I32 |study_chunk |NN struct RExC_state_t *pRExC_state \
|
|
|
44c692 |
|I32 stopparen|NULLOK U8* recursed \
|
|
|
44c692 |
|NULLOK struct regnode_charclass_class *and_withp \
|
|
|
44c692 |
|U32 flags|U32 depth|bool was_mutate_ok
|
|
|
44c692 |
+Es |void |rck_elide_nothing|NN regnode *node
|
|
|
44c692 |
EsRn |U32 |add_data |NN struct RExC_state_t *pRExC_state|U32 n \
|
|
|
44c692 |
|NN const char *s
|
|
|
44c692 |
rs |void |re_croak2 |NN const char* pat1|NN const char* pat2|...
|
|
|
44c692 |
diff --git a/embed.h b/embed.h
|
|
|
44c692 |
index f7db1e0..555538d 100644
|
|
|
44c692 |
--- a/embed.h
|
|
|
44c692 |
+++ b/embed.h
|
|
|
44c692 |
@@ -933,6 +933,7 @@
|
|
|
44c692 |
#define make_trie(a,b,c,d,e,f,g,h) S_make_trie(aTHX_ a,b,c,d,e,f,g,h)
|
|
|
44c692 |
#define make_trie_failtable(a,b,c,d) S_make_trie_failtable(aTHX_ a,b,c,d)
|
|
|
44c692 |
#define nextchar(a) S_nextchar(aTHX_ a)
|
|
|
44c692 |
+#define rck_elide_nothing(a) S_rck_elide_nothing(aTHX_ a)
|
|
|
44c692 |
#define reg(a,b,c,d) S_reg(aTHX_ a,b,c,d)
|
|
|
44c692 |
#define reg_namedseq(a,b,c,d) S_reg_namedseq(aTHX_ a,b,c,d)
|
|
|
44c692 |
#define reg_node(a,b) S_reg_node(aTHX_ a,b)
|
|
|
44c692 |
diff --git a/proto.h b/proto.h
|
|
|
44c692 |
index 143eee0..d7cba26 100644
|
|
|
44c692 |
--- a/proto.h
|
|
|
44c692 |
+++ b/proto.h
|
|
|
44c692 |
@@ -6477,6 +6477,10 @@ STATIC char * S_nextchar(pTHX_ struct RExC_state_t *pRExC_state)
|
|
|
44c692 |
#define PERL_ARGS_ASSERT_NEXTCHAR \
|
|
|
44c692 |
assert(pRExC_state)
|
|
|
44c692 |
|
|
|
44c692 |
+STATIC void S_rck_elide_nothing(pTHX_ regnode *node);
|
|
|
44c692 |
+#define PERL_ARGS_ASSERT_RCK_ELIDE_NOTHING \
|
|
|
44c692 |
+ assert(node)
|
|
|
44c692 |
+
|
|
|
44c692 |
STATIC void S_re_croak2(pTHX_ const char* pat1, const char* pat2, ...)
|
|
|
44c692 |
__attribute__noreturn__
|
|
|
44c692 |
__attribute__nonnull__(pTHX_1)
|
|
|
44c692 |
diff --git a/regcomp.c b/regcomp.c
|
|
|
44c692 |
index 9842a83..aa96980 100644
|
|
|
44c692 |
--- a/regcomp.c
|
|
|
44c692 |
+++ b/regcomp.c
|
|
|
44c692 |
@@ -2967,6 +2967,43 @@ case N ## nAmE: \
|
|
|
44c692 |
break
|
|
|
44c692 |
|
|
|
44c692 |
|
|
|
44c692 |
+/* Follow the next-chain of the current node and optimize away
|
|
|
44c692 |
+ all the NOTHINGs from it.
|
|
|
44c692 |
+ */
|
|
|
44c692 |
+STATIC void
|
|
|
44c692 |
+S_rck_elide_nothing(pTHX_ regnode *node)
|
|
|
44c692 |
+{
|
|
|
44c692 |
+ dVAR;
|
|
|
44c692 |
+
|
|
|
44c692 |
+ PERL_ARGS_ASSERT_RCK_ELIDE_NOTHING;
|
|
|
44c692 |
+
|
|
|
44c692 |
+ if (OP(node) != CURLYX) {
|
|
|
44c692 |
+ const int max = (reg_off_by_arg[OP(node)]
|
|
|
44c692 |
+ ? I32_MAX
|
|
|
44c692 |
+ /* I32 may be smaller than U16 on CRAYs! */
|
|
|
44c692 |
+ : (I32_MAX < U16_MAX ? I32_MAX : U16_MAX));
|
|
|
44c692 |
+ int off = (reg_off_by_arg[OP(node)] ? ARG(node) : NEXT_OFF(node));
|
|
|
44c692 |
+ int noff;
|
|
|
44c692 |
+ regnode *n = node;
|
|
|
44c692 |
+
|
|
|
44c692 |
+ /* Skip NOTHING and LONGJMP. */
|
|
|
44c692 |
+ while (
|
|
|
44c692 |
+ (n = regnext(n))
|
|
|
44c692 |
+ && (
|
|
|
44c692 |
+ (PL_regkind[OP(n)] == NOTHING && (noff = NEXT_OFF(n)))
|
|
|
44c692 |
+ || ((OP(n) == LONGJMP) && (noff = ARG(n)))
|
|
|
44c692 |
+ )
|
|
|
44c692 |
+ && off + noff < max
|
|
|
44c692 |
+ ) {
|
|
|
44c692 |
+ off += noff;
|
|
|
44c692 |
+ }
|
|
|
44c692 |
+ if (reg_off_by_arg[OP(node)])
|
|
|
44c692 |
+ ARG(node) = off;
|
|
|
44c692 |
+ else
|
|
|
44c692 |
+ NEXT_OFF(node) = off;
|
|
|
44c692 |
+ }
|
|
|
44c692 |
+ return;
|
|
|
44c692 |
+}
|
|
|
44c692 |
|
|
|
44c692 |
STATIC I32
|
|
|
44c692 |
S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
|
|
|
44c692 |
@@ -3034,27 +3071,9 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
|
|
|
44c692 |
|
|
|
44c692 |
|
|
|
44c692 |
/* Follow the next-chain of the current node and optimize
|
|
|
44c692 |
- away all the NOTHINGs from it. */
|
|
|
44c692 |
- if (OP(scan) != CURLYX) {
|
|
|
44c692 |
- const int max = (reg_off_by_arg[OP(scan)]
|
|
|
44c692 |
- ? I32_MAX
|
|
|
44c692 |
- /* I32 may be smaller than U16 on CRAYs! */
|
|
|
44c692 |
- : (I32_MAX < U16_MAX ? I32_MAX : U16_MAX));
|
|
|
44c692 |
- int off = (reg_off_by_arg[OP(scan)] ? ARG(scan) : NEXT_OFF(scan));
|
|
|
44c692 |
- int noff;
|
|
|
44c692 |
- regnode *n = scan;
|
|
|
44c692 |
-
|
|
|
44c692 |
- /* Skip NOTHING and LONGJMP. */
|
|
|
44c692 |
- while ((n = regnext(n))
|
|
|
44c692 |
- && ((PL_regkind[OP(n)] == NOTHING && (noff = NEXT_OFF(n)))
|
|
|
44c692 |
- || ((OP(n) == LONGJMP) && (noff = ARG(n))))
|
|
|
44c692 |
- && off + noff < max)
|
|
|
44c692 |
- off += noff;
|
|
|
44c692 |
- if (reg_off_by_arg[OP(scan)])
|
|
|
44c692 |
- ARG(scan) = off;
|
|
|
44c692 |
- else
|
|
|
44c692 |
- NEXT_OFF(scan) = off;
|
|
|
44c692 |
- }
|
|
|
44c692 |
+ away all the NOTHINGs from it.
|
|
|
44c692 |
+ */
|
|
|
44c692 |
+ rck_elide_nothing(scan);
|
|
|
44c692 |
|
|
|
44c692 |
|
|
|
44c692 |
|
|
|
44c692 |
@@ -4057,11 +4094,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
|
|
|
44c692 |
if (data && (fl & SF_HAS_EVAL))
|
|
|
44c692 |
data->flags |= SF_HAS_EVAL;
|
|
|
44c692 |
optimize_curly_tail:
|
|
|
44c692 |
- if (OP(oscan) != CURLYX) {
|
|
|
44c692 |
- while (PL_regkind[OP(next = regnext(oscan))] == NOTHING
|
|
|
44c692 |
- && NEXT_OFF(next))
|
|
|
44c692 |
- NEXT_OFF(oscan) += NEXT_OFF(next);
|
|
|
44c692 |
- }
|
|
|
44c692 |
+ rck_elide_nothing(oscan);
|
|
|
44c692 |
continue;
|
|
|
44c692 |
default: /* REF, ANYOFV, and CLUMP only? */
|
|
|
44c692 |
if (flags & SCF_DO_SUBSTR) {
|
|
|
44c692 |
--
|
|
|
44c692 |
2.25.4
|
|
|
44c692 |
|