Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix -Wstringop-overflow warnings in arch/x86/mm/pgtable.c (GCC-11) #203

Closed
GustavoARSilva opened this issue Sep 21, 2022 · 1 comment
Closed
Assignees
Labels
[Build] Global flag [PATCH] Accepted A submitted patch has been accepted upstream

Comments

@GustavoARSilva
Copy link
Collaborator

We need to address the following warnings in arch/x86/mm/pgtable.c before we can enable -Wstriongop-overflow globally:

  CC      arch/x86/mm/pgtable.o
arch/x86/mm/pgtable.c: In function ‘pgd_alloc’:
arch/x86/mm/pgtable.c:437:13: warning: ‘preallocate_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
  437 |         if (preallocate_pmds(mm, pmds, PREALLOCATED_PMDS) != 0)
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/x86/mm/pgtable.c:437:13: note: referencing argument 2 of type ‘pmd_t **’
arch/x86/mm/pgtable.c:225:12: note: in a call to function ‘preallocate_pmds.constprop’
  225 | static int preallocate_pmds(struct mm_struct *mm, pmd_t *pmds[], int count)
      |            ^~~~~~~~~~~~~~~~
arch/x86/mm/pgtable.c:440:13: warning: ‘preallocate_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
  440 |         if (preallocate_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS) != 0)
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/x86/mm/pgtable.c:440:13: note: referencing argument 2 of type ‘pmd_t **’
arch/x86/mm/pgtable.c:225:12: note: in a call to function ‘preallocate_pmds.constprop’
  225 | static int preallocate_pmds(struct mm_struct *mm, pmd_t *pmds[], int count)
      |            ^~~~~~~~~~~~~~~~
arch/x86/mm/pgtable.c:462:9: warning: ‘free_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
  462 |         free_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/x86/mm/pgtable.c:462:9: note: referencing argument 2 of type ‘pmd_t **’
arch/x86/mm/pgtable.c:213:13: note: in a call to function ‘free_pmds.constprop’
  213 | static void free_pmds(struct mm_struct *mm, pmd_t *pmds[], int count)
      |             ^~~~~~~~~
arch/x86/mm/pgtable.c:455:9: warning: ‘pgd_prepopulate_user_pmd’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
  455 |         pgd_prepopulate_user_pmd(mm, pgd, u_pmds);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/x86/mm/pgtable.c:455:9: note: referencing argument 3 of type ‘pmd_t **’
arch/x86/mm/pgtable.c:320:13: note: in a call to function ‘pgd_prepopulate_user_pmd’
  320 | static void pgd_prepopulate_user_pmd(struct mm_struct *mm,
      |             ^~~~~~~~~~~~~~~~~~~~~~~~
arch/x86/mm/pgtable.c:464:9: warning: ‘free_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
  464 |         free_pmds(mm, pmds, PREALLOCATED_PMDS);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/x86/mm/pgtable.c:464:9: note: referencing argument 2 of type ‘pmd_t **’
arch/x86/mm/pgtable.c:213:13: note: in a call to function ‘free_pmds.constprop’
  213 | static void free_pmds(struct mm_struct *mm, pmd_t *pmds[], int count)
      |             ^~~~~~~~~
@GustavoARSilva GustavoARSilva self-assigned this Sep 21, 2022
@GustavoARSilva GustavoARSilva added the [PATCH] Exists A patch exists to address the issue label Oct 6, 2022
@GustavoARSilva
Copy link
Collaborator Author

intel-lab-lkp pushed a commit to intel-lab-lkp/linux that referenced this issue Nov 28, 2022
The actual size of the following arrays at run-time depends on
CONFIG_X86_PAE.

427         pmd_t *u_pmds[MAX_PREALLOCATED_USER_PMDS];
428         pmd_t *pmds[MAX_PREALLOCATED_PMDS];

If CONFIG_X86_PAE is not enabled, their final size will be zero (which
is technically not a legal storage size in C, but remains "valid" via
the GNU extension). In that case, the compiler complains about trying to
access objects of size zero when calling functions where these objects
are passed as arguments.

Fix this by sanity-checking the size of those arrays just before the
function calls. Also, the following warnings are fixed by these changes
when building with GCC 11+ and -Wstringop-overflow enabled:

arch/x86/mm/pgtable.c:437:13: warning: ‘preallocate_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
arch/x86/mm/pgtable.c:440:13: warning: ‘preallocate_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
arch/x86/mm/pgtable.c:462:9: warning: ‘free_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
arch/x86/mm/pgtable.c:455:9: warning: ‘pgd_prepopulate_user_pmd’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
arch/x86/mm/pgtable.c:464:9: warning: ‘free_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]

This is one of the last cases in the ongoing effort to globally enable
-Wstringop-overflow.

The alternative to this is to make the originally suggested change:
make the pmds argument from an array pointer to a pointer pointer. That
situation is considered "legal" for C in the sense that it does not have
a way to reason about the storage. i.e.:

-static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
+static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmds)

With the above change, there's no difference in binary output, and the
compiler warning is silenced.

However, with this patch, the compiler can actually figure out that it
isn't using the code at all, and it gets dropped:

   text    data     bss     dec     hex filename
   8218     718      32    8968    2308 arch/x86/mm/pgtable.o.before
   7765     694      32    8491    212b arch/x86/mm/pgtable.o.after

So this case (fixing a warning and reducing image size) is a clear win.

Additionally drops an old work-around for GCC in the same code.

Link: KSPP#203
Link: KSPP#181
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/Yytb67xvrnctxnEe@work
@kees kees added [PATCH] Accepted A submitted patch has been accepted upstream and removed [PATCH] Exists A patch exists to address the issue labels Nov 30, 2022
mj22226 pushed a commit to mj22226/linux that referenced this issue Dec 2, 2022
The actual size of the following arrays at run-time depends on
CONFIG_X86_PAE.

427         pmd_t *u_pmds[MAX_PREALLOCATED_USER_PMDS];
428         pmd_t *pmds[MAX_PREALLOCATED_PMDS];

If CONFIG_X86_PAE is not enabled, their final size will be zero (which
is technically not a legal storage size in C, but remains "valid" via
the GNU extension). In that case, the compiler complains about trying to
access objects of size zero when calling functions where these objects
are passed as arguments.

Fix this by sanity-checking the size of those arrays just before the
function calls. Also, the following warnings are fixed by these changes
when building with GCC 11+ and -Wstringop-overflow enabled:

arch/x86/mm/pgtable.c:437:13: warning: ‘preallocate_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
arch/x86/mm/pgtable.c:440:13: warning: ‘preallocate_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
arch/x86/mm/pgtable.c:462:9: warning: ‘free_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
arch/x86/mm/pgtable.c:455:9: warning: ‘pgd_prepopulate_user_pmd’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
arch/x86/mm/pgtable.c:464:9: warning: ‘free_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]

This is one of the last cases in the ongoing effort to globally enable
-Wstringop-overflow.

The alternative to this is to make the originally suggested change:
make the pmds argument from an array pointer to a pointer pointer. That
situation is considered "legal" for C in the sense that it does not have
a way to reason about the storage. i.e.:

-static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
+static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmds)

With the above change, there's no difference in binary output, and the
compiler warning is silenced.

However, with this patch, the compiler can actually figure out that it
isn't using the code at all, and it gets dropped:

   text    data     bss     dec     hex filename
   8218     718      32    8968    2308 arch/x86/mm/pgtable.o.before
   7765     694      32    8491    212b arch/x86/mm/pgtable.o.after

So this case (fixing a warning and reducing image size) is a clear win.

Additionally drops an old work-around for GCC in the same code.

Link: KSPP#203
Link: KSPP#181
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/Yytb67xvrnctxnEe@work
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Build] Global flag [PATCH] Accepted A submitted patch has been accepted upstream
Projects
None yet
Development

No branches or pull requests

2 participants