]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Sun, 23 Feb 2025 17:23:16 +0000 (12:23 -0500)
committerSasha Levin <sashal@kernel.org>
Sun, 23 Feb 2025 17:23:16 +0000 (12:23 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.10/bpf-skip-non-exist-keys-in-generic_map_lookup_batch.patch [new file with mode: 0644]
queue-5.10/power-supply-da9150-fg-fix-potential-overflow.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/bpf-skip-non-exist-keys-in-generic_map_lookup_batch.patch b/queue-5.10/bpf-skip-non-exist-keys-in-generic_map_lookup_batch.patch
new file mode 100644 (file)
index 0000000..4b7a548
--- /dev/null
@@ -0,0 +1,119 @@
+From 67555a67c8ba62a2b2fcbf5fb2ee9e9572957559 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Feb 2025 23:22:35 -0800
+Subject: bpf: skip non exist keys in generic_map_lookup_batch
+
+From: Yan Zhai <yan@cloudflare.com>
+
+[ Upstream commit 5644c6b50ffee0a56c1e01430a8c88e34decb120 ]
+
+The generic_map_lookup_batch currently returns EINTR if it fails with
+ENOENT and retries several times on bpf_map_copy_value. The next batch
+would start from the same location, presuming it's a transient issue.
+This is incorrect if a map can actually have "holes", i.e.
+"get_next_key" can return a key that does not point to a valid value. At
+least the array of maps type may contain such holes legitly. Right now
+these holes show up, generic batch lookup cannot proceed any more. It
+will always fail with EINTR errors.
+
+Rather, do not retry in generic_map_lookup_batch. If it finds a non
+existing element, skip to the next key. This simple solution comes with
+a price that transient errors may not be recovered, and the iteration
+might cycle back to the first key under parallel deletion. For example,
+Hou Tao <houtao@huaweicloud.com> pointed out a following scenario:
+
+For LPM trie map:
+(1) ->map_get_next_key(map, prev_key, key) returns a valid key
+
+(2) bpf_map_copy_value() return -ENOMENT
+It means the key must be deleted concurrently.
+
+(3) goto next_key
+It swaps the prev_key and key
+
+(4) ->map_get_next_key(map, prev_key, key) again
+prev_key points to a non-existing key, for LPM trie it will treat just
+like prev_key=NULL case, the returned key will be duplicated.
+
+With the retry logic, the iteration can continue to the key next to the
+deleted one. But if we directly skip to the next key, the iteration loop
+would restart from the first key for the lpm_trie type.
+
+However, not all races may be recovered. For example, if current key is
+deleted after instead of before bpf_map_copy_value, or if the prev_key
+also gets deleted, then the loop will still restart from the first key
+for lpm_tire anyway. For generic lookup it might be better to stay
+simple, i.e. just skip to the next key. To guarantee that the output
+keys are not duplicated, it is better to implement map type specific
+batch operations, which can properly lock the trie and synchronize with
+concurrent mutators.
+
+Fixes: cb4d03ab499d ("bpf: Add generic support for lookup batch op")
+Closes: https://lore.kernel.org/bpf/Z6JXtA1M5jAZx8xD@debian.debian/
+Signed-off-by: Yan Zhai <yan@cloudflare.com>
+Acked-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/85618439eea75930630685c467ccefeac0942e2b.1739171594.git.yan@cloudflare.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/syscall.c | 18 +++++-------------
+ 1 file changed, 5 insertions(+), 13 deletions(-)
+
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index b5d9bba738347..008bb4e5c4ddc 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -1406,8 +1406,6 @@ int generic_map_update_batch(struct bpf_map *map,
+       return err;
+ }
+-#define MAP_LOOKUP_RETRIES 3
+-
+ int generic_map_lookup_batch(struct bpf_map *map,
+                                   const union bpf_attr *attr,
+                                   union bpf_attr __user *uattr)
+@@ -1417,8 +1415,8 @@ int generic_map_lookup_batch(struct bpf_map *map,
+       void __user *values = u64_to_user_ptr(attr->batch.values);
+       void __user *keys = u64_to_user_ptr(attr->batch.keys);
+       void *buf, *buf_prevkey, *prev_key, *key, *value;
+-      int err, retry = MAP_LOOKUP_RETRIES;
+       u32 value_size, cp, max_count;
++      int err;
+       if (attr->batch.elem_flags & ~BPF_F_LOCK)
+               return -EINVAL;
+@@ -1464,14 +1462,8 @@ int generic_map_lookup_batch(struct bpf_map *map,
+               err = bpf_map_copy_value(map, key, value,
+                                        attr->batch.elem_flags);
+-              if (err == -ENOENT) {
+-                      if (retry) {
+-                              retry--;
+-                              continue;
+-                      }
+-                      err = -EINTR;
+-                      break;
+-              }
++              if (err == -ENOENT)
++                      goto next_key;
+               if (err)
+                       goto free_buf;
+@@ -1486,12 +1478,12 @@ int generic_map_lookup_batch(struct bpf_map *map,
+                       goto free_buf;
+               }
++              cp++;
++next_key:
+               if (!prev_key)
+                       prev_key = buf_prevkey;
+               swap(prev_key, key);
+-              retry = MAP_LOOKUP_RETRIES;
+-              cp++;
+               cond_resched();
+       }
+-- 
+2.39.5
+
diff --git a/queue-5.10/power-supply-da9150-fg-fix-potential-overflow.patch b/queue-5.10/power-supply-da9150-fg-fix-potential-overflow.patch
new file mode 100644 (file)
index 0000000..d456d5e
--- /dev/null
@@ -0,0 +1,56 @@
+From b383b32717b43fc6cc7346fde0b8e3f0c46be365 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jan 2025 09:00:34 +0000
+Subject: power: supply: da9150-fg: fix potential overflow
+
+From: Andrey Vatoropin <a.vatoropin@crpt.ru>
+
+[ Upstream commit 3fb3cb4350befc4f901c54e0cb4a2a47b1302e08 ]
+
+Size of variable sd_gain equals four bytes - DA9150_QIF_SD_GAIN_SIZE.
+Size of variable shunt_val equals two bytes - DA9150_QIF_SHUNT_VAL_SIZE.
+
+The expression sd_gain * shunt_val is currently being evaluated using
+32-bit arithmetic. So during the multiplication an overflow may occur.
+
+As the value of type 'u64' is used as storage for the eventual result, put
+ULL variable at the first position of each expression in order to give the
+compiler complete information about the proper arithmetic to use. According
+to C99 the guaranteed width for a variable of type 'unsigned long long' >=
+64 bits.
+
+Remove the explicit cast to u64 as it is meaningless.
+
+Just for the sake of consistency, perform the similar trick with another
+expression concerning 'iavg'.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: a419b4fd9138 ("power: Add support for DA9150 Fuel-Gauge")
+Signed-off-by: Andrey Vatoropin <a.vatoropin@crpt.ru>
+Link: https://lore.kernel.org/r/20250130090030.53422-1-a.vatoropin@crpt.ru
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/da9150-fg.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/supply/da9150-fg.c b/drivers/power/supply/da9150-fg.c
+index 6e367826aae92..d5e1fbac87f22 100644
+--- a/drivers/power/supply/da9150-fg.c
++++ b/drivers/power/supply/da9150-fg.c
+@@ -247,9 +247,9 @@ static int da9150_fg_current_avg(struct da9150_fg *fg,
+                                     DA9150_QIF_SD_GAIN_SIZE);
+       da9150_fg_read_sync_end(fg);
+-      div = (u64) (sd_gain * shunt_val * 65536ULL);
++      div = 65536ULL * sd_gain * shunt_val;
+       do_div(div, 1000000);
+-      res = (u64) (iavg * 1000000ULL);
++      res = 1000000ULL * iavg;
+       do_div(res, div);
+       val->intval = (int) res;
+-- 
+2.39.5
+
index 62e2194d3150c5d32ada3bc40c97792e5f30b0c9..6bb626a2afa1a444d722910eaa8e81b4395d54a6 100644 (file)
@@ -352,3 +352,5 @@ geneve-suppress-list-corruption-splat-in-geneve_dest.patch
 net-extract-port-range-fields-from-fl_flow_key.patch
 flow_dissector-fix-handling-of-mixed-port-and-port-r.patch
 flow_dissector-fix-port-range-key-handling-in-bpf-co.patch
+power-supply-da9150-fg-fix-potential-overflow.patch
+bpf-skip-non-exist-keys-in-generic_map_lookup_batch.patch