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

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

diff --git a/queue-4.19/ipvs-fix-racy-memcpy-in-proc_do_sync_threshold.patch b/queue-4.19/ipvs-fix-racy-memcpy-in-proc_do_sync_threshold.patch
new file mode 100644 (file)
index 0000000..8852782
--- /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
+@@ -1690,6 +1690,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;
+@@ -1699,6 +1700,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) {
+@@ -1708,6 +1710,7 @@ proc_do_sync_threshold(struct ctl_table
+               else
+                       memcpy(valp, val, sizeof(val));
+       }
++      mutex_unlock(&ipvs->sync_mutex);
+       return rc;
+ }
+@@ -3944,6 +3947,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.19/ipvs-improve-robustness-to-the-ipvs-sysctl.patch b/queue-4.19/ipvs-improve-robustness-to-the-ipvs-sysctl.patch
new file mode 100644 (file)
index 0000000..faa01ba
--- /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
+@@ -1656,6 +1656,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
+@@ -1667,12 +1668,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);
+               }
+       }
+@@ -1686,33 +1693,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;
+ }
+@@ -1725,12 +1719,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;
+ }
+@@ -1790,7 +1790,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 d9c3e8016251cbb455d996fc47d9277350a91035..4153df30cfc8062e604d09990fbf987abb8270f0 100644 (file)
@@ -116,3 +116,5 @@ igb-avoid-starting-unnecessary-workqueues.patch
 net-sched-fix-a-qdisc-modification-with-ambiguous-co.patch
 net-remove-bond_slave_has_mac_rcu.patch
 bonding-fix-macvlan-over-alb-bond-support.patch
+ipvs-improve-robustness-to-the-ipvs-sysctl.patch
+ipvs-fix-racy-memcpy-in-proc_do_sync_threshold.patch