* [PATCH] Fix do_pages_stat to use compat_uptr_t [not found] ` <d42cc185-b774-4d5e-9a51-0581dd5f3962@arm.com> @ 2025-06-25 15:24 ` Christoph Berg 2025-06-25 15:42 ` David Hildenbrand 2025-06-25 20:39 ` [PATCH] Fix do_pages_stat to use compat_uptr_t Andrew Morton 0 siblings, 2 replies; 12+ messages in thread From: Christoph Berg @ 2025-06-25 15:24 UTC (permalink / raw) To: Andrew Morton, David Hildenbrand, Zi Yan, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list For arrays with more than 16 entries, the old code would incorrectly advance the pages pointer by 16 words instead of 16 compat_uptr_t. Signed-off-by: Christoph Berg <myon@debian.org> Suggested-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> --- mm/migrate.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mm/migrate.c b/mm/migrate.c index 8cf0f9c9599..542c81ec3ed 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -2444,7 +2444,13 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status))) break; - pages += chunk_nr; + if (in_compat_syscall()) { + compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages; + + pages32 += chunk_nr; + pages = (const void __user * __user *) pages32; + } else + pages += chunk_nr; status += chunk_nr; nr_pages -= chunk_nr; } -- 2.47.2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Fix do_pages_stat to use compat_uptr_t 2025-06-25 15:24 ` [PATCH] Fix do_pages_stat to use compat_uptr_t Christoph Berg @ 2025-06-25 15:42 ` David Hildenbrand 2025-07-01 16:58 ` [PATCH v2] mm/migrate: Fix do_pages_stat in 32-bit mode Christoph Berg 2025-06-25 20:39 ` [PATCH] Fix do_pages_stat to use compat_uptr_t Andrew Morton 1 sibling, 1 reply; 12+ messages in thread From: David Hildenbrand @ 2025-06-25 15:42 UTC (permalink / raw) To: Christoph Berg, Andrew Morton, Zi Yan, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list On 25.06.25 17:24, Christoph Berg wrote: Subject should start with "mm/migrate:" > For arrays with more than 16 entries, the old code would incorrectly > advance the pages pointer by 16 words instead of 16 compat_uptr_t. > > Signed-off-by: Christoph Berg <myon@debian.org> > Suggested-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Likely we want a Fixes: and then this is probably "Reported-by:" paired with a "Closes:" link to any such report. But I'm wondering how long this has already been like that. :) > --- > mm/migrate.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/mm/migrate.c b/mm/migrate.c > index 8cf0f9c9599..542c81ec3ed 100644 > --- a/mm/migrate.c > +++ b/mm/migrate.c > @@ -2444,7 +2444,13 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, > if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status))) > break; > > - pages += chunk_nr; > + if (in_compat_syscall()) { > + compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages; > + > + pages32 += chunk_nr; > + pages = (const void __user * __user *) pages32; > + } else > + pages += chunk_nr; > status += chunk_nr; > nr_pages -= chunk_nr; > } Something a bit more elegant might be: diff --git a/mm/migrate.c b/mm/migrate.c index ea8c74d996592..fc99448771041 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -2398,6 +2398,7 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages, static int get_compat_pages_array(const void __user *chunk_pages[], const void __user * __user *pages, + unsigned long chunk_offs, unsigned long chunk_nr) { compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages; @@ -2405,7 +2406,7 @@ static int get_compat_pages_array(const void __user *chunk_pages[], int i; for (i = 0; i < chunk_nr; i++) { - if (get_user(p, pages32 + i)) + if (get_user(p, pages32 + i + chunk_offs)) return -EFAULT; chunk_pages[i] = compat_ptr(p); } @@ -2424,13 +2425,14 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, #define DO_PAGES_STAT_CHUNK_NR 16UL const void __user *chunk_pages[DO_PAGES_STAT_CHUNK_NR]; int chunk_status[DO_PAGES_STAT_CHUNK_NR]; + unsigned long chunk_offs = 0; while (nr_pages) { unsigned long chunk_nr = min(nr_pages, DO_PAGES_STAT_CHUNK_NR); if (in_compat_syscall()) { if (get_compat_pages_array(chunk_pages, pages, - chunk_nr)) + chunk_offs, chunk_nr)) break; } else { if (copy_from_user(chunk_pages, pages, @@ -2440,11 +2442,11 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); - if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status))) + if (copy_to_user(status + chunk_offs, chunk_status, + chunk_nr * sizeof(*status))) break; - pages += chunk_nr; - status += chunk_nr; + chunk_offs += chunk_nr; nr_pages -= chunk_nr; } return nr_pages ? -EFAULT : 0; (untested, of course) -- Cheers, David / dhildenb ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2] mm/migrate: Fix do_pages_stat in 32-bit mode 2025-06-25 15:42 ` David Hildenbrand @ 2025-07-01 16:58 ` Christoph Berg 2025-07-01 17:09 ` Zi Yan 0 siblings, 1 reply; 12+ messages in thread From: Christoph Berg @ 2025-07-01 16:58 UTC (permalink / raw) To: David Hildenbrand, Andrew Morton Cc: Zi Yan, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list Re: David Hildenbrand > Subject should start with "mm/migrate:" > Likely we want a > Fixes: > and then this is probably "Reported-by:" paired with a "Closes:" link > to any such report. I included these now, except for "Closes:" which I have to idea what to put in. > But I'm wondering how long this has already been like that. :) The now-offending "pages += chunk_nr" line is from 2010, but I think the bug is rather from 5b1b561ba73c8ab9c98e5dfd14dc7ee47efb6530 (2021) which reshuffled the array-vs-32-bit handling. > Something a bit more elegant might be: Thanks, I used your patch draft with some minor changes. > static int get_compat_pages_array(const void __user *chunk_pages[], > const void __user * __user *pages, > + unsigned long chunk_offs, I replaced chunk_offs with "chunk_offset" since "offs" looked too much like plural (list of offsets) to me. > if (in_compat_syscall()) { > if (get_compat_pages_array(chunk_pages, pages, > - chunk_nr)) > + chunk_offs, chunk_nr)) > break; > } else { > if (copy_from_user(chunk_pages, pages, The else branch here needs tweaking as well: } else { - if (copy_from_user(chunk_pages, pages, + if (copy_from_user(chunk_pages, pages + chunk_offset, chunk_nr * sizeof(*chunk_pages))) > @@ -2440,11 +2442,11 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, > do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); > - if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status))) > + if (copy_to_user(status + chunk_offs, chunk_status, > + chunk_nr * sizeof(*status))) This seems to work, but honestly I am wondering, if copy_from_user needs a special 32-bit case, doesn't copy_to_user need special casing as well? > (untested, of course) The attached patch makes PG18's new numa test pass on amd64 kernels both in amd64 and i386 userlands. (In the meantime, PG git head got a workaround that limits the chunk size to the same 16 as used in do_pages_stat; I tested with the version before that.) Christoph From fdbcbc88825bc2e857dfeeebc91d62864e0774dd Mon Sep 17 00:00:00 2001 From: Christoph Berg <myon@debian.org> Date: Tue, 24 Jun 2025 16:44:27 +0200 Subject: [PATCH v2] mm/migrate: Fix do_pages_stat in 32-bit mode For arrays with more than 16 entries, the old code would incorrectly advance the pages pointer by 16 words instead of 16 compat_uptr_t. Fix by doing the pointer arithmetic inside get_compat_pages_array where pages32 is already a correctly-typed pointer. Discovered while working on PostgreSQL 18's new NUMA introspection code. Signed-off-by: Christoph Berg <myon@debian.org> Reported-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Reported-by: Tomas Vondra <tomas@vondra.me> Suggested-by: David Hildenbrand <david@redhat.com> Fixes: 5b1b561ba73c8ab9c98e5dfd14dc7ee47efb6530 --- mm/migrate.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index 8cf0f9c9599d..2c88f3b33833 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -2399,6 +2399,7 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages, static int get_compat_pages_array(const void __user *chunk_pages[], const void __user * __user *pages, + unsigned long chunk_offset, unsigned long chunk_nr) { compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages; @@ -2406,7 +2407,7 @@ static int get_compat_pages_array(const void __user *chunk_pages[], int i; for (i = 0; i < chunk_nr; i++) { - if (get_user(p, pages32 + i)) + if (get_user(p, pages32 + chunk_offset + i)) return -EFAULT; chunk_pages[i] = compat_ptr(p); } @@ -2425,27 +2426,28 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, #define DO_PAGES_STAT_CHUNK_NR 16UL const void __user *chunk_pages[DO_PAGES_STAT_CHUNK_NR]; int chunk_status[DO_PAGES_STAT_CHUNK_NR]; + unsigned long chunk_offset = 0; while (nr_pages) { unsigned long chunk_nr = min(nr_pages, DO_PAGES_STAT_CHUNK_NR); if (in_compat_syscall()) { if (get_compat_pages_array(chunk_pages, pages, - chunk_nr)) + chunk_offset, chunk_nr)) break; } else { - if (copy_from_user(chunk_pages, pages, + if (copy_from_user(chunk_pages, pages + chunk_offset, chunk_nr * sizeof(*chunk_pages))) break; } do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); - if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status))) + if (copy_to_user(status + chunk_offset, chunk_status, + chunk_nr * sizeof(*status))) break; - pages += chunk_nr; - status += chunk_nr; + chunk_offset += chunk_nr; nr_pages -= chunk_nr; } return nr_pages ? -EFAULT : 0; -- 2.47.2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] mm/migrate: Fix do_pages_stat in 32-bit mode 2025-07-01 16:58 ` [PATCH v2] mm/migrate: Fix do_pages_stat in 32-bit mode Christoph Berg @ 2025-07-01 17:09 ` Zi Yan 2025-07-01 17:55 ` [PATCH v3] " Christoph Berg 0 siblings, 1 reply; 12+ messages in thread From: Zi Yan @ 2025-07-01 17:09 UTC (permalink / raw) To: Christoph Berg Cc: David Hildenbrand, Andrew Morton, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list On 1 Jul 2025, at 12:58, Christoph Berg wrote: > Re: David Hildenbrand >> Subject should start with "mm/migrate:" >> Likely we want a >> Fixes: >> and then this is probably "Reported-by:" paired with a "Closes:" link >> to any such report. > > I included these now, except for "Closes:" which I have to idea what > to put in. Fixes should be: Fixes: 5b1b561ba73c ("mm: simplify compat_sys_move_pages") Closes could be a link to the bug report. > >> But I'm wondering how long this has already been like that. :) > > The now-offending "pages += chunk_nr" line is from 2010, but I think > the bug is rather from 5b1b561ba73c8ab9c98e5dfd14dc7ee47efb6530 (2021) > which reshuffled the array-vs-32-bit handling. > >> Something a bit more elegant might be: > > Thanks, I used your patch draft with some minor changes. > >> static int get_compat_pages_array(const void __user *chunk_pages[], >> const void __user * __user *pages, >> + unsigned long chunk_offs, > > I replaced chunk_offs with "chunk_offset" since "offs" looked too much > like plural (list of offsets) to me. > >> if (in_compat_syscall()) { >> if (get_compat_pages_array(chunk_pages, pages, >> - chunk_nr)) >> + chunk_offs, chunk_nr)) >> break; >> } else { >> if (copy_from_user(chunk_pages, pages, > > The else branch here needs tweaking as well: > > } else { > - if (copy_from_user(chunk_pages, pages, > + if (copy_from_user(chunk_pages, pages + chunk_offset, > chunk_nr * sizeof(*chunk_pages))) > > >> @@ -2440,11 +2442,11 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, >> do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); >> - if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status))) >> + if (copy_to_user(status + chunk_offs, chunk_status, >> + chunk_nr * sizeof(*status))) > > This seems to work, but honestly I am wondering, if copy_from_user > needs a special 32-bit case, doesn't copy_to_user need special casing > as well? > >> (untested, of course) > > The attached patch makes PG18's new numa test pass on amd64 kernels > both in amd64 and i386 userlands. > > (In the meantime, PG git head got a workaround that limits the chunk > size to the same 16 as used in do_pages_stat; I tested with the > version before that.) > > Christoph > > > From fdbcbc88825bc2e857dfeeebc91d62864e0774dd Mon Sep 17 00:00:00 2001 > From: Christoph Berg <myon@debian.org> > Date: Tue, 24 Jun 2025 16:44:27 +0200 > Subject: [PATCH v2] mm/migrate: Fix do_pages_stat in 32-bit mode > > For arrays with more than 16 entries, the old code would incorrectly > advance the pages pointer by 16 words instead of 16 compat_uptr_t. > Fix by doing the pointer arithmetic inside get_compat_pages_array where > pages32 is already a correctly-typed pointer. > > Discovered while working on PostgreSQL 18's new NUMA introspection code. > > Signed-off-by: Christoph Berg <myon@debian.org> > Reported-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> > Reported-by: Tomas Vondra <tomas@vondra.me> > Suggested-by: David Hildenbrand <david@redhat.com> > Fixes: 5b1b561ba73c8ab9c98e5dfd14dc7ee47efb6530 > --- > mm/migrate.c | 14 ++++++++------ > 1 file changed, 8 insertions(+), 6 deletions(-) > > diff --git a/mm/migrate.c b/mm/migrate.c > index 8cf0f9c9599d..2c88f3b33833 100644 > --- a/mm/migrate.c > +++ b/mm/migrate.c > @@ -2399,6 +2399,7 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages, > > static int get_compat_pages_array(const void __user *chunk_pages[], > const void __user * __user *pages, > + unsigned long chunk_offset, > unsigned long chunk_nr) > { > compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages; > @@ -2406,7 +2407,7 @@ static int get_compat_pages_array(const void __user *chunk_pages[], > int i; > > for (i = 0; i < chunk_nr; i++) { > - if (get_user(p, pages32 + i)) > + if (get_user(p, pages32 + chunk_offset + i)) > return -EFAULT; > chunk_pages[i] = compat_ptr(p); > } > @@ -2425,27 +2426,28 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, > #define DO_PAGES_STAT_CHUNK_NR 16UL > const void __user *chunk_pages[DO_PAGES_STAT_CHUNK_NR]; > int chunk_status[DO_PAGES_STAT_CHUNK_NR]; > + unsigned long chunk_offset = 0; > > while (nr_pages) { > unsigned long chunk_nr = min(nr_pages, DO_PAGES_STAT_CHUNK_NR); > > if (in_compat_syscall()) { > if (get_compat_pages_array(chunk_pages, pages, > - chunk_nr)) > + chunk_offset, chunk_nr)) > break; > } else { > - if (copy_from_user(chunk_pages, pages, > + if (copy_from_user(chunk_pages, pages + chunk_offset, > chunk_nr * sizeof(*chunk_pages))) > break; > } > > do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); > > - if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status))) > + if (copy_to_user(status + chunk_offset, chunk_status, > + chunk_nr * sizeof(*status))) > break; > > - pages += chunk_nr; > - status += chunk_nr; > + chunk_offset += chunk_nr; > nr_pages -= chunk_nr; > } > return nr_pages ? -EFAULT : 0; > -- > 2.47.2 Best Regards, Yan, Zi ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3] mm/migrate: Fix do_pages_stat in 32-bit mode 2025-07-01 17:09 ` Zi Yan @ 2025-07-01 17:55 ` Christoph Berg 2025-07-01 18:17 ` David Hildenbrand 0 siblings, 1 reply; 12+ messages in thread From: Christoph Berg @ 2025-07-01 17:55 UTC (permalink / raw) To: Zi Yan Cc: David Hildenbrand, Andrew Morton, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list Re: Zi Yan > Fixes should be: > > Fixes: 5b1b561ba73c ("mm: simplify compat_sys_move_pages") > > Closes could be a link to the bug report. Updated, thanks. > > This seems to work, but honestly I am wondering, if copy_from_user > > needs a special 32-bit case, doesn't copy_to_user need special casing > > as well? Scratch that, it works because an int[] is copied back, and that's always the same size. So I think the patch is good to go. Christoph From 426c93d558572248273cf386ca784626ae431413 Mon Sep 17 00:00:00 2001 From: Christoph Berg <myon@debian.org> Date: Tue, 24 Jun 2025 16:44:27 +0200 Subject: [PATCH v3] mm/migrate: Fix do_pages_stat in 32-bit mode For arrays with more than 16 entries, the old code would incorrectly advance the pages pointer by 16 words instead of 16 compat_uptr_t. Fix by doing the pointer arithmetic inside get_compat_pages_array where pages32 is already a correctly-typed pointer. Discovered while working on PostgreSQL 18's new NUMA introspection code. Signed-off-by: Christoph Berg <myon@debian.org> Suggested-by: David Hildenbrand <david@redhat.com> Fixes: 5b1b561ba73c ("mm: simplify compat_sys_move_pages") Reported-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Reported-by: Tomas Vondra <tomas@vondra.me> Closes: https://www.postgresql.org/message-id/flat/6342f601-77de-4ee0-8c2a-3deb50ceac5b%40vondra.me#86402e3d80c031788f5f55b42c459471 --- mm/migrate.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index 8cf0f9c9599d..2c88f3b33833 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -2399,6 +2399,7 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages, static int get_compat_pages_array(const void __user *chunk_pages[], const void __user * __user *pages, + unsigned long chunk_offset, unsigned long chunk_nr) { compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages; @@ -2406,7 +2407,7 @@ static int get_compat_pages_array(const void __user *chunk_pages[], int i; for (i = 0; i < chunk_nr; i++) { - if (get_user(p, pages32 + i)) + if (get_user(p, pages32 + chunk_offset + i)) return -EFAULT; chunk_pages[i] = compat_ptr(p); } @@ -2425,27 +2426,28 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, #define DO_PAGES_STAT_CHUNK_NR 16UL const void __user *chunk_pages[DO_PAGES_STAT_CHUNK_NR]; int chunk_status[DO_PAGES_STAT_CHUNK_NR]; + unsigned long chunk_offset = 0; while (nr_pages) { unsigned long chunk_nr = min(nr_pages, DO_PAGES_STAT_CHUNK_NR); if (in_compat_syscall()) { if (get_compat_pages_array(chunk_pages, pages, - chunk_nr)) + chunk_offset, chunk_nr)) break; } else { - if (copy_from_user(chunk_pages, pages, + if (copy_from_user(chunk_pages, pages + chunk_offset, chunk_nr * sizeof(*chunk_pages))) break; } do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); - if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status))) + if (copy_to_user(status + chunk_offset, chunk_status, + chunk_nr * sizeof(*status))) break; - pages += chunk_nr; - status += chunk_nr; + chunk_offset += chunk_nr; nr_pages -= chunk_nr; } return nr_pages ? -EFAULT : 0; -- 2.47.2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3] mm/migrate: Fix do_pages_stat in 32-bit mode 2025-07-01 17:55 ` [PATCH v3] " Christoph Berg @ 2025-07-01 18:17 ` David Hildenbrand 2025-07-03 17:39 ` Christoph Berg 0 siblings, 1 reply; 12+ messages in thread From: David Hildenbrand @ 2025-07-01 18:17 UTC (permalink / raw) To: Christoph Berg, Zi Yan Cc: Andrew Morton, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list On 01.07.25 19:55, Christoph Berg wrote: > Re: Zi Yan >> Fixes should be: >> >> Fixes: 5b1b561ba73c ("mm: simplify compat_sys_move_pages") >> >> Closes could be a link to the bug report. > > Updated, thanks. > >>> This seems to work, but honestly I am wondering, if copy_from_user >>> needs a special 32-bit case, doesn't copy_to_user need special casing >>> as well? > > Scratch that, it works because an int[] is copied back, and that's > always the same size. > > So I think the patch is good to go. > > Christoph > > If you have to resend, next time resend the full patch separately, not as reply to the previous version. > From 426c93d558572248273cf386ca784626ae431413 Mon Sep 17 00:00:00 2001 > From: Christoph Berg <myon@debian.org> > Date: Tue, 24 Jun 2025 16:44:27 +0200 > Subject: [PATCH v3] mm/migrate: Fix do_pages_stat in 32-bit mode s/32-bit mode/compat mode/ ? Because on native 32bit it should be working fine. > > For arrays with more than 16 entries, the old code would incorrectly > advance the pages pointer by 16 words instead of 16 compat_uptr_t. > Fix by doing the pointer arithmetic inside get_compat_pages_array where > pages32 is already a correctly-typed pointer. > > Discovered while working on PostgreSQL 18's new NUMA introspection code. > > Signed-off-by: Christoph Berg <myon@debian.org> > Suggested-by: David Hildenbrand <david@redhat.com> > Fixes: 5b1b561ba73c ("mm: simplify compat_sys_move_pages") Hmm, still not sure if 5b1b561ba73c really introduced the issue. I think it only messed with the "pages" pointer, not with the "status" pointer? Hmmmm I assume we want to Cc stable. @Andrew can do that. > Reported-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> > Reported-by: Tomas Vondra <tomas@vondra.me> > Closes: https://www.postgresql.org/message-id/flat/6342f601-77de-4ee0-8c2a-3deb50ceac5b%40vondra.me#86402e3d80c031788f5f55b42c459471 > --- Acked-by: David Hildenbrand <david@redhat.com> -- Cheers, David / dhildenb ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3] mm/migrate: Fix do_pages_stat in 32-bit mode 2025-07-01 18:17 ` David Hildenbrand @ 2025-07-03 17:39 ` Christoph Berg 0 siblings, 0 replies; 12+ messages in thread From: Christoph Berg @ 2025-07-03 17:39 UTC (permalink / raw) To: David Hildenbrand Cc: Zi Yan, Andrew Morton, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list Re: David Hildenbrand > > For arrays with more than 16 entries, the old code would incorrectly > > advance the pages pointer by 16 words instead of 16 compat_uptr_t. > > Fix by doing the pointer arithmetic inside get_compat_pages_array where > > pages32 is already a correctly-typed pointer. > > > > Discovered while working on PostgreSQL 18's new NUMA introspection code. > > > > Signed-off-by: Christoph Berg <myon@debian.org> > > Suggested-by: David Hildenbrand <david@redhat.com> > > Fixes: 5b1b561ba73c ("mm: simplify compat_sys_move_pages") > > Hmm, still not sure if 5b1b561ba73c really introduced the issue. I think it > only messed with the "pages" pointer, not with the "status" pointer? "pages" was the broken one. "status" isn't affected by compat mode. > Acked-by: David Hildenbrand <david@redhat.com> Thanks! Christoph ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Fix do_pages_stat to use compat_uptr_t 2025-06-25 15:24 ` [PATCH] Fix do_pages_stat to use compat_uptr_t Christoph Berg 2025-06-25 15:42 ` David Hildenbrand @ 2025-06-25 20:39 ` Andrew Morton 2025-06-25 21:10 ` Christoph Berg 1 sibling, 1 reply; 12+ messages in thread From: Andrew Morton @ 2025-06-25 20:39 UTC (permalink / raw) To: Christoph Berg Cc: David Hildenbrand, Zi Yan, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list On Wed, 25 Jun 2025 17:24:14 +0200 Christoph Berg <myon@debian.org> wrote: > For arrays with more than 16 entries, the old code would incorrectly > advance the pages pointer by 16 words instead of 16 compat_uptr_t. > > ... > > --- a/mm/migrate.c > +++ b/mm/migrate.c > @@ -2444,7 +2444,13 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, > if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status))) > break; > > - pages += chunk_nr; > + if (in_compat_syscall()) { > + compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages; > + > + pages32 += chunk_nr; > + pages = (const void __user * __user *) pages32; > + } else > + pages += chunk_nr; > status += chunk_nr; > nr_pages -= chunk_nr; > } Seems this has been present since 2010. I'll update the Subject: as David suggests and I'll add a cc:stable, thanks. I'll also add a note that David suggested an alternative, so please let's advance that option. Also, a coding-style tweak: --- a/mm/migrate.c~fix-do_pages_stat-to-use-compat_uptr_t-fix +++ a/mm/migrate.c @@ -2449,8 +2449,9 @@ static int do_pages_stat(struct mm_struc pages32 += chunk_nr; pages = (const void __user * __user *) pages32; - } else + } else { pages += chunk_nr; + } status += chunk_nr; nr_pages -= chunk_nr; } _ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Fix do_pages_stat to use compat_uptr_t 2025-06-25 20:39 ` [PATCH] Fix do_pages_stat to use compat_uptr_t Andrew Morton @ 2025-06-25 21:10 ` Christoph Berg 2025-06-25 21:15 ` Andrew Morton 0 siblings, 1 reply; 12+ messages in thread From: Christoph Berg @ 2025-06-25 21:10 UTC (permalink / raw) To: Andrew Morton Cc: David Hildenbrand, Zi Yan, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list Re: Andrew Morton > I'll update the Subject: as David suggests and I'll add a cc:stable, > thanks. I'll also add a note that David suggested an alternative, so > please let's advance that option. Sorry, I'm new here. Do I have to do anything now? The above sounds like the alternative coding by David would be preferred, but the other mails say the patches have already been pushed to a hotfix branch? Or are we doing both, i.e. stable gets the simple fix and next the pretty one? Christoph ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Fix do_pages_stat to use compat_uptr_t 2025-06-25 21:10 ` Christoph Berg @ 2025-06-25 21:15 ` Andrew Morton 2025-06-26 8:16 ` David Hildenbrand 0 siblings, 1 reply; 12+ messages in thread From: Andrew Morton @ 2025-06-25 21:15 UTC (permalink / raw) To: Christoph Berg Cc: David Hildenbrand, Zi Yan, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list On Wed, 25 Jun 2025 23:10:13 +0200 Christoph Berg <myon@debian.org> wrote: > Re: Andrew Morton > > I'll update the Subject: as David suggests and I'll add a cc:stable, > > thanks. I'll also add a note that David suggested an alternative, so > > please let's advance that option. > > Sorry, I'm new here. Do I have to do anything now? The above sounds > like the alternative coding by David would be preferred, but the other > mails say the patches have already been pushed to a hotfix branch? Or > are we doing both, i.e. stable gets the simple fix and next the pretty > one? Well I added the v1 patch for testing and so it doesn't get lost - fixing the bug is the most important thing. But if a nicer v2 patch is sent in the next few days, I can switch to that version. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Fix do_pages_stat to use compat_uptr_t 2025-06-25 21:15 ` Andrew Morton @ 2025-06-26 8:16 ` David Hildenbrand 2025-06-26 19:21 ` Christoph Berg 0 siblings, 1 reply; 12+ messages in thread From: David Hildenbrand @ 2025-06-26 8:16 UTC (permalink / raw) To: Andrew Morton, Christoph Berg Cc: Zi Yan, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list On 25.06.25 23:15, Andrew Morton wrote: > On Wed, 25 Jun 2025 23:10:13 +0200 Christoph Berg <myon@debian.org> wrote: > >> Re: Andrew Morton >>> I'll update the Subject: as David suggests and I'll add a cc:stable, >>> thanks. I'll also add a note that David suggested an alternative, so >>> please let's advance that option. >> >> Sorry, I'm new here. Do I have to do anything now? The above sounds >> like the alternative coding by David would be preferred See if my proposal makes sense, and then incorporate+test it. You can feel free to add my Suggested-by: David Hildenbrand <david@redhat.com> -- Cheers, David / dhildenb ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Fix do_pages_stat to use compat_uptr_t 2025-06-26 8:16 ` David Hildenbrand @ 2025-06-26 19:21 ` Christoph Berg 0 siblings, 0 replies; 12+ messages in thread From: Christoph Berg @ 2025-06-26 19:21 UTC (permalink / raw) To: David Hildenbrand Cc: Andrew Morton, Zi Yan, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, Gregory Price, Ying Huang, Alistair Popple, open list:MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION, open list Re: David Hildenbrand > See if my proposal makes sense, and then incorporate+test it. > > You can feel free to add my > > Suggested-by: David Hildenbrand <david@redhat.com> Thanks, will do. But it will be next week, currently busy with the ham radio fair in Friedrichshafen. Christoph ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-07-03 17:39 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <aFrBhyHQFffJ4xgX@msg.df7cb.de>
[not found] ` <d42cc185-b774-4d5e-9a51-0581dd5f3962@arm.com>
2025-06-25 15:24 ` [PATCH] Fix do_pages_stat to use compat_uptr_t Christoph Berg
2025-06-25 15:42 ` David Hildenbrand
2025-07-01 16:58 ` [PATCH v2] mm/migrate: Fix do_pages_stat in 32-bit mode Christoph Berg
2025-07-01 17:09 ` Zi Yan
2025-07-01 17:55 ` [PATCH v3] " Christoph Berg
2025-07-01 18:17 ` David Hildenbrand
2025-07-03 17:39 ` Christoph Berg
2025-06-25 20:39 ` [PATCH] Fix do_pages_stat to use compat_uptr_t Andrew Morton
2025-06-25 21:10 ` Christoph Berg
2025-06-25 21:15 ` Andrew Morton
2025-06-26 8:16 ` David Hildenbrand
2025-06-26 19:21 ` Christoph Berg
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®