From: Jan Kara <jack(a)suse.cz>
stable inclusion
from stable-v4.19.320
commit 2b2d2b8766db028bd827af34075f221ae9e9efff
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAGRLH
CVE: CVE-2024-42131
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 385d838df280eba6c8680f9777bfa0d0bfe7e8b2 ]
The dirty throttling logic is interspersed with assumptions that dirty
limits in PAGE_SIZE units fit into 32-bit (so that various multiplications
fit into 64-bits). If limits end up being larger, we will hit overflows,
possible divisions by 0 etc. Fix these problems by never allowing so
large dirty limits as they have dubious practical value anyway. For
dirty_bytes / dirty_background_bytes interfaces we can just refuse to set
so large limits. For dirty_ratio / dirty_background_ratio it isn't so
simple as the dirty limit is computed from the amount of available memory
which can change due to memory hotplug etc. So when converting dirty
limits from ratios to numbers of pages, we just don't allow the result to
exceed UINT_MAX.
This is root-only triggerable problem which occurs when the operator
sets dirty limits to >16 TB.
Link: https://lkml.kernel.org/r/20240621144246.11148-2-jack@suse.cz
Signed-off-by: Jan Kara <jack(a)suse.cz>
Reported-by: Zach O'Keefe <zokeefe(a)google.com>
Reviewed-By: Zach O'Keefe <zokeefe(a)google.com>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com>
---
mm/page-writeback.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 43e83930ce44..06d8242a926e 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -432,13 +432,20 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc)
else
bg_thresh = (bg_ratio * available_memory) / PAGE_SIZE;
- if (bg_thresh >= thresh)
- bg_thresh = thresh / 2;
tsk = current;
if (tsk->flags & PF_LESS_THROTTLE || rt_task(tsk)) {
bg_thresh += bg_thresh / 4 + global_wb_domain.dirty_limit / 32;
thresh += thresh / 4 + global_wb_domain.dirty_limit / 32;
}
+ /*
+ * Dirty throttling logic assumes the limits in page units fit into
+ * 32-bits. This gives 16TB dirty limits max which is hopefully enough.
+ */
+ if (thresh > UINT_MAX)
+ thresh = UINT_MAX;
+ /* This makes sure bg_thresh is within 32-bits as well */
+ if (bg_thresh >= thresh)
+ bg_thresh = thresh / 2;
dtc->thresh = thresh;
dtc->bg_thresh = bg_thresh;
@@ -488,7 +495,11 @@ static unsigned long node_dirty_limit(struct pglist_data *pgdat)
if (tsk->flags & PF_LESS_THROTTLE || rt_task(tsk))
dirty += dirty / 4;
- return dirty;
+ /*
+ * Dirty throttling logic assumes the limits in page units fit into
+ * 32-bits. This gives 16TB dirty limits max which is hopefully enough.
+ */
+ return min_t(unsigned long, dirty, UINT_MAX);
}
/**
@@ -527,10 +538,17 @@ int dirty_background_bytes_handler(struct ctl_table *table, int write,
loff_t *ppos)
{
int ret;
+ unsigned long old_bytes = dirty_background_bytes;
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
- if (ret == 0 && write)
+ if (ret == 0 && write) {
+ if (DIV_ROUND_UP(dirty_background_bytes, PAGE_SIZE) >
+ UINT_MAX) {
+ dirty_background_bytes = old_bytes;
+ return -ERANGE;
+ }
dirty_background_ratio = 0;
+ }
return ret;
}
@@ -558,6 +576,10 @@ int dirty_bytes_handler(struct ctl_table *table, int write,
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
if (ret == 0 && write && vm_dirty_bytes != old_bytes) {
+ if (DIV_ROUND_UP(vm_dirty_bytes, PAGE_SIZE) > UINT_MAX) {
+ vm_dirty_bytes = old_bytes;
+ return -ERANGE;
+ }
writeback_set_ratelimit();
vm_dirty_ratio = 0;
}
--
2.25.1
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: b3492b88408a530f644afcd9e80b98cbf9883a82
commit: 013280dfab06d20e73de842e8d2fc2a200055455 [26952/30000] urma: upload kernel patch for 20240224_rain
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20240829/202408290746.znnxteuy-lkp@…)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240829/202408290746.znnxteuy-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/202408290746.znnxteuy-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/ub/urma/ubcore/ubcore_vtp.c:261:6: warning: no previous prototype for function 'ubcore_hash_table_rmv_vtpn' [-Wmissing-prototypes]
261 | void ubcore_hash_table_rmv_vtpn(struct ubcore_device *dev, struct ubcore_vtpn *vtpn)
| ^
drivers/ub/urma/ubcore/ubcore_vtp.c:261:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
261 | void ubcore_hash_table_rmv_vtpn(struct ubcore_device *dev, struct ubcore_vtpn *vtpn)
| ^
| static
1 warning generated.
vim +/ubcore_hash_table_rmv_vtpn +261 drivers/ub/urma/ubcore/ubcore_vtp.c
260
> 261 void ubcore_hash_table_rmv_vtpn(struct ubcore_device *dev, struct ubcore_vtpn *vtpn)
262 {
263 struct ubcore_hash_table *ht;
264
265 ht = ubcore_get_vtpn_ht(dev, vtpn->trans_mode);
266 if (ht == NULL)
267 return;
268 ubcore_hash_table_remove(ht, &vtpn->hnode);
269 }
270
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: b3492b88408a530f644afcd9e80b98cbf9883a82
commit: 822da186955cbcd69b4715b8a307053e6c756f30 [29221/30000] x86/ibt,paravirt: Use text_gen_insn() for paravirt_patch()
config: x86_64-buildonly-randconfig-005-20240829 (https://download.01.org/0day-ci/archive/20240829/202408290612.YVWkhiUH-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240829/202408290612.YVWkhiUH-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/202408290612.YVWkhiUH-lkp@intel.com/
All errors (new ones prefixed by >>):
arch/x86/kernel/paravirt.c: In function 'paravirt_patch_call':
>> arch/x86/kernel/paravirt.c:65:9: error: implicit declaration of function '__text_gen_insn' [-Werror=implicit-function-declaration]
65 | __text_gen_insn(insn_buff, CALL_INSN_OPCODE,
| ^~~~~~~~~~~~~~~
>> arch/x86/kernel/paravirt.c:65:36: error: 'CALL_INSN_OPCODE' undeclared (first use in this function)
65 | __text_gen_insn(insn_buff, CALL_INSN_OPCODE,
| ^~~~~~~~~~~~~~~~
arch/x86/kernel/paravirt.c:65:36: note: each undeclared identifier is reported only once for each function it appears in
>> arch/x86/kernel/paravirt.c:66:47: error: 'CALL_INSN_SIZE' undeclared (first use in this function)
66 | (void *)addr, target, CALL_INSN_SIZE);
| ^~~~~~~~~~~~~~
arch/x86/kernel/paravirt.c: At top level:
arch/x86/kernel/paravirt.c:99:13: warning: no previous prototype for 'native_pv_lock_init' [-Wmissing-prototypes]
99 | void __init native_pv_lock_init(void)
| ^~~~~~~~~~~~~~~~~~~
arch/x86/kernel/paravirt.c: In function 'paravirt_patch_call':
arch/x86/kernel/paravirt.c:68:1: warning: control reaches end of non-void function [-Wreturn-type]
68 | }
| ^
cc1: some warnings being treated as errors
vim +/__text_gen_insn +65 arch/x86/kernel/paravirt.c
61
62 static unsigned paravirt_patch_call(void *insn_buff, const void *target,
63 unsigned long addr, unsigned len)
64 {
> 65 __text_gen_insn(insn_buff, CALL_INSN_OPCODE,
> 66 (void *)addr, target, CALL_INSN_SIZE);
67 return CALL_INSN_SIZE;
68 }
69
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Yu,
FYI, the error/warning was bisected to this commit, please ignore it if it's irrelevant.
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: 46d28312ab3cc0cfe7e8dea2f41d22fe4ac35e67
commit: 9d0422bf311dfb36617e4d8f7367a3e7dc9179ec [20748/23581] nbd: fold nbd config initialization into nbd_alloc_config()
config: x86_64-buildonly-randconfig-004-20240825 (https://download.01.org/0day-ci/archive/20240829/202408290453.uMJshGum-lkp@…)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240829/202408290453.uMJshGum-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/202408290453.uMJshGum-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from drivers/block/nbd.c:17:
In file included from include/linux/blkdev.h:16:
include/linux/pagemap.h:425:21: warning: cast from 'int (*)(struct file *, struct page *)' to 'filler_t *' (aka 'int (*)(void *, struct page *)') converts to incompatible function type [-Wcast-function-type-strict]
425 | filler_t *filler = (filler_t *)mapping->a_ops->readpage;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
>> drivers/block/.tmp_nbd.o: warning: objtool: nbd_alloc_and_init_config()+0x165: unreachable instruction
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki