diff options
Diffstat (limited to 'system/musl/dcngettext-null-deref.patch')
-rw-r--r-- | system/musl/dcngettext-null-deref.patch | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/system/musl/dcngettext-null-deref.patch b/system/musl/dcngettext-null-deref.patch new file mode 100644 index 000000000..bcc385e86 --- /dev/null +++ b/system/musl/dcngettext-null-deref.patch @@ -0,0 +1,82 @@ +From 017e67ddde79fa2b6187a5e56b1e92bafc7c4cd2 Mon Sep 17 00:00:00 2001 +From: Rich Felker <dalias@aerifal.cx> +Date: Fri, 14 Sep 2018 13:00:41 -0400 +Subject: drop lazy plural forms init in dcngettext + +there is no good reason to wait to find and process the plural rules +for a translated message file until a gettext form requesting plural +rule processing is used. it just imposes additional synchronization, +here in the form of clunky use of atomics. + +it looks like there may also have been a race condition where nplurals +could be seen without plural_rule being seen, possibly leading to null +pointer dereference. if so, this commit fixes it. +--- + src/locale/dcngettext.c | 35 +++++++++++++++++------------------ + 1 file changed, 17 insertions(+), 18 deletions(-) + +diff --git a/src/locale/dcngettext.c b/src/locale/dcngettext.c +index 7fbe7196..8b891d00 100644 +--- a/src/locale/dcngettext.c ++++ b/src/locale/dcngettext.c +@@ -100,8 +100,8 @@ struct msgcat { + struct msgcat *next; + const void *map; + size_t map_size; +- void *volatile plural_rule; +- volatile int nplurals; ++ const char *plural_rule; ++ int nplurals; + struct binding *binding; + const struct __locale_map *lm; + int cat; +@@ -200,20 +200,7 @@ notrans: + p->lm = lm; + p->map = map; + p->map_size = map_size; +- do { +- old_cats = cats; +- p->next = old_cats; +- } while (a_cas_p(&cats, old_cats, p) != old_cats); +- } +- +- const char *trans = __mo_lookup(p->map, p->map_size, msgid1); +- if (!trans) goto notrans; +- +- /* Non-plural-processing gettext forms pass a null pointer as +- * msgid2 to request that dcngettext suppress plural processing. */ +- if (!msgid2) return (char *)trans; + +- if (!p->plural_rule) { + const char *rule = "n!=1;"; + unsigned long np = 2; + const char *r = __mo_lookup(p->map, p->map_size, ""); +@@ -237,10 +224,22 @@ notrans: + rule = r+7; + } + } +- a_store(&p->nplurals, np); +- a_cas_p(&p->plural_rule, 0, (void *)rule); ++ p->nplurals = np; ++ p->plural_rule = rule; ++ ++ do { ++ old_cats = cats; ++ p->next = old_cats; ++ } while (a_cas_p(&cats, old_cats, p) != old_cats); + } +- if (p->nplurals) { ++ ++ const char *trans = __mo_lookup(p->map, p->map_size, msgid1); ++ if (!trans) goto notrans; ++ ++ /* Non-plural-processing gettext forms pass a null pointer as ++ * msgid2 to request that dcngettext suppress plural processing. */ ++ ++ if (msgid2 && p->nplurals) { + unsigned long plural = __pleval(p->plural_rule, n); + if (plural > p->nplurals) goto notrans; + while (plural--) { +-- +cgit v1.2.1 + |