Skip to content

Commit 25226df

Browse files
GustavoARSilvakees
authored andcommitted
mm/pgtable: Fix multiple -Wstringop-overflow warnings
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 <[email protected]> Reviewed-by: Kees Cook <[email protected]> Signed-off-by: Kees Cook <[email protected]> Link: https://lore.kernel.org/r/Yytb67xvrnctxnEe@work
1 parent 38931d8 commit 25226df

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

arch/x86/mm/pgtable.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,6 @@ static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
299299
pud_t *pud;
300300
int i;
301301

302-
if (PREALLOCATED_PMDS == 0) /* Work around gcc-3.4.x bug */
303-
return;
304-
305302
p4d = p4d_offset(pgd, 0);
306303
pud = pud_offset(p4d, 0);
307304

@@ -434,10 +431,12 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
434431

435432
mm->pgd = pgd;
436433

437-
if (preallocate_pmds(mm, pmds, PREALLOCATED_PMDS) != 0)
434+
if (sizeof(pmds) != 0 &&
435+
preallocate_pmds(mm, pmds, PREALLOCATED_PMDS) != 0)
438436
goto out_free_pgd;
439437

440-
if (preallocate_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS) != 0)
438+
if (sizeof(u_pmds) != 0 &&
439+
preallocate_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS) != 0)
441440
goto out_free_pmds;
442441

443442
if (paravirt_pgd_alloc(mm) != 0)
@@ -451,17 +450,22 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
451450
spin_lock(&pgd_lock);
452451

453452
pgd_ctor(mm, pgd);
454-
pgd_prepopulate_pmd(mm, pgd, pmds);
455-
pgd_prepopulate_user_pmd(mm, pgd, u_pmds);
453+
if (sizeof(pmds) != 0)
454+
pgd_prepopulate_pmd(mm, pgd, pmds);
455+
456+
if (sizeof(u_pmds) != 0)
457+
pgd_prepopulate_user_pmd(mm, pgd, u_pmds);
456458

457459
spin_unlock(&pgd_lock);
458460

459461
return pgd;
460462

461463
out_free_user_pmds:
462-
free_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS);
464+
if (sizeof(u_pmds) != 0)
465+
free_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS);
463466
out_free_pmds:
464-
free_pmds(mm, pmds, PREALLOCATED_PMDS);
467+
if (sizeof(pmds) != 0)
468+
free_pmds(mm, pmds, PREALLOCATED_PMDS);
465469
out_free_pgd:
466470
_pgd_free(pgd);
467471
out:

0 commit comments

Comments
 (0)