git: ef1976ccf542 - main - linprocfs: Skip printing of the guard page in the /proc/self/maps

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Wed, 22 Jun 2022 11:50:49 UTC
The branch main has been updated by dchagin:

URL: https://cgit.FreeBSD.org/src/commit/?id=ef1976ccf5420d0912afcb49733c7a88643069da

commit ef1976ccf5420d0912afcb49733c7a88643069da
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-06-22 11:49:40 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-06-22 11:49:40 +0000

    linprocfs: Skip printing of the guard page in the /proc/self/maps
    
    To calculate the base (lowest addressable) address of the stack of the
    initial thread glibc parses /proc/self/maps.
    In fact, the base address is calculated as 'to' value of stack entry of the
    /proc/self/maps - stack size limit (if the stack grows down).
    The base address should fit in between preceding entry and stack entry of
    the /proc/self/maps.
    In FreeBSD, since 19bd0d9 (Implement address space guards), we actually
    have two mappings for the stack region. The first one is the no-access
    mapping for the region the stack can grow into (guard page), and the
    second - initial stack region with size sgrowsiz.
    The first mapping confuses Glibc, in the end which is improperly
    calculate stack size and the base address.
    
    PR:                     253337
    Reviewed by:            kib
    Differential revision:  https://reviews.freebsd.org/D35537
    MFC after:              2 week
---
 sys/compat/linprocfs/linprocfs.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 62fa797ae875..93b5af04e670 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -1307,7 +1307,13 @@ linprocfs_doprocmaps(PFS_FILL_ARGS)
 	VM_MAP_ENTRY_FOREACH(entry, map) {
 		name = "";
 		freename = NULL;
-		if (entry->eflags & MAP_ENTRY_IS_SUB_MAP)
+		/*
+		 * Skip printing of the guard page of the stack region, as
+		 * it confuses glibc pthread_getattr_np() method, where both
+		 * the base address and size of the stack of the initial thread
+		 * are calculated.
+		 */
+		if ((entry->eflags & (MAP_ENTRY_IS_SUB_MAP | MAP_ENTRY_GUARD)) != 0)
 			continue;
 		e_prot = entry->protection;
 		e_start = entry->start;