linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Zi Yan <ziy@nvidia.com>
To: Dan Carpenter <dan.carpenter@linaro.org>
Cc: linux-mm@kvack.org
Subject: Re: [bug report] mm: huge_memory: enable debugfs to split huge pages to any order
Date: Thu, 07 Mar 2024 09:20:09 -0500	[thread overview]
Message-ID: <4EFF8F91-5B42-4E90-BFBB-FBA8DAAB8301@nvidia.com> (raw)
In-Reply-To: <7dda9283-b437-4cf8-ab0d-83c330deb9c0@moroto.mountain>

[-- Attachment #1: Type: text/plain, Size: 4473 bytes --]

On 7 Mar 2024, at 8:49, Dan Carpenter wrote:

> Hello Zi Yan,
>
> Commit fc4d182316bd ("mm: huge_memory: enable debugfs to split huge
> pages to any order") from Feb 26, 2024 (linux-next), leads to the
> following Smatch static checker warning:
>
> 	mm/huge_memory.c:2898 __split_huge_page()
> 	error: undefined (user controlled) shift '1 << new_order'
>
> mm/huge_memory.c
>     2889 static void __split_huge_page(struct page *page, struct list_head *list,
>     2890                 pgoff_t end, unsigned int new_order)
>     2891 {
>     2892         struct folio *folio = page_folio(page);
>     2893         struct page *head = &folio->page;
>     2894         struct lruvec *lruvec;
>     2895         struct address_space *swap_cache = NULL;
>     2896         unsigned long offset = 0;
>     2897         int i, nr_dropped = 0;
> --> 2898         unsigned int new_nr = 1 << new_order;
>                                             ^^^^^^^^^
> The new_order variable comes from the user via debugfs.
>
>     2899         int order = folio_order(folio);
>     2900         unsigned int nr = 1 << order;
>     2901
>     2902         /* complete memcg works before add pages to LRU */
>     2903         split_page_memcg(head, order, new_order);
>     2904
>     2905         if (folio_test_anon(folio) && folio_test_swapcache(folio)) {
>     2906                 offset = swp_offset(folio->swap);
>     2907                 swap_cache = swap_address_space(folio->swap);
>
> Here is the debugfs code in split_huge_pages_write()
>
> mm/huge_memory.c
>   3628
>   3629          ret = sscanf(input_buf, "%d,0x%lx,0x%lx,%d", &pid, &vaddr_start, &vaddr_end, &new_order);
>                                                                                              ^^^^^^^^^^
> We just read new_order
>
>   3630          if (ret == 1 && pid == 1) {
>   3631                  split_huge_pages_all();
>   3632                  ret = strlen(input_buf);
>   3633                  goto out;
>   3634          } else if (ret != 3 && ret != 4) {
>   3635                  ret = -EINVAL;
>   3636                  goto out;
>   3637          }
>   3638
>   3639          ret = split_huge_pages_pid(pid, vaddr_start, vaddr_end, new_order);
>                                                                         ^^^^^^^^^
> And pass it directly with no bounds checking.  Debugfs code is root
> only...  We used to take a view that if root does something stupid then
> they get what they deserve.  But these days syzbot is fuzz testing stuff
> even when it's root only and complaining about shift wraps or other
> undefined behavior.  So I feel like it might be easiest to silence this
> undefined behavior warning now instead of waiting for the syzbot reports
> to come back to bite us in a couple years.

Sure. Thank you for reporting this.

Can you check if the patch below fixes the issue? I checked the inputs from
debugfs and also inside split_huge_page_to_list_to_order().

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index a81a09236c16..4d21e57a7d07 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3052,6 +3052,9 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
        VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
        VM_BUG_ON_FOLIO(!folio_test_large(folio), folio);

+       if (new_order >= folio_order(folio))
+               return -EINVAL;
+
        /* Cannot split anonymous THP to order-1 */
        if (new_order == 1 && folio_test_anon(folio)) {
                VM_WARN_ONCE(1, "Cannot split to order-1 folio");
@@ -3484,6 +3487,9 @@ static int split_huge_pages_pid(int pid, unsigned long vaddr_start,
                        goto next;

                total++;
+
+               if (new_order >= folio_order(folio))
+                       goto next;
                /*
                 * For folios with private, split_huge_page_to_list_to_order()
                 * will try to drop it before split and then check if the folio
@@ -3550,6 +3556,9 @@ static int split_huge_pages_in_file(const char *file_path, pgoff_t off_start,
                total++;
                nr_pages = folio_nr_pages(folio);

+               if (new_order >= folio_order(folio))
+                       goto next;
+
                if (!folio_trylock(folio))
                        goto next;
--
Best Regards,
Yan, Zi

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 854 bytes --]

  reply	other threads:[~2024-03-07 14:20 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-07 13:49 [bug report] mm: huge_memory: enable debugfs to split huge pages to any order Dan Carpenter
2024-03-07 14:20 ` Zi Yan [this message]
2024-03-07 14:31   ` Dan Carpenter
2024-03-07 14:41     ` Zi Yan
2024-03-07 14:44       ` Dan Carpenter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4EFF8F91-5B42-4E90-BFBB-FBA8DAAB8301@nvidia.com \
    --to=ziy@nvidia.com \
    --cc=dan.carpenter@linaro.org \
    --cc=linux-mm@kvack.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).