Re: [PATCH v3 08/12] treewide: Use initializer for struct vm_unmapped_area_info

2024-03-13 Thread Edgecombe, Rick P
On Tue, 2024-03-12 at 20:18 -0700, Kees Cook wrote:
> 
> Thanks! This looks to do exactly what it describes. :)
> 
> Reviewed-by: Kees Cook 

Thanks!


Re: [PATCH v3 08/12] treewide: Use initializer for struct vm_unmapped_area_info

2024-03-12 Thread Kees Cook
On Tue, Mar 12, 2024 at 03:28:39PM -0700, Rick Edgecombe wrote:
> So to be reduce the chance of bugs via uninitialized fields, perform a
> tree wide change using the consensus for the best general way to do this
> change. Use C99 static initializing to zero the struct and remove and
> statements that simply set members to zero.
> 
> Signed-off-by: Rick Edgecombe 

Thanks! This looks to do exactly what it describes. :)

Reviewed-by: Kees Cook 

-- 
Kees Cook



[PATCH v3 08/12] treewide: Use initializer for struct vm_unmapped_area_info

2024-03-12 Thread Rick Edgecombe
Future changes will need to add a new member to struct
vm_unmapped_area_info. This would cause trouble for any call site that
doesn't initialize the struct. Currently every caller sets each member
manually, so if new ones are added they will be uninitialized and the
core code parsing the struct will see garbage in the new member.

It could be possible to initialize the new member manually to 0 at each
call site. This and a couple other options were discussed. Having some
struct vm_unmapped_area_info instances not zero initialized will put
those sites at risk of feeding garbage into vm_unmapped_area(), if the
convention is to zero initialize the struct and any new field addition
missed a call site that initializes each field manually. So it is
useful to do things similar across the kernel.

The consensus (see links) was that in general the best way to accomplish
taking into account both code cleanliness and minimizing the chance of
introducing bugs, was to do C99 static initialization. As in:
struct vm_unmapped_area_info info = {};

With this method of initialization, the whole struct will be zero
initialized, and any statements setting fields to zero will be unneeded.
The change should not leave cleanup at the call sides.

While iterating though the possible solutions a few archs kindly acked
other variations that still zero initialized the struct. These sites have
been modified in previous changes using the pattern acked by the respective
arch.

So to be reduce the chance of bugs via uninitialized fields, perform a
tree wide change using the consensus for the best general way to do this
change. Use C99 static initializing to zero the struct and remove and
statements that simply set members to zero.

Signed-off-by: Rick Edgecombe 
Cc: linux...@kvack.org
Cc: linux-alpha@vger.kernel.org
Cc: linux-snps-...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-c...@vger.kernel.org
Cc: loonga...@lists.linux.dev
Cc: linux-m...@vger.kernel.org
Cc: linux-s...@vger.kernel.org
Cc: linux...@vger.kernel.org
Cc: sparcli...@vger.kernel.org
Link: https://lore.kernel.org/lkml/202402280912.33AEE7A9CF@keescook/#t
Link: 
https://lore.kernel.org/lkml/j7bfvig3gew3qruouxrh7z7ehjjafrgkbcmg6tcghhfh3rhmzi@wzlcoecgy5rs/
Link: 
https://lore.kernel.org/lkml/ec3e377a-c0a0-4dd3-9cb9-96517e54d...@csgroup.eu/
---
Hi archs,

For some context, this is part of a larger series to improve shadow stack
guard gaps. It involves plumbing a new field via
struct vm_unmapped_area_info. The first user is x86, but arm and riscv may
likely use it as well. The change is compile tested only for non-x86.

Thanks,

Rick
---
 arch/alpha/kernel/osf_sys.c  |  5 +
 arch/arc/mm/mmap.c   |  4 +---
 arch/arm/mm/mmap.c   |  5 ++---
 arch/loongarch/mm/mmap.c |  3 +--
 arch/mips/mm/mmap.c  |  3 +--
 arch/s390/mm/hugetlbpage.c   |  7 ++-
 arch/s390/mm/mmap.c  | 11 ---
 arch/sh/mm/mmap.c|  5 ++---
 arch/sparc/kernel/sys_sparc_32.c |  3 +--
 arch/sparc/kernel/sys_sparc_64.c |  5 ++---
 arch/sparc/mm/hugetlbpage.c  |  7 ++-
 arch/x86/kernel/sys_x86_64.c |  7 ++-
 arch/x86/mm/hugetlbpage.c|  7 ++-
 fs/hugetlbfs/inode.c |  7 ++-
 mm/mmap.c|  9 ++---
 15 files changed, 27 insertions(+), 61 deletions(-)

diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 5db88b627439..e5f881bc8288 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -1218,14 +1218,11 @@ static unsigned long
 arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
 unsigned long limit)
 {
-   struct vm_unmapped_area_info info;
+   struct vm_unmapped_area_info info = {};
 
-   info.flags = 0;
info.length = len;
info.low_limit = addr;
info.high_limit = limit;
-   info.align_mask = 0;
-   info.align_offset = 0;
return vm_unmapped_area();
 }
 
diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c
index 3c1c7ae73292..69a915297155 100644
--- a/arch/arc/mm/mmap.c
+++ b/arch/arc/mm/mmap.c
@@ -27,7 +27,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 {
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
-   struct vm_unmapped_area_info info;
+   struct vm_unmapped_area_info info = {};
 
/*
 * We enforce the MAP_FIXED case.
@@ -51,11 +51,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr;
}
 
-   info.flags = 0;
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
-   info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
return vm_unmapped_area();
 }
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index a0f8a0ca0788..d65d0e6ed10a 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@