From: Sergey Shtylyov <s.shtylyov(a)omp.ru>
mainline inclusion
from mainline-v6.9-rc3
commit a1aa5390cc912934fee76ce80af5f940452fa987
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9QG8R
CVE: CVE-2024-35878
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
In of_modalias(), we can get passed the str and len parameters which would
cause a kernel oops in vsnprintf() since it only allows passing a NULL ptr
when the length is also 0. Also, we need to filter out the negative values
of the len parameter as these will result in a really huge buffer since
snprintf() takes size_t parameter while ours is ssize_t...
Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.
Signed-off-by: Sergey Shtylyov <s.shtylyov(a)omp.ru>
Cc: stable(a)vger.kernel.org
Link: https://lore.kernel.org/r/1d211023-3923-685b-20f0-f3f90ea56e1f@omp.ru
Signed-off-by: Rob Herring <robh(a)kernel.org>
Conflicts:
drivers/of/device.c
drivers/of/module.c
[chenjun: context conflicts. of_modalias() is not extracted from
of_device_get_modalias().]
Signed-off-by: Chen Jun <chenjun102(a)huawei.com>
---
drivers/of/device.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 93f08f18f6b3..0b1d317acb88 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -226,6 +226,14 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len
if ((!dev) || (!dev->of_node))
return -ENODEV;
+ /*
+ * Prevent a kernel oops in vsnprintf() -- it only allows passing a
+ * NULL ptr when the length is also 0. Also filter out the negative
+ * lengths...
+ */
+ if ((len > 0 && !str) || len < 0)
+ return -EINVAL;
+
/* Name & Type */
/* %p eats all alphanum characters, so %c must be used here */
csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T',
--
2.17.1
From: Ma Wupeng <mawupeng1(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6RKHX
--------------------------------
After the fork operation, it is erroneous for the child process to have a
reliable page size twice that of its parent process.
Upon examining the mm_struct structure, it was discovered that
reliable_nr_page should be initialized to 0, similar to how RSS is
initialized during mm_init(). This particular problem that arises during
forking is merely one such example.
To resolve this issue, it is recommended to set reliable_nr_page to 0
during the mm_init() operation.
Fixes: 8fc2546f8508 ("proc: mem_reliable: Count reliable memory usage of reliable tasks")
Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com>
---
include/linux/mem_reliable.h | 9 +++++++++
kernel/fork.c | 1 +
2 files changed, 10 insertions(+)
diff --git a/include/linux/mem_reliable.h b/include/linux/mem_reliable.h
index d8cabf94f4a32..1e928ff69d997 100644
--- a/include/linux/mem_reliable.h
+++ b/include/linux/mem_reliable.h
@@ -216,6 +216,14 @@ static inline void add_reliable_page_counter(struct page *page,
reliable_page_counter_inner(mm, val);
}
+
+static inline void reliable_clear_page_counter(struct mm_struct *mm)
+{
+ if (!mem_reliable_is_enabled())
+ return;
+
+ atomic_long_set(&mm->reliable_nr_page, 0);
+}
#else
#define reliable_enabled 0
@@ -259,6 +267,7 @@ static inline void add_reliable_folio_counter(struct folio *folio,
struct mm_struct *mm, int val) {}
static inline void reliable_report_usage(struct seq_file *m,
struct mm_struct *mm) {}
+static inline void reliable_clear_page_counter(struct mm_struct *mm) {}
#endif
#endif
diff --git a/kernel/fork.c b/kernel/fork.c
index e033388b11bd9..27d605c64b45d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1326,6 +1326,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
mm->locked_vm = 0;
atomic64_set(&mm->pinned_vm, 0);
memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
+ reliable_clear_page_counter(mm);
spin_lock_init(&mm->page_table_lock);
spin_lock_init(&mm->arg_lock);
mm_init_cpumask(mm);
--
2.25.1