Message ID | 20241031193608.1965366-1-Liam.Howlett@oracle.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v2] vma: Detect infinite loop in vma tree | expand |
On Thu, 31 Oct 2024 15:36:08 -0400 "Liam R. Howlett" <Liam.Howlett@oracle.com> wrote: > From: "Liam R. Howlett" <Liam.Howlett@Oracle.com> > > There have been no reported infinite loops in the tree, but checking the > detection of an infinite loop during validation is simple enough. Add > the detection to the validate_mm() function so that error reports are > clear and don't just report stalls. > > This does not protect against internal maple tree issues, but it does > detect too many vmas being returned from the tree. > > The variance of +10 is to allow for the debugging output to be more useful for > nearly correct counts. In the event of more than 10 over the map_count, the > count will be set to -1 for easier identification of a potential infinite loop. > > Note that the mmap lock is held to ensure a consistent tree state during the > validation process. > > ... > > +++ b/mm/vma.c > @@ -615,7 +615,10 @@ void validate_mm(struct mm_struct *mm) > anon_vma_unlock_read(anon_vma); > } > #endif > - i++; > + if (++i > mm->map_count + 10) { > + i = -1; > + break; > + } > } > if (i != mm->map_count) { > pr_emerg("map_count %d vma iterator %d\n", mm->map_count, i); It might be helpful to tell readers what's going on here? --- a/mm/vma.c~vma-detect-infinite-loop-in-vma-tree-fix +++ a/mm/vma.c @@ -615,6 +615,7 @@ void validate_mm(struct mm_struct *mm) anon_vma_unlock_read(anon_vma); } #endif + /* Check for a infinite loop */ if (++i > mm->map_count + 10) { i = -1; break;
* Andrew Morton <akpm@linux-foundation.org> [241031 16:48]: > On Thu, 31 Oct 2024 15:36:08 -0400 "Liam R. Howlett" <Liam.Howlett@oracle.com> wrote: > > > From: "Liam R. Howlett" <Liam.Howlett@Oracle.com> > > > > There have been no reported infinite loops in the tree, but checking the > > detection of an infinite loop during validation is simple enough. Add > > the detection to the validate_mm() function so that error reports are > > clear and don't just report stalls. > > > > This does not protect against internal maple tree issues, but it does > > detect too many vmas being returned from the tree. > > > > The variance of +10 is to allow for the debugging output to be more useful for > > nearly correct counts. In the event of more than 10 over the map_count, the > > count will be set to -1 for easier identification of a potential infinite loop. > > > > Note that the mmap lock is held to ensure a consistent tree state during the > > validation process. > > > > ... > > > > +++ b/mm/vma.c > > @@ -615,7 +615,10 @@ void validate_mm(struct mm_struct *mm) > > anon_vma_unlock_read(anon_vma); > > } > > #endif > > - i++; > > + if (++i > mm->map_count + 10) { > > + i = -1; > > + break; > > + } > > } > > if (i != mm->map_count) { > > pr_emerg("map_count %d vma iterator %d\n", mm->map_count, i); > > It might be helpful to tell readers what's going on here? Sounds good. I guess I should have waited longer for a v2. > > --- a/mm/vma.c~vma-detect-infinite-loop-in-vma-tree-fix > +++ a/mm/vma.c > @@ -615,6 +615,7 @@ void validate_mm(struct mm_struct *mm) > anon_vma_unlock_read(anon_vma); > } > #endif > + /* Check for a infinite loop */ > if (++i > mm->map_count + 10) { > i = -1; > break; > _ >
On 31.10.24 20:36, Liam R. Howlett wrote: > From: "Liam R. Howlett" <Liam.Howlett@Oracle.com> > > There have been no reported infinite loops in the tree, but checking the > detection of an infinite loop during validation is simple enough. Add > the detection to the validate_mm() function so that error reports are > clear and don't just report stalls. > > This does not protect against internal maple tree issues, but it does > detect too many vmas being returned from the tree. > > The variance of +10 is to allow for the debugging output to be more useful for > nearly correct counts. In the event of more than 10 over the map_count, the > count will be set to -1 for easier identification of a potential infinite loop. > > Note that the mmap lock is held to ensure a consistent tree state during the > validation process. > > Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com> > Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> > Cc: Vlastimil Babka <vbabka@suse.cz> > Cc: Jann Horn <jannh@google.com> > --- > mm/vma.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/mm/vma.c b/mm/vma.c > index 68138e8c153e..283e6bc4884f 100644 > --- a/mm/vma.c > +++ b/mm/vma.c > @@ -615,7 +615,10 @@ void validate_mm(struct mm_struct *mm) > anon_vma_unlock_read(anon_vma); > } > #endif > - i++; > + if (++i > mm->map_count + 10) { > + i = -1; > + break; > + } > } > if (i != mm->map_count) { > pr_emerg("map_count %d vma iterator %d\n", mm->map_count, i); Reviewed-by: David Hildenbrand <david@redhat.com>
On 10/31/24 20:36, Liam R. Howlett wrote: > From: "Liam R. Howlett" <Liam.Howlett@Oracle.com> > > There have been no reported infinite loops in the tree, but checking the > detection of an infinite loop during validation is simple enough. Add > the detection to the validate_mm() function so that error reports are > clear and don't just report stalls. > > This does not protect against internal maple tree issues, but it does > detect too many vmas being returned from the tree. > > The variance of +10 is to allow for the debugging output to be more useful for > nearly correct counts. In the event of more than 10 over the map_count, the > count will be set to -1 for easier identification of a potential infinite loop. > > Note that the mmap lock is held to ensure a consistent tree state during the > validation process. > > Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com> > Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> > Cc: Vlastimil Babka <vbabka@suse.cz> > Cc: Jann Horn <jannh@google.com> Reviewed-by: Vlastimil Babka <vbabka@suse.cz> > --- > mm/vma.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/mm/vma.c b/mm/vma.c > index 68138e8c153e..283e6bc4884f 100644 > --- a/mm/vma.c > +++ b/mm/vma.c > @@ -615,7 +615,10 @@ void validate_mm(struct mm_struct *mm) > anon_vma_unlock_read(anon_vma); > } > #endif > - i++; > + if (++i > mm->map_count + 10) { > + i = -1; > + break; > + } > } > if (i != mm->map_count) { > pr_emerg("map_count %d vma iterator %d\n", mm->map_count, i);
diff --git a/mm/vma.c b/mm/vma.c index 68138e8c153e..283e6bc4884f 100644 --- a/mm/vma.c +++ b/mm/vma.c @@ -615,7 +615,10 @@ void validate_mm(struct mm_struct *mm) anon_vma_unlock_read(anon_vma); } #endif - i++; + if (++i > mm->map_count + 10) { + i = -1; + break; + } } if (i != mm->map_count) { pr_emerg("map_count %d vma iterator %d\n", mm->map_count, i);