From patchwork Tue May 20 09:21:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 112632 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D8D643858401 for ; Tue, 20 May 2025 09:23:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D8D643858401 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=IgM6i+3t X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 39BC33858D20 for ; Tue, 20 May 2025 09:21:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 39BC33858D20 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 39BC33858D20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1747732896; cv=none; b=B0kcfm8KfLNBytSVrJVuvzqKGcIcs7NQ1c84FyNMSbVLRdpJjHmakH0qcaspXCaXpjyXqh+4be97LN/DVu6D/rO/FbIHi0mcYgPovQwxV3nrJ3u50gAgGAQ7ofBgeSyW98KQ/iqqsDn/dUuIJKZIxQOonCwLX00Vf/CbHpDS6cI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1747732896; c=relaxed/simple; bh=BE6Yxhd3L5nFMw9PvU60bUNucgCjL6dIkd+BEAHyGPI=; h=DKIM-Signature:From:To:Subject:Message-ID:Date:MIME-Version; b=OYCk5bYhFXsHYSeFKEg4mShGKrCZjoZFzUVeGuDgPQCE1pHUD68NdqH+IPv0bD9DpQ4+/J9Ua2jiPNaWBxtd1KWO+h53KbTBW8C9JOiEZJPBQBaMZ/OLgOZ88OGQbiUcGpq+oY/x2gzYRGnxpkHQHgZOhxvET5uJGMjjUio8lIE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 39BC33858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747732891; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Cr7rjvBduSxm8AEqbMxho1rolEtX2XcT+Rg9bax6Mx4=; b=IgM6i+3t8PjPYRGKyY22zuMolMugKjpKJYXuwYl/Q9YreXi2PPdO1mWpGVU9vww7Y11DSZ bwX6dDUKPlWfE2kegJ4M7WPzuxV8QiqqOc+CvjwvDbnlExzX7qgUgHSv9aue7/R4X7wYEl HeBga2zvbCpmfdzka3anx3IEKVuGSAI= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-281-sbdoeKmCOpe5VgcCgfDxSA-1; Tue, 20 May 2025 05:21:29 -0400 X-MC-Unique: sbdoeKmCOpe5VgcCgfDxSA-1 X-Mimecast-MFC-AGG-ID: sbdoeKmCOpe5VgcCgfDxSA_1747732888 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 797D519560A3 for ; Tue, 20 May 2025 09:21:28 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.2.16.247]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A00F11956096 for ; Tue, 20 May 2025 09:21:27 +0000 (UTC) From: Florian Weimer To: libc-alpha@sourceware.org Subject: [PATCH v6 01/23] elf: Add tests to verify that l_contiguous reflects reality In-Reply-To: Message-ID: <6107ac6cb88c91de9ed8ee128dd2170c154e8e4f.1747731758.git.fweimer@redhat.com> References: X-From-Line: 6107ac6cb88c91de9ed8ee128dd2170c154e8e4f Mon Sep 17 00:00:00 2001 Date: Tue, 20 May 2025 11:21:24 +0200 User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: UYsVxOSS-VJmt9qDU5Gq6ilNw0cYn28aaGDKFgOPjnI_1747732888 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Test elf/tst-link-map-contiguous-ldso iterates over the loader image, reading every word to make sure memory is actually mapped. It only does that if the l_contiguous flag is set for the link map. The test elf/tst-link-map-contiguous-main does the same thing for the libc.so shared object. This only works if the kernel loaded the main program because the glibc dynamic loader may fill the gaps with PROT_NONE mappings in some cases, making it contiguous, but accesses to individual words may still fault. Test elf/tst-link-map-contiguous-libc is again slightly different because the dynamic loader always fills the gaps with PROT_NONE mappings, so a different form of probing has to be used. --- elf/Makefile | 6 ++++ elf/tst-link-map-contiguous-ldso.c | 44 +++++++++++++++++++++++ elf/tst-link-map-contiguous-libc.c | 57 ++++++++++++++++++++++++++++++ elf/tst-link-map-contiguous-main.c | 45 +++++++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 elf/tst-link-map-contiguous-ldso.c create mode 100644 elf/tst-link-map-contiguous-libc.c create mode 100644 elf/tst-link-map-contiguous-main.c diff --git a/elf/Makefile b/elf/Makefile index ed1b0223da..f60971bc2b 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -538,6 +538,8 @@ tests-internal += \ tst-dl_find_object-threads \ tst-dlmopen2 \ tst-hash-collision3 \ + tst-link-map-contiguous-ldso \ + tst-link-map-contiguous-libc \ tst-ptrguard1 \ tst-stackguard1 \ tst-tls-surplus \ @@ -549,6 +551,10 @@ tests-internal += \ unload2 \ # tests-internal +ifeq ($(build-hardcoded-path-in-tests),yes) +tests-internal += tst-link-map-contiguous-main +endif + tests-container += \ tst-dlopen-self-container \ tst-dlopen-tlsmodid-container \ diff --git a/elf/tst-link-map-contiguous-ldso.c b/elf/tst-link-map-contiguous-ldso.c new file mode 100644 index 0000000000..e83f5a48b8 --- /dev/null +++ b/elf/tst-link-map-contiguous-ldso.c @@ -0,0 +1,44 @@ +/* Check that the entire ld.so program image is readable if contiguous. + Copyright (C) 2014-2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +static int +do_test (void) +{ + struct link_map *l = xdlopen (LD_SO, RTLD_NOW); + if (!l->l_contiguous) + FAIL_UNSUPPORTED ("ld.so link map is not contiguous"); + + volatile long int *p = (volatile long int *) l->l_map_start; + volatile long int *end = (volatile long int *) l->l_map_end; + while (p < end) + { + *p; + ++p; + } + + xdlclose (l); + + return 0; +} + +#include diff --git a/elf/tst-link-map-contiguous-libc.c b/elf/tst-link-map-contiguous-libc.c new file mode 100644 index 0000000000..49fda125b0 --- /dev/null +++ b/elf/tst-link-map-contiguous-libc.c @@ -0,0 +1,57 @@ +/* Check that the entire libc.so program image is readable if contiguous. + Copyright (C) 2014-2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include + +static int +do_test (void) +{ + struct link_map *l = xdlopen (LIBC_SO, RTLD_NOW); + + /* The dynamic loader fills holes with PROT_NONE mappings. */ + if (!l->l_contiguous) + FAIL_EXIT1 ("libc.so link map is not contiguous"); + + /* Direct probing does not work because not everything is readable + due to PROT_NONE mappings. */ + int pagesize = getpagesize (); + ElfW(Addr) addr = l->l_map_start; + TEST_COMPARE (addr % pagesize, 0); + while (addr < l->l_map_end) + { + void *expected = (void *) addr; + void *ptr = xmmap (expected, 1, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1); + if (ptr == expected) + FAIL ("hole in libc.so memory image after %lu bytes", + (unsigned long int) (addr - l->l_map_start)); + xmunmap (ptr, 1); + addr += pagesize; + } + + xdlclose (l); + + return 0; +} +#include diff --git a/elf/tst-link-map-contiguous-main.c b/elf/tst-link-map-contiguous-main.c new file mode 100644 index 0000000000..ca5e0b9310 --- /dev/null +++ b/elf/tst-link-map-contiguous-main.c @@ -0,0 +1,45 @@ +/* Check that the entire main program image is readable if contiguous. + Copyright (C) 2014-2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +static int +do_test (void) +{ + struct link_map *l = xdlopen ("", RTLD_NOW); + if (!l->l_contiguous) + FAIL_UNSUPPORTED ("main link map is not contiguous"); + + /* This check only works if the kernel loaded the main program. The + dynamic loader replaces gaps with PROT_NONE mappings, resulting + in faults. */ + volatile long int *p = (volatile long int *) l->l_map_start; + volatile long int *end = (volatile long int *) l->l_map_end; + while (p < end) + { + *p; + ++p; + } + + xdlclose (l); + + return 0; +} +#include