* [PATCH] mm/migrate: fix do_pages_move for compat pointers
@ 2023-10-03 14:48 Gregory Price
2023-10-03 14:48 ` [PATCH 2/2] mm/migrate: remove unused mm argument from do_move_pages_to_node Gregory Price
2023-10-03 16:49 ` [PATCH] mm/migrate: fix do_pages_move for compat pointers Andrew Morton
0 siblings, 2 replies; 7+ messages in thread
From: Gregory Price @ 2023-10-03 14:48 UTC (permalink / raw)
To: linux-mm; +Cc: linux-kernel, arnd, akpm, Gregory Price
do_pages_move does not handle compat pointers for the page list.
correctly. Add in_compat_syscall check and appropriate get_user
fetch when iterating the page list.
Fixes: 5b1b561ba73c ("mm: simplify compat_sys_move_pages")
Signed-off-by: Gregory Price <gregory.price@memverge.com>
Reported-by: Arnd Bergmann <arnd@arndb.de>
Co-developed-by: Arnd Bergmann <arnd@arndb.de>
---
mm/migrate.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index 2053b54556ca..06086dc9da28 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2162,6 +2162,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
const int __user *nodes,
int __user *status, int flags)
{
+ compat_uptr_t __user *compat_pages = (void __user *)pages;
int current_node = NUMA_NO_NODE;
LIST_HEAD(pagelist);
int start, i;
@@ -2174,8 +2175,17 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
int node;
err = -EFAULT;
- if (get_user(p, pages + i))
- goto out_flush;
+ if (in_compat_syscall()) {
+ compat_uptr_t cp;
+
+ if (get_user(cp, compat_pages + i))
+ goto out_flush;
+
+ p = compat_ptr(cp);
+ } else {
+ if (get_user(p, pages + i))
+ goto out_flush;
+ }
if (get_user(node, nodes + i))
goto out_flush;
--
2.39.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] mm/migrate: remove unused mm argument from do_move_pages_to_node
2023-10-03 14:48 [PATCH] mm/migrate: fix do_pages_move for compat pointers Gregory Price
@ 2023-10-03 14:48 ` Gregory Price
2023-10-03 16:49 ` [PATCH] mm/migrate: fix do_pages_move for compat pointers Andrew Morton
1 sibling, 0 replies; 7+ messages in thread
From: Gregory Price @ 2023-10-03 14:48 UTC (permalink / raw)
To: linux-mm; +Cc: linux-kernel, arnd, akpm, Gregory Price, Jonathan Cameron
This function does not actively use the mm_struct, it can be removed.
Signed-off-by: Gregory Price <gregory.price@memverge.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
mm/migrate.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index 06086dc9da28..4e8368408b17 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2029,8 +2029,7 @@ static int store_status(int __user *status, int start, int value, int nr)
return 0;
}
-static int do_move_pages_to_node(struct mm_struct *mm,
- struct list_head *pagelist, int node)
+static int do_move_pages_to_node(struct list_head *pagelist, int node)
{
int err;
struct migration_target_control mtc = {
@@ -2126,7 +2125,7 @@ static int add_page_for_migration(struct mm_struct *mm, const void __user *p,
return err;
}
-static int move_pages_and_store_status(struct mm_struct *mm, int node,
+static int move_pages_and_store_status(int node,
struct list_head *pagelist, int __user *status,
int start, int i, unsigned long nr_pages)
{
@@ -2135,7 +2134,7 @@ static int move_pages_and_store_status(struct mm_struct *mm, int node,
if (list_empty(pagelist))
return 0;
- err = do_move_pages_to_node(mm, pagelist, node);
+ err = do_move_pages_to_node(pagelist, node);
if (err) {
/*
* Positive err means the number of failed
@@ -2203,7 +2202,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
current_node = node;
start = i;
} else if (node != current_node) {
- err = move_pages_and_store_status(mm, current_node,
+ err = move_pages_and_store_status(current_node,
&pagelist, status, start, i, nr_pages);
if (err)
goto out;
@@ -2238,7 +2237,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
if (err)
goto out_flush;
- err = move_pages_and_store_status(mm, current_node, &pagelist,
+ err = move_pages_and_store_status(current_node, &pagelist,
status, start, i, nr_pages);
if (err) {
/* We have accounted for page i */
@@ -2250,7 +2249,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
}
out_flush:
/* Make sure we do not overwrite the existing error */
- err1 = move_pages_and_store_status(mm, current_node, &pagelist,
+ err1 = move_pages_and_store_status(current_node, &pagelist,
status, start, i, nr_pages);
if (err >= 0)
err = err1;
--
2.39.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mm/migrate: fix do_pages_move for compat pointers
2023-10-03 14:48 [PATCH] mm/migrate: fix do_pages_move for compat pointers Gregory Price
2023-10-03 14:48 ` [PATCH 2/2] mm/migrate: remove unused mm argument from do_move_pages_to_node Gregory Price
@ 2023-10-03 16:49 ` Andrew Morton
2023-10-03 16:57 ` Arnd Bergmann
1 sibling, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2023-10-03 16:49 UTC (permalink / raw)
To: Gregory Price; +Cc: linux-mm, linux-kernel, arnd, Gregory Price
On Tue, 3 Oct 2023 10:48:56 -0400 Gregory Price <gourry.memverge@gmail.com> wrote:
> do_pages_move does not handle compat pointers for the page list.
> correctly. Add in_compat_syscall check and appropriate get_user
> fetch when iterating the page list.
What are the userspace visible effects of this change?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mm/migrate: fix do_pages_move for compat pointers
2023-10-03 16:49 ` [PATCH] mm/migrate: fix do_pages_move for compat pointers Andrew Morton
@ 2023-10-03 16:57 ` Arnd Bergmann
2023-10-03 17:01 ` Arnd Bergmann
0 siblings, 1 reply; 7+ messages in thread
From: Arnd Bergmann @ 2023-10-03 16:57 UTC (permalink / raw)
To: Andrew Morton, Gregory Price; +Cc: linux-mm, linux-kernel, Gregory Price
On Tue, Oct 3, 2023, at 18:49, Andrew Morton wrote:
> On Tue, 3 Oct 2023 10:48:56 -0400 Gregory Price
> <gourry.memverge@gmail.com> wrote:
>
>> do_pages_move does not handle compat pointers for the page list.
>> correctly. Add in_compat_syscall check and appropriate get_user
>> fetch when iterating the page list.
>
> What are the userspace visible effects of this change?
It makes the syscall in compat mode (32-bit userspace, 64-bit kernel)
work the same way as the native 32-bit syscall again, restoring the
behavior before my broken commit 5b1b561ba73c ("mm: simplify
compat_sys_move_pages").
Arnd
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mm/migrate: fix do_pages_move for compat pointers
2023-10-03 16:57 ` Arnd Bergmann
@ 2023-10-03 17:01 ` Arnd Bergmann
2023-10-03 17:17 ` Andrew Morton
0 siblings, 1 reply; 7+ messages in thread
From: Arnd Bergmann @ 2023-10-03 17:01 UTC (permalink / raw)
To: Andrew Morton, Gregory Price; +Cc: linux-mm, linux-kernel, Gregory Price
On Tue, Oct 3, 2023, at 18:57, Arnd Bergmann wrote:
> On Tue, Oct 3, 2023, at 18:49, Andrew Morton wrote:
>> On Tue, 3 Oct 2023 10:48:56 -0400 Gregory Price
>> <gourry.memverge@gmail.com> wrote:
>>
>>> do_pages_move does not handle compat pointers for the page list.
>>> correctly. Add in_compat_syscall check and appropriate get_user
>>> fetch when iterating the page list.
>>
>> What are the userspace visible effects of this change?
>
> It makes the syscall in compat mode (32-bit userspace, 64-bit kernel)
> work the same way as the native 32-bit syscall again, restoring the
> behavior before my broken commit 5b1b561ba73c ("mm: simplify
> compat_sys_move_pages").
More specifically, my patch moved the parsing of the 'pages'
array from the main entry point into do_pages_stat(), which left
the syscall working correctly for the 'stat' operation (nodes = NULL),
while the 'move' operation (nodes != NULL) is now missing
the conversion and interprets 'pages' as an array of 64-bit
pointers instead of the intended 32-bit userspace pointers.
Arnd
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mm/migrate: fix do_pages_move for compat pointers
2023-10-03 17:01 ` Arnd Bergmann
@ 2023-10-03 17:17 ` Andrew Morton
2023-10-03 17:36 ` Arnd Bergmann
0 siblings, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2023-10-03 17:17 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: Gregory Price, linux-mm, linux-kernel, Gregory Price
On Tue, 03 Oct 2023 19:01:45 +0200 "Arnd Bergmann" <arnd@arndb.de> wrote:
> On Tue, Oct 3, 2023, at 18:57, Arnd Bergmann wrote:
> > On Tue, Oct 3, 2023, at 18:49, Andrew Morton wrote:
> >> On Tue, 3 Oct 2023 10:48:56 -0400 Gregory Price
> >> <gourry.memverge@gmail.com> wrote:
> >>
> >>> do_pages_move does not handle compat pointers for the page list.
> >>> correctly. Add in_compat_syscall check and appropriate get_user
> >>> fetch when iterating the page list.
> >>
> >> What are the userspace visible effects of this change?
> >
> > It makes the syscall in compat mode (32-bit userspace, 64-bit kernel)
> > work the same way as the native 32-bit syscall again, restoring the
> > behavior before my broken commit 5b1b561ba73c ("mm: simplify
> > compat_sys_move_pages").
>
> More specifically, my patch moved the parsing of the 'pages'
> array from the main entry point into do_pages_stat(), which left
> the syscall working correctly for the 'stat' operation (nodes = NULL),
> while the 'move' operation (nodes != NULL) is now missing
> the conversion and interprets 'pages' as an array of 64-bit
> pointers instead of the intended 32-bit userspace pointers.
>
Thanks. So is a cc:stable warranted?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mm/migrate: fix do_pages_move for compat pointers
2023-10-03 17:17 ` Andrew Morton
@ 2023-10-03 17:36 ` Arnd Bergmann
0 siblings, 0 replies; 7+ messages in thread
From: Arnd Bergmann @ 2023-10-03 17:36 UTC (permalink / raw)
To: Andrew Morton; +Cc: Gregory Price, linux-mm, linux-kernel, Gregory Price
On Tue, Oct 3, 2023, at 19:17, Andrew Morton wrote:
> On Tue, 03 Oct 2023 19:01:45 +0200 "Arnd Bergmann" <arnd@arndb.de> wrote:
>> On Tue, Oct 3, 2023, at 18:57, Arnd Bergmann wrote:
>> > On Tue, Oct 3, 2023, at 18:49, Andrew Morton wrote:
>> >> On Tue, 3 Oct 2023 10:48:56 -0400 Gregory Price
>> >> <gourry.memverge@gmail.com> wrote:
>> >>
>> >>> do_pages_move does not handle compat pointers for the page list.
>> >>> correctly. Add in_compat_syscall check and appropriate get_user
>> >>> fetch when iterating the page list.
>> >>
>> >> What are the userspace visible effects of this change?
>> >
>> > It makes the syscall in compat mode (32-bit userspace, 64-bit kernel)
>> > work the same way as the native 32-bit syscall again, restoring the
>> > behavior before my broken commit 5b1b561ba73c ("mm: simplify
>> > compat_sys_move_pages").
>>
>> More specifically, my patch moved the parsing of the 'pages'
>> array from the main entry point into do_pages_stat(), which left
>> the syscall working correctly for the 'stat' operation (nodes = NULL),
>> while the 'move' operation (nodes != NULL) is now missing
>> the conversion and interprets 'pages' as an array of 64-bit
>> pointers instead of the intended 32-bit userspace pointers.
>>
>
> Thanks. So is a cc:stable warranted?
Yes, absolutely. It is possible that nobody noticed this
bug because the few applications that actually call move_pages are
unlikely to run in compat mode because of their large memory
requirements, but this clearly fixes a user-visible regression
and should have been caught by ltp.
Arnd
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-10-03 17:36 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-03 14:48 [PATCH] mm/migrate: fix do_pages_move for compat pointers Gregory Price
2023-10-03 14:48 ` [PATCH 2/2] mm/migrate: remove unused mm argument from do_move_pages_to_node Gregory Price
2023-10-03 16:49 ` [PATCH] mm/migrate: fix do_pages_move for compat pointers Andrew Morton
2023-10-03 16:57 ` Arnd Bergmann
2023-10-03 17:01 ` Arnd Bergmann
2023-10-03 17:17 ` Andrew Morton
2023-10-03 17:36 ` Arnd Bergmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox