From: Josef Bacik <josef(a)toxicpanda.com>
stable inclusion
from stable-v5.10.226
commit c60676b81fab456b672796830f6d8057058f029c
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAU9NE
CVE: CVE-2024-46840
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit b8ccef048354074a548f108e51d0557d6adfd3a3 ]
In reada we BUG_ON(refs == 0), which could be unkind since we aren't
holding a lock on the extent leaf and thus could get a transient
incorrect answer. In walk_down_proc we also BUG_ON(refs == 0), which
could happen if we have extent tree corruption. Change that to return
-EUCLEAN. In do_walk_down() we catch this case and handle it correctly,
however we return -EIO, which -EUCLEAN is a more appropriate error code.
Finally in walk_up_proc we have the same BUG_ON(refs == 0), so convert
that to proper error handling. Also adjust the error message so we can
actually do something with the information.
Signed-off-by: Josef Bacik <josef(a)toxicpanda.com>
Reviewed-by: David Sterba <dsterba(a)suse.com>
Signed-off-by: David Sterba <dsterba(a)suse.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Conflicts:
fs/btrfs/extent-tree.c
[Context difference.]
Signed-off-by: Baokun Li <libaokun1(a)huawei.com>
---
fs/btrfs/extent-tree.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 62956c24b4b5..8212c2440158 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4796,7 +4796,15 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
/* We don't care about errors in readahead. */
if (ret < 0)
continue;
- BUG_ON(refs == 0);
+
+ /*
+ * This could be racey, it's conceivable that we raced and end
+ * up with a bogus refs count, if that's the case just skip, if
+ * we are actually corrupt we will notice when we look up
+ * everything again with our locks.
+ */
+ if (refs == 0)
+ continue;
if (wc->stage == DROP_REFERENCE) {
if (refs == 1)
@@ -4862,7 +4870,11 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
&wc->flags[level]);
if (ret)
return ret;
- BUG_ON(wc->refs[level] == 0);
+ if (unlikely(wc->refs[level] == 0)) {
+ btrfs_err(fs_info, "bytenr %llu has 0 references, expect > 0",
+ eb->start);
+ return -EUCLEAN;
+ }
}
if (wc->stage == DROP_REFERENCE) {
@@ -4995,8 +5007,9 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
goto out_unlock;
if (unlikely(wc->refs[level - 1] == 0)) {
- btrfs_err(fs_info, "Missing references.");
- ret = -EIO;
+ btrfs_err(fs_info, "bytenr %llu has 0 references, expect > 0",
+ bytenr);
+ ret = -EUCLEAN;
goto out_unlock;
}
*lookup_info = 0;
@@ -5198,7 +5211,12 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
path->locks[level] = 0;
return ret;
}
- BUG_ON(wc->refs[level] == 0);
+ if (unlikely(wc->refs[level] == 0)) {
+ btrfs_tree_unlock_rw(eb, path->locks[level]);
+ btrfs_err(fs_info, "bytenr %llu has 0 references, expect > 0",
+ eb->start);
+ return -EUCLEAN;
+ }
if (wc->refs[level] == 1) {
btrfs_tree_unlock_rw(eb, path->locks[level]);
path->locks[level] = 0;
--
2.31.1
From: Josef Bacik <josef(a)toxicpanda.com>
stable inclusion
from stable-v5.10.226
commit c60676b81fab456b672796830f6d8057058f029c
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAU9NE
CVE: CVE-2024-46840
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit b8ccef048354074a548f108e51d0557d6adfd3a3 ]
In reada we BUG_ON(refs == 0), which could be unkind since we aren't
holding a lock on the extent leaf and thus could get a transient
incorrect answer. In walk_down_proc we also BUG_ON(refs == 0), which
could happen if we have extent tree corruption. Change that to return
-EUCLEAN. In do_walk_down() we catch this case and handle it correctly,
however we return -EIO, which -EUCLEAN is a more appropriate error code.
Finally in walk_up_proc we have the same BUG_ON(refs == 0), so convert
that to proper error handling. Also adjust the error message so we can
actually do something with the information.
Signed-off-by: Josef Bacik <josef(a)toxicpanda.com>
Reviewed-by: David Sterba <dsterba(a)suse.com>
Signed-off-by: David Sterba <dsterba(a)suse.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Conflicts:
fs/btrfs/extent-tree.c
[Context difference.]
Signed-off-by: Baokun Li <libaokun1(a)huawei.com>
---
fs/btrfs/extent-tree.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 854c7fa0fc06..12d2923da2b4 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4808,7 +4808,15 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
/* We don't care about errors in readahead. */
if (ret < 0)
continue;
- BUG_ON(refs == 0);
+
+ /*
+ * This could be racey, it's conceivable that we raced and end
+ * up with a bogus refs count, if that's the case just skip, if
+ * we are actually corrupt we will notice when we look up
+ * everything again with our locks.
+ */
+ if (refs == 0)
+ continue;
if (wc->stage == DROP_REFERENCE) {
if (refs == 1)
@@ -4874,7 +4882,11 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
&wc->flags[level]);
if (ret)
return ret;
- BUG_ON(wc->refs[level] == 0);
+ if (unlikely(wc->refs[level] == 0)) {
+ btrfs_err(fs_info, "bytenr %llu has 0 references, expect > 0",
+ eb->start);
+ return -EUCLEAN;
+ }
}
if (wc->stage == DROP_REFERENCE) {
@@ -5007,8 +5019,9 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
goto out_unlock;
if (unlikely(wc->refs[level - 1] == 0)) {
- btrfs_err(fs_info, "Missing references.");
- ret = -EIO;
+ btrfs_err(fs_info, "bytenr %llu has 0 references, expect > 0",
+ bytenr);
+ ret = -EUCLEAN;
goto out_unlock;
}
*lookup_info = 0;
@@ -5210,7 +5223,12 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
path->locks[level] = 0;
return ret;
}
- BUG_ON(wc->refs[level] == 0);
+ if (unlikely(wc->refs[level] == 0)) {
+ btrfs_tree_unlock_rw(eb, path->locks[level]);
+ btrfs_err(fs_info, "bytenr %llu has 0 references, expect > 0",
+ eb->start);
+ return -EUCLEAN;
+ }
if (wc->refs[level] == 1) {
btrfs_tree_unlock_rw(eb, path->locks[level]);
path->locks[level] = 0;
--
2.31.1
Hi Tim,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: c9c7afae6802fd2282529d80c0f808360f7b654a
commit: f4128ae8e6ff03b4c805707fe75d0345797f7f53 [23034/30000] sched: Add cluster scheduler level for x86
config: x86_64-buildonly-randconfig-002-20241010 (https://download.01.org/0day-ci/archive/20241010/202410100921.MexAROBI-lkp@…)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241010/202410100921.MexAROBI-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410100921.MexAROBI-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from kernel/sched/topology.c:5:
kernel/sched/sched.h:1838:15: warning: cast from 'void (*)(struct rq *)' to 'void (*)(struct callback_head *)' converts to incompatible function type [-Wcast-function-type-strict]
1838 | head->func = (void (*)(struct callback_head *))func;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
kernel/sched/topology.c:718:6: warning: variable 'numa_distance' set but not used [-Wunused-but-set-variable]
718 | int numa_distance = 0;
| ^
>> kernel/sched/topology.c:1749:2: error: implicit declaration of function 'register_sysctl_init' [-Werror,-Wimplicit-function-declaration]
1749 | register_sysctl_init("kernel", sched_cluster_sysctls);
| ^
2 warnings and 1 error generated.
vim +/register_sysctl_init +1749 kernel/sched/topology.c
8ce3e706b314091 Tim Chen 2021-12-03 1746
8ce3e706b314091 Tim Chen 2021-12-03 1747 static int __init sched_cluster_sysctl_init(void)
8ce3e706b314091 Tim Chen 2021-12-03 1748 {
8ce3e706b314091 Tim Chen 2021-12-03 @1749 register_sysctl_init("kernel", sched_cluster_sysctls);
8ce3e706b314091 Tim Chen 2021-12-03 1750 return 0;
8ce3e706b314091 Tim Chen 2021-12-03 1751 }
8ce3e706b314091 Tim Chen 2021-12-03 1752 late_initcall(sched_cluster_sysctl_init);
9e68cc2bf535a2f Tim Chen 2021-12-03 1753
:::::: The code at line 1749 was first introduced by commit
:::::: 8ce3e706b31409147f035c037055caa68e450ce5 scheduler: Add runtime knob sysctl_sched_cluster
:::::: TO: Tim Chen <tim.c.chen(a)linux.intel.com>
:::::: CC: Jie Liu <liujie375(a)h-partners.com>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Li,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 5d76abff5e121f2d916bcbc121f558c82e5dc221
commit: 792b82446538ed840a6e23b89673ce21564702bd [3405/14324] Fix gic support for Phytium S2500
config: arm64-randconfig-002-20241010 (https://download.01.org/0day-ci/archive/20241010/202410100523.x3WsGWyG-lkp@…)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 70e0a7e7e6a8541bcc46908c592eed561850e416)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241010/202410100523.x3WsGWyG-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410100523.x3WsGWyG-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from drivers/gpu/drm/phytium/phytium_pci.c:7:
In file included from include/linux/pci.h:2106:
In file included from arch/arm64/include/asm/pci.h:7:
In file included from include/linux/dma-mapping.h:11:
In file included from include/linux/scatterlist.h:8:
In file included from include/linux/mm.h:2193:
include/linux/vmstat.h:522:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
522 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
| ~~~~~~~~~~~ ^ ~~~
drivers/gpu/drm/phytium/phytium_pci.c:23:6: warning: no previous prototype for function 'phytium_pci_vram_hw_init' [-Wmissing-prototypes]
23 | void phytium_pci_vram_hw_init(struct phytium_display_private *priv)
| ^
drivers/gpu/drm/phytium/phytium_pci.c:23:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
23 | void phytium_pci_vram_hw_init(struct phytium_display_private *priv)
| ^
| static
drivers/gpu/drm/phytium/phytium_pci.c:30:5: warning: no previous prototype for function 'phytium_pci_vram_init' [-Wmissing-prototypes]
30 | int phytium_pci_vram_init(struct pci_dev *pdev, struct phytium_display_private *priv)
| ^
drivers/gpu/drm/phytium/phytium_pci.c:30:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
30 | int phytium_pci_vram_init(struct pci_dev *pdev, struct phytium_display_private *priv)
| ^
| static
drivers/gpu/drm/phytium/phytium_pci.c:68:6: warning: no previous prototype for function 'phytium_pci_vram_fini' [-Wmissing-prototypes]
68 | void phytium_pci_vram_fini(struct pci_dev *pdev, struct phytium_display_private *priv)
| ^
drivers/gpu/drm/phytium/phytium_pci.c:68:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
68 | void phytium_pci_vram_fini(struct pci_dev *pdev, struct phytium_display_private *priv)
| ^
| static
drivers/gpu/drm/phytium/phytium_pci.c:89:5: warning: no previous prototype for function 'phytium_pci_dma_init' [-Wmissing-prototypes]
89 | int phytium_pci_dma_init(struct phytium_display_private *priv)
| ^
drivers/gpu/drm/phytium/phytium_pci.c:89:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
89 | int phytium_pci_dma_init(struct phytium_display_private *priv)
| ^
| static
drivers/gpu/drm/phytium/phytium_pci.c:137:6: warning: no previous prototype for function 'phytium_pci_dma_fini' [-Wmissing-prototypes]
137 | void phytium_pci_dma_fini(struct phytium_display_private *priv)
| ^
drivers/gpu/drm/phytium/phytium_pci.c:137:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
137 | void phytium_pci_dma_fini(struct phytium_display_private *priv)
| ^
| static
>> drivers/gpu/drm/phytium/phytium_pci.c:236:9: error: call to undeclared function 'pci_enable_msi'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
236 | ret = pci_enable_msi(pdev);
| ^
>> drivers/gpu/drm/phytium/phytium_pci.c:271:3: error: call to undeclared function 'pci_disable_msi'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
271 | pci_disable_msi(pdev);
| ^
drivers/gpu/drm/phytium/phytium_pci.c:271:3: note: did you mean 'pci_disable_sriov'?
include/linux/pci.h:2437:20: note: 'pci_disable_sriov' declared here
2437 | static inline void pci_disable_sriov(struct pci_dev *dev) { }
| ^
drivers/gpu/drm/phytium/phytium_pci.c:291:3: error: call to undeclared function 'pci_disable_msi'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
291 | pci_disable_msi(pdev);
| ^
6 warnings and 3 errors generated.
vim +/pci_enable_msi +236 drivers/gpu/drm/phytium/phytium_pci.c
b80df10f845813 lishuo 2024-01-31 215
b80df10f845813 lishuo 2024-01-31 216 static int phytium_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
b80df10f845813 lishuo 2024-01-31 217 {
b80df10f845813 lishuo 2024-01-31 218 struct phytium_display_private *priv = NULL;
b80df10f845813 lishuo 2024-01-31 219 struct drm_device *dev = NULL;
b80df10f845813 lishuo 2024-01-31 220 int ret = 0;
b80df10f845813 lishuo 2024-01-31 221
b80df10f845813 lishuo 2024-01-31 222 dev = drm_dev_alloc(&phytium_display_drm_driver, &pdev->dev);
b80df10f845813 lishuo 2024-01-31 223 if (IS_ERR(dev)) {
b80df10f845813 lishuo 2024-01-31 224 DRM_ERROR("failed to allocate drm_device\n");
b80df10f845813 lishuo 2024-01-31 225 return PTR_ERR(dev);
b80df10f845813 lishuo 2024-01-31 226 }
b80df10f845813 lishuo 2024-01-31 227 pci_set_drvdata(pdev, dev);
b80df10f845813 lishuo 2024-01-31 228 pci_set_master(pdev);
b80df10f845813 lishuo 2024-01-31 229 ret = pci_enable_device(pdev);
b80df10f845813 lishuo 2024-01-31 230 if (ret) {
b80df10f845813 lishuo 2024-01-31 231 DRM_ERROR("pci enable device fail\n");
b80df10f845813 lishuo 2024-01-31 232 goto failed_enable_device;
b80df10f845813 lishuo 2024-01-31 233 }
b80df10f845813 lishuo 2024-01-31 234
b80df10f845813 lishuo 2024-01-31 235 if (dc_msi_enable) {
b80df10f845813 lishuo 2024-01-31 @236 ret = pci_enable_msi(pdev);
b80df10f845813 lishuo 2024-01-31 237 if (ret)
b80df10f845813 lishuo 2024-01-31 238 DRM_ERROR("pci enable msi fail\n");
b80df10f845813 lishuo 2024-01-31 239 }
b80df10f845813 lishuo 2024-01-31 240
b80df10f845813 lishuo 2024-01-31 241 dma_set_mask(&pdev->dev, DMA_BIT_MASK(40));
b80df10f845813 lishuo 2024-01-31 242
b80df10f845813 lishuo 2024-01-31 243 priv = phytium_pci_private_init(pdev, ent);
b80df10f845813 lishuo 2024-01-31 244 if (priv)
b80df10f845813 lishuo 2024-01-31 245 dev->dev_private = priv;
b80df10f845813 lishuo 2024-01-31 246 else
b80df10f845813 lishuo 2024-01-31 247 goto failed_pci_private_init;
b80df10f845813 lishuo 2024-01-31 248
b80df10f845813 lishuo 2024-01-31 249 ret = phytium_pci_vram_init(pdev, priv);
b80df10f845813 lishuo 2024-01-31 250 if (ret) {
b80df10f845813 lishuo 2024-01-31 251 DRM_ERROR("failed to init pci vram\n");
b80df10f845813 lishuo 2024-01-31 252 goto failed_pci_vram_init;
b80df10f845813 lishuo 2024-01-31 253 }
b80df10f845813 lishuo 2024-01-31 254
b80df10f845813 lishuo 2024-01-31 255 ret = drm_dev_register(dev, 0);
b80df10f845813 lishuo 2024-01-31 256 if (ret) {
b80df10f845813 lishuo 2024-01-31 257 DRM_ERROR("failed to register drm dev\n");
b80df10f845813 lishuo 2024-01-31 258 goto failed_register_drm;
b80df10f845813 lishuo 2024-01-31 259 }
b80df10f845813 lishuo 2024-01-31 260
b80df10f845813 lishuo 2024-01-31 261 phytium_dp_hpd_irq_setup(dev, true);
b80df10f845813 lishuo 2024-01-31 262
b80df10f845813 lishuo 2024-01-31 263 return 0;
b80df10f845813 lishuo 2024-01-31 264
b80df10f845813 lishuo 2024-01-31 265 failed_register_drm:
b80df10f845813 lishuo 2024-01-31 266 phytium_pci_vram_fini(pdev, priv);
b80df10f845813 lishuo 2024-01-31 267 failed_pci_vram_init:
b80df10f845813 lishuo 2024-01-31 268 phytium_pci_private_fini(pdev, priv);
b80df10f845813 lishuo 2024-01-31 269 failed_pci_private_init:
b80df10f845813 lishuo 2024-01-31 270 if (pdev->msi_enabled)
b80df10f845813 lishuo 2024-01-31 @271 pci_disable_msi(pdev);
b80df10f845813 lishuo 2024-01-31 272 pci_disable_device(pdev);
b80df10f845813 lishuo 2024-01-31 273 failed_enable_device:
b80df10f845813 lishuo 2024-01-31 274 pci_set_drvdata(pdev, NULL);
b80df10f845813 lishuo 2024-01-31 275 drm_dev_put(dev);
b80df10f845813 lishuo 2024-01-31 276
b80df10f845813 lishuo 2024-01-31 277 return -1;
b80df10f845813 lishuo 2024-01-31 278 }
b80df10f845813 lishuo 2024-01-31 279
:::::: The code at line 236 was first introduced by commit
:::::: b80df10f845813bb4fc2002b5386ecdfa8be5f6c DRM: Phytium display DRM driver
:::::: TO: lishuo <lishuo(a)phytium.com.cn>
:::::: CC: lishuo <lishuo(a)phytium.com.cn>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki