summaryrefslogtreecommitdiff
path: root/system/musl/dcngettext-null-deref.patch
diff options
context:
space:
mode:
Diffstat (limited to 'system/musl/dcngettext-null-deref.patch')
-rw-r--r--system/musl/dcngettext-null-deref.patch82
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
+