]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 26 Aug 2023 16:19:59 +0000 (18:19 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 26 Aug 2023 16:19:59 +0000 (18:19 +0200)
added patches:
ipvs-fix-racy-memcpy-in-proc_do_sync_threshold.patch
ipvs-improve-robustness-to-the-ipvs-sysctl.patch

queue-4.14/ipvs-fix-racy-memcpy-in-proc_do_sync_threshold.patch [new file with mode: 0644]
queue-4.14/ipvs-improve-robustness-to-the-ipvs-sysctl.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/ipvs-fix-racy-memcpy-in-proc_do_sync_threshold.patch b/queue-4.14/ipvs-fix-racy-memcpy-in-proc_do_sync_threshold.patch
new file mode 100644 (file)
index 0000000..2b32697
--- /dev/null
@@ -0,0 +1,64 @@
+From 5310760af1d4fbea1452bfc77db5f9a680f7ae47 Mon Sep 17 00:00:00 2001
+From: Sishuai Gong <sishuai.system@gmail.com>
+Date: Thu, 10 Aug 2023 15:12:42 -0400
+Subject: ipvs: fix racy memcpy in proc_do_sync_threshold
+
+From: Sishuai Gong <sishuai.system@gmail.com>
+
+commit 5310760af1d4fbea1452bfc77db5f9a680f7ae47 upstream.
+
+When two threads run proc_do_sync_threshold() in parallel,
+data races could happen between the two memcpy():
+
+Thread-1                       Thread-2
+memcpy(val, valp, sizeof(val));
+                               memcpy(valp, val, sizeof(val));
+
+This race might mess up the (struct ctl_table *) table->data,
+so we add a mutex lock to serialize them.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Link: https://lore.kernel.org/netdev/B6988E90-0A1E-4B85-BF26-2DAF6D482433@gmail.com/
+Signed-off-by: Sishuai Gong <sishuai.system@gmail.com>
+Acked-by: Simon Horman <horms@kernel.org>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/ipvs/ip_vs_ctl.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/netfilter/ipvs/ip_vs_ctl.c
++++ b/net/netfilter/ipvs/ip_vs_ctl.c
+@@ -1682,6 +1682,7 @@ static int
+ proc_do_sync_threshold(struct ctl_table *table, int write,
+                      void __user *buffer, size_t *lenp, loff_t *ppos)
+ {
++      struct netns_ipvs *ipvs = table->extra2;
+       int *valp = table->data;
+       int val[2];
+       int rc;
+@@ -1691,6 +1692,7 @@ proc_do_sync_threshold(struct ctl_table
+               .mode = table->mode,
+       };
++      mutex_lock(&ipvs->sync_mutex);
+       memcpy(val, valp, sizeof(val));
+       rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
+       if (write) {
+@@ -1700,6 +1702,7 @@ proc_do_sync_threshold(struct ctl_table
+               else
+                       memcpy(valp, val, sizeof(val));
+       }
++      mutex_unlock(&ipvs->sync_mutex);
+       return rc;
+ }
+@@ -3976,6 +3979,7 @@ static int __net_init ip_vs_control_net_
+       ipvs->sysctl_sync_threshold[0] = DEFAULT_SYNC_THRESHOLD;
+       ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD;
+       tbl[idx].data = &ipvs->sysctl_sync_threshold;
++      tbl[idx].extra2 = ipvs;
+       tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold);
+       ipvs->sysctl_sync_refresh_period = DEFAULT_SYNC_REFRESH_PERIOD;
+       tbl[idx++].data = &ipvs->sysctl_sync_refresh_period;
diff --git a/queue-4.14/ipvs-improve-robustness-to-the-ipvs-sysctl.patch b/queue-4.14/ipvs-improve-robustness-to-the-ipvs-sysctl.patch
new file mode 100644 (file)
index 0000000..ae85330
--- /dev/null
@@ -0,0 +1,141 @@
+From 1b90af292e71b20d03b837d39406acfbdc5d4b2a Mon Sep 17 00:00:00 2001
+From: Junwei Hu <hujunwei4@huawei.com>
+Date: Thu, 1 Aug 2019 00:03:30 +0800
+Subject: ipvs: Improve robustness to the ipvs sysctl
+
+From: Junwei Hu <hujunwei4@huawei.com>
+
+commit 1b90af292e71b20d03b837d39406acfbdc5d4b2a upstream.
+
+The ipvs module parse the user buffer and save it to sysctl,
+then check if the value is valid. invalid value occurs
+over a period of time.
+Here, I add a variable, struct ctl_table tmp, used to read
+the value from the user buffer, and save only when it is valid.
+I delete proc_do_sync_mode and use extra1/2 in table for the
+proc_dointvec_minmax call.
+
+Fixes: f73181c8288f ("ipvs: add support for sync threads")
+Signed-off-by: Junwei Hu <hujunwei4@huawei.com>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+[Julian: Backport by changing SYSCTL_ZERO/SYSCTL_ONE to zero/one]
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/ipvs/ip_vs_ctl.c |   70 +++++++++++++++++++++--------------------
+ 1 file changed, 36 insertions(+), 34 deletions(-)
+
+--- a/net/netfilter/ipvs/ip_vs_ctl.c
++++ b/net/netfilter/ipvs/ip_vs_ctl.c
+@@ -1648,6 +1648,7 @@ static int ip_vs_zero_all(struct netns_i
+ #ifdef CONFIG_SYSCTL
+ static int zero;
++static int one = 1;
+ static int three = 3;
+ static int
+@@ -1659,12 +1660,18 @@ proc_do_defense_mode(struct ctl_table *t
+       int val = *valp;
+       int rc;
+-      rc = proc_dointvec(table, write, buffer, lenp, ppos);
++      struct ctl_table tmp = {
++              .data = &val,
++              .maxlen = sizeof(int),
++              .mode = table->mode,
++      };
++
++      rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
+       if (write && (*valp != val)) {
+-              if ((*valp < 0) || (*valp > 3)) {
+-                      /* Restore the correct value */
+-                      *valp = val;
++              if (val < 0 || val > 3) {
++                      rc = -EINVAL;
+               } else {
++                      *valp = val;
+                       update_defense_level(ipvs);
+               }
+       }
+@@ -1678,33 +1685,20 @@ proc_do_sync_threshold(struct ctl_table
+       int *valp = table->data;
+       int val[2];
+       int rc;
++      struct ctl_table tmp = {
++              .data = &val,
++              .maxlen = table->maxlen,
++              .mode = table->mode,
++      };
+-      /* backup the value first */
+       memcpy(val, valp, sizeof(val));
+-
+-      rc = proc_dointvec(table, write, buffer, lenp, ppos);
+-      if (write && (valp[0] < 0 || valp[1] < 0 ||
+-          (valp[0] >= valp[1] && valp[1]))) {
+-              /* Restore the correct value */
+-              memcpy(valp, val, sizeof(val));
+-      }
+-      return rc;
+-}
+-
+-static int
+-proc_do_sync_mode(struct ctl_table *table, int write,
+-                   void __user *buffer, size_t *lenp, loff_t *ppos)
+-{
+-      int *valp = table->data;
+-      int val = *valp;
+-      int rc;
+-
+-      rc = proc_dointvec(table, write, buffer, lenp, ppos);
+-      if (write && (*valp != val)) {
+-              if ((*valp < 0) || (*valp > 1)) {
+-                      /* Restore the correct value */
+-                      *valp = val;
+-              }
++      rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
++      if (write) {
++              if (val[0] < 0 || val[1] < 0 ||
++                  (val[0] >= val[1] && val[1]))
++                      rc = -EINVAL;
++              else
++                      memcpy(valp, val, sizeof(val));
+       }
+       return rc;
+ }
+@@ -1717,12 +1711,18 @@ proc_do_sync_ports(struct ctl_table *tab
+       int val = *valp;
+       int rc;
+-      rc = proc_dointvec(table, write, buffer, lenp, ppos);
++      struct ctl_table tmp = {
++              .data = &val,
++              .maxlen = sizeof(int),
++              .mode = table->mode,
++      };
++
++      rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
+       if (write && (*valp != val)) {
+-              if (*valp < 1 || !is_power_of_2(*valp)) {
+-                      /* Restore the correct value */
++              if (val < 1 || !is_power_of_2(val))
++                      rc = -EINVAL;
++              else
+                       *valp = val;
+-              }
+       }
+       return rc;
+ }
+@@ -1782,7 +1782,9 @@ static struct ctl_table vs_vars[] = {
+               .procname       = "sync_version",
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+-              .proc_handler   = proc_do_sync_mode,
++              .proc_handler   = proc_dointvec_minmax,
++              .extra1         = &zero,
++              .extra2         = &one,
+       },
+       {
+               .procname       = "sync_ports",
index 7931e178510687d53cacd522a90f26c1a7c26bc3..c61bb91eeb910060b15d0ec071f61becdb8337ac 100644 (file)
@@ -41,3 +41,5 @@ net-phy-broadcom-stub-c45-read-write-for-54810.patch
 tracing-fix-memleak-due-to-race-between-current_trac.patch
 sock-annotate-data-races-around-prot-memory_pressure.patch
 igb-avoid-starting-unnecessary-workqueues.patch
+ipvs-improve-robustness-to-the-ipvs-sysctl.patch
+ipvs-fix-racy-memcpy-in-proc_do_sync_threshold.patch