mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 14:50:05 +00:00
elf: Add support for GNU_PROPERTY_NO_MEMORY_SEAL
The GNU_PROPERTY_NO_MEMORY_SEAL is a GNU property per module instructing the glibc not to seal the object PT_LOAD. It can be used for any reason the modules require to seal not to be enabled (i.e., on Firefox hack to bypass the dynamic loader and enable DT_RELR on older glibc [1]). In this case, it is up to the module to apply memory sealing itself. The sealing is applied by default, and it is always enforced with glibc.rtld.seal=2. Checked on aarch64-linux-gnu, x86_64-linux-gnu, and powerpc64le-linux-gnu. [1] https://glandium.org/blog/?p=4297
This commit is contained in:
parent
8d2a331b64
commit
52ddeb99b2
35
configure
vendored
35
configure
vendored
@ -7102,6 +7102,41 @@ printf "%s\n" "$libc_linker_feature" >&6; }
|
|||||||
config_vars="$config_vars
|
config_vars="$config_vars
|
||||||
have-no-dynamic-linker = $libc_cv_no_dynamic_linker"
|
have-no-dynamic-linker = $libc_cv_no_dynamic_linker"
|
||||||
|
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z no-memory-seal" >&5
|
||||||
|
printf %s "checking for linker that supports -z no-memory-seal... " >&6; }
|
||||||
|
libc_linker_feature=no
|
||||||
|
cat > conftest.c <<EOF
|
||||||
|
int _start (void) { return 42; }
|
||||||
|
EOF
|
||||||
|
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
|
||||||
|
-Wl,-z,no-memory-seal -nostdlib -nostartfiles
|
||||||
|
-fPIC -shared -o conftest.so conftest.c
|
||||||
|
1>&5'
|
||||||
|
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; }
|
||||||
|
then
|
||||||
|
if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,-z,no-memory-seal -nostdlib \
|
||||||
|
-nostartfiles -fPIC -shared -o conftest.so conftest.c 2>&1 \
|
||||||
|
| grep "warning: -z no-memory-seal ignored" > /dev/null 2>&1; then
|
||||||
|
true
|
||||||
|
else
|
||||||
|
libc_linker_feature=yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
rm -f conftest*
|
||||||
|
if test $libc_linker_feature = yes; then
|
||||||
|
libc_cv_z_no_memory_seal=yes
|
||||||
|
else
|
||||||
|
libc_cv_z_no_memory_seal=no
|
||||||
|
fi
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
|
||||||
|
printf "%s\n" "$libc_linker_feature" >&6; }
|
||||||
|
config_vars="$config_vars
|
||||||
|
have-z-no-memory-seal = $libc_cv_z_no_memory_seal"
|
||||||
|
|
||||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -static-pie" >&5
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -static-pie" >&5
|
||||||
printf %s "checking for -static-pie... " >&6; }
|
printf %s "checking for -static-pie... " >&6; }
|
||||||
if test ${libc_cv_static_pie+y}
|
if test ${libc_cv_static_pie+y}
|
||||||
|
@ -1278,6 +1278,11 @@ LIBC_LINKER_FEATURE([--no-dynamic-linker],
|
|||||||
[libc_cv_no_dynamic_linker=no])
|
[libc_cv_no_dynamic_linker=no])
|
||||||
LIBC_CONFIG_VAR([have-no-dynamic-linker], [$libc_cv_no_dynamic_linker])
|
LIBC_CONFIG_VAR([have-no-dynamic-linker], [$libc_cv_no_dynamic_linker])
|
||||||
|
|
||||||
|
LIBC_LINKER_FEATURE([-z no-memory-seal],
|
||||||
|
[-Wl,-z,no-memory-seal],
|
||||||
|
[libc_cv_z_no_memory_seal=yes], [libc_cv_z_no_memory_seal=no])
|
||||||
|
LIBC_CONFIG_VAR([have-z-no-memory-seal], [$libc_cv_z_no_memory_seal])
|
||||||
|
|
||||||
AC_CACHE_CHECK(for -static-pie, libc_cv_static_pie, [dnl
|
AC_CACHE_CHECK(for -static-pie, libc_cv_static_pie, [dnl
|
||||||
LIBC_TRY_CC_OPTION([-static-pie],
|
LIBC_TRY_CC_OPTION([-static-pie],
|
||||||
[libc_cv_static_pie=yes],
|
[libc_cv_static_pie=yes],
|
||||||
|
@ -1431,7 +1431,9 @@ cannot enable executable stack as shared object requires");
|
|||||||
/* Assign the next available module ID. */
|
/* Assign the next available module ID. */
|
||||||
_dl_assign_tls_modid (l);
|
_dl_assign_tls_modid (l);
|
||||||
|
|
||||||
l->l_seal = mode & RTLD_NODELETE ? lt_seal_toseal : lt_seal_dont;
|
/* Do not alter the sealing if the GNU property disables it. */
|
||||||
|
if (l->l_seal == lt_seal_undefined && mode & RTLD_NODELETE)
|
||||||
|
l->l_seal = lt_seal_toseal;
|
||||||
|
|
||||||
#ifdef DL_AFTER_LOAD
|
#ifdef DL_AFTER_LOAD
|
||||||
DL_AFTER_LOAD (l);
|
DL_AFTER_LOAD (l);
|
||||||
|
@ -841,7 +841,7 @@ dl_open_worker (void *a)
|
|||||||
|
|
||||||
/* The seal flag is set only for NEW, however its dependencies could not be
|
/* The seal flag is set only for NEW, however its dependencies could not be
|
||||||
unloaded and thus can also be sealed. */
|
unloaded and thus can also be sealed. */
|
||||||
_dl_mseal_map (new, true);
|
_dl_mseal_map (new, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -352,7 +352,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
|||||||
/* Seal the memory mapping after RELRO setup, we can use the PT_LOAD
|
/* Seal the memory mapping after RELRO setup, we can use the PT_LOAD
|
||||||
segments because even if relro splits the the original RW VMA,
|
segments because even if relro splits the the original RW VMA,
|
||||||
mseal works with multiple VMAs with different flags. */
|
mseal works with multiple VMAs with different flags. */
|
||||||
_dl_mseal_map (l, false);
|
_dl_mseal_map (l, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -376,11 +376,10 @@ cannot apply additional memory protection after relocation");
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_dl_mseal_map_1 (struct link_map *l)
|
_dl_mseal_map_1 (struct link_map *l, bool force)
|
||||||
{
|
{
|
||||||
/* We only checked if the map is already sealed here so we can seal audit
|
if (l->l_seal == lt_seal_dont
|
||||||
module dependencies after the initial audit setup. */
|
|| (!force && (l->l_seal != lt_seal_toseal)))
|
||||||
if (l->l_seal == lt_seal_sealed)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int r = -1;
|
int r = -1;
|
||||||
@ -408,16 +407,13 @@ _dl_mseal_map_1 (struct link_map *l)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_dl_mseal_map (struct link_map *l, bool dep)
|
_dl_mseal_map (struct link_map *l, bool dep, bool force)
|
||||||
{
|
{
|
||||||
if (l->l_seal == lt_seal_dont || l->l_seal == lt_seal_sealed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (l->l_searchlist.r_list == NULL || !dep)
|
if (l->l_searchlist.r_list == NULL || !dep)
|
||||||
_dl_mseal_map_1 (l);
|
_dl_mseal_map_1 (l, force);
|
||||||
else
|
else
|
||||||
for (unsigned int i = 0; i < l->l_searchlist.r_nlist; ++i)
|
for (unsigned int i = 0; i < l->l_searchlist.r_nlist; ++i)
|
||||||
_dl_mseal_map_1 (l->l_searchlist.r_list[i]);
|
_dl_mseal_map_1 (l->l_searchlist.r_list[i], force);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -101,7 +101,7 @@ static struct link_map _dl_main_map =
|
|||||||
.l_used = 1,
|
.l_used = 1,
|
||||||
.l_tls_offset = NO_TLS_OFFSET,
|
.l_tls_offset = NO_TLS_OFFSET,
|
||||||
.l_serial = 1,
|
.l_serial = 1,
|
||||||
.l_seal = SUPPORT_MSEAL,
|
.l_seal = lt_seal_toseal,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Namespace information. */
|
/* Namespace information. */
|
||||||
@ -359,7 +359,7 @@ _dl_non_dynamic_init (void)
|
|||||||
/* Seal the memory mapping after RELRO setup, we can use the PT_LOAD
|
/* Seal the memory mapping after RELRO setup, we can use the PT_LOAD
|
||||||
segments because even if relro splits the the original RW VMA,
|
segments because even if relro splits the the original RW VMA,
|
||||||
mseal works with multiple VMAs with different flags. */
|
mseal works with multiple VMAs with different flags. */
|
||||||
_dl_mseal_map (&_dl_main_map, false);
|
_dl_mseal_map (&_dl_main_map, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DL_SYSINFO_IMPLEMENTATION
|
#ifdef DL_SYSINFO_IMPLEMENTATION
|
||||||
|
@ -1357,6 +1357,8 @@ typedef struct
|
|||||||
#define GNU_PROPERTY_STACK_SIZE 1
|
#define GNU_PROPERTY_STACK_SIZE 1
|
||||||
/* No copy relocation on protected data symbol. */
|
/* No copy relocation on protected data symbol. */
|
||||||
#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
|
#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
|
||||||
|
/* No memory sealing. */
|
||||||
|
#define GNU_PROPERTY_NO_MEMORY_SEAL 3
|
||||||
|
|
||||||
/* A 4-byte unsigned integer property: A bit is set if it is set in all
|
/* A 4-byte unsigned integer property: A bit is set if it is set in all
|
||||||
relocatable inputs. */
|
relocatable inputs. */
|
||||||
|
10
elf/rtld.c
10
elf/rtld.c
@ -478,7 +478,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
|
|||||||
GL(dl_rtld_map).l_real = &GL(dl_rtld_map);
|
GL(dl_rtld_map).l_real = &GL(dl_rtld_map);
|
||||||
GL(dl_rtld_map).l_map_start = (ElfW(Addr)) &__ehdr_start;
|
GL(dl_rtld_map).l_map_start = (ElfW(Addr)) &__ehdr_start;
|
||||||
GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
|
GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
|
||||||
GL(dl_rtld_map).l_seal = 1;
|
GL(dl_rtld_map).l_seal = lt_seal_toseal;
|
||||||
/* Copy the TLS related data if necessary. */
|
/* Copy the TLS related data if necessary. */
|
||||||
#ifndef DONT_USE_BOOTSTRAP_MAP
|
#ifndef DONT_USE_BOOTSTRAP_MAP
|
||||||
# if NO_TLS_OFFSET != 0
|
# if NO_TLS_OFFSET != 0
|
||||||
@ -1046,9 +1046,9 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
|
|||||||
/* Mark the DSO as being used for auditing. */
|
/* Mark the DSO as being used for auditing. */
|
||||||
dlmargs.map->l_auditing = 1;
|
dlmargs.map->l_auditing = 1;
|
||||||
|
|
||||||
/* Seal the audit modules and their dependencies. */
|
/* Since audit modules can not be loaded with RTLD_NODELETE, force the
|
||||||
dlmargs.map->l_seal = lt_seal_toseal;
|
sealing of the modules and its dependencies. */
|
||||||
_dl_mseal_map (dlmargs.map, true);
|
_dl_mseal_map (dlmargs.map, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load all audit modules. */
|
/* Load all audit modules. */
|
||||||
@ -1131,7 +1131,7 @@ rtld_setup_main_map (struct link_map *main_map)
|
|||||||
/* And it was opened directly. */
|
/* And it was opened directly. */
|
||||||
++main_map->l_direct_opencount;
|
++main_map->l_direct_opencount;
|
||||||
main_map->l_contiguous = 1;
|
main_map->l_contiguous = 1;
|
||||||
main_map->l_seal = 1;
|
main_map->l_seal = lt_seal_toseal;
|
||||||
|
|
||||||
/* A PT_LOAD segment at an unexpected address will clear the
|
/* A PT_LOAD segment at an unexpected address will clear the
|
||||||
l_contiguous flag. The ELF specification says that PT_LOAD
|
l_contiguous flag. The ELF specification says that PT_LOAD
|
||||||
|
@ -214,6 +214,7 @@ struct link_map
|
|||||||
lt_library map. */
|
lt_library map. */
|
||||||
enum /* Memory sealing status. */
|
enum /* Memory sealing status. */
|
||||||
{
|
{
|
||||||
|
lt_seal_undefined = 0, /* No set. */
|
||||||
lt_seal_dont, /* Do not seal the object. */
|
lt_seal_dont, /* Do not seal the object. */
|
||||||
lt_seal_toseal, /* The library is marked to be sealed. */
|
lt_seal_toseal, /* The library is marked to be sealed. */
|
||||||
lt_seal_sealed /* The library is sealed. */
|
lt_seal_sealed /* The library is sealed. */
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
<https://www.gnu.org/licenses/>. */
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
strerrorname_np (int errnum)
|
strerrorname_np (int errnum)
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#ifndef _DL_PROP_H
|
#ifndef _DL_PROP_H
|
||||||
#define _DL_PROP_H
|
#define _DL_PROP_H
|
||||||
|
|
||||||
|
#include <dl-prop-mseal.h>
|
||||||
|
|
||||||
extern void _dl_bti_protect (struct link_map *, int) attribute_hidden;
|
extern void _dl_bti_protect (struct link_map *, int) attribute_hidden;
|
||||||
|
|
||||||
extern void _dl_bti_check (struct link_map *, const char *)
|
extern void _dl_bti_check (struct link_map *, const char *)
|
||||||
@ -45,6 +47,9 @@ static inline int
|
|||||||
_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
|
_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
|
||||||
uint32_t datasz, void *data)
|
uint32_t datasz, void *data)
|
||||||
{
|
{
|
||||||
|
if (_dl_process_gnu_property_seal (l, fd, type, datasz, data))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!GLRO(dl_aarch64_cpu_features).bti)
|
if (!GLRO(dl_aarch64_cpu_features).bti)
|
||||||
/* Skip note processing. */
|
/* Skip note processing. */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -21,5 +21,3 @@ _dl_mseal (void *addr, size_t len)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SUPPORT_MSEAL lt_seal_dont
|
|
||||||
|
38
sysdeps/generic/dl-prop-mseal.h
Normal file
38
sysdeps/generic/dl-prop-mseal.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* Support for GNU properties. Generic version.
|
||||||
|
Copyright (C) 2024 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef _DL_PROP_MSEAL_H
|
||||||
|
#define _LD_PROP_MSEAL_H
|
||||||
|
|
||||||
|
#include <dl-tunables.h>
|
||||||
|
#include <dl-mseal-mode.h>
|
||||||
|
|
||||||
|
static __always_inline bool
|
||||||
|
_dl_process_gnu_property_seal (struct link_map *l, int fd, uint32_t type,
|
||||||
|
uint32_t datasz, void *data)
|
||||||
|
{
|
||||||
|
if (type == GNU_PROPERTY_NO_MEMORY_SEAL && datasz == 0)
|
||||||
|
{
|
||||||
|
int32_t mode = TUNABLE_GET (glibc, rtld, seal, int32_t, NULL);
|
||||||
|
l->l_seal = (mode == DL_SEAL_ENFORCE) ? lt_seal_toseal : lt_seal_dont;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -19,6 +19,8 @@
|
|||||||
#ifndef _DL_PROP_H
|
#ifndef _DL_PROP_H
|
||||||
#define _DL_PROP_H
|
#define _DL_PROP_H
|
||||||
|
|
||||||
|
#include <dl-prop-mseal.h>
|
||||||
|
|
||||||
/* The following functions are used by the dynamic loader and the
|
/* The following functions are used by the dynamic loader and the
|
||||||
dlopen machinery to process PT_NOTE and PT_GNU_PROPERTY entries in
|
dlopen machinery to process PT_NOTE and PT_GNU_PROPERTY entries in
|
||||||
the binary or shared object. The notes can be used to change the
|
the binary or shared object. The notes can be used to change the
|
||||||
@ -47,6 +49,9 @@ static inline int __attribute__ ((always_inline))
|
|||||||
_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
|
_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
|
||||||
uint32_t datasz, void *data)
|
uint32_t datasz, void *data)
|
||||||
{
|
{
|
||||||
|
if (_dl_process_gnu_property_seal (l, fd, type, datasz, data))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Continue until GNU_PROPERTY_1_NEEDED is found. */
|
/* Continue until GNU_PROPERTY_1_NEEDED is found. */
|
||||||
if (type == GNU_PROPERTY_1_NEEDED)
|
if (type == GNU_PROPERTY_1_NEEDED)
|
||||||
{
|
{
|
||||||
|
@ -1017,10 +1017,13 @@ extern void _dl_relocate_object (struct link_map *map,
|
|||||||
/* Protect PT_GNU_RELRO area. */
|
/* Protect PT_GNU_RELRO area. */
|
||||||
extern void _dl_protect_relro (struct link_map *map) attribute_hidden;
|
extern void _dl_protect_relro (struct link_map *map) attribute_hidden;
|
||||||
|
|
||||||
/* Protect MAP with mseal. If MAP is contiguous the while region is
|
/* Issue memory sealing for the link map MAP. If MAP is contiguous the
|
||||||
sealed, otherwise iterate over the phdr to seal each PT_LOAD. The DEP
|
whole region is sealed, otherwise iterate over the program headerrs and
|
||||||
specify whether to seal the dependencies as well. */
|
seal each PT_LOAD segment.i
|
||||||
extern void _dl_mseal_map (struct link_map *map, bool dep)
|
The DEP specify whether to seal the dependencies as well, while FORCE
|
||||||
|
ignores if previous seal configuration (such as
|
||||||
|
GNU_PROPERTY_NO_MEMORY_SEAL mark). */
|
||||||
|
extern void _dl_mseal_map (struct link_map *map, bool dep, bool force)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
|
||||||
/* Call _dl_signal_error with a message about an unhandled reloc type.
|
/* Call _dl_signal_error with a message about an unhandled reloc type.
|
||||||
|
@ -685,6 +685,52 @@ $(objpfx)tst-dl_mseal-dlopen-2.so: $(objpfx)tst-dl_mseal-dlopen-2-1.so
|
|||||||
LDFLAGS-tst-dl_mseal-dlopen-2.so = -Wl,--no-as-needed
|
LDFLAGS-tst-dl_mseal-dlopen-2.so = -Wl,--no-as-needed
|
||||||
|
|
||||||
tst-dl_mseal-static-ARGS = -- $(host-test-program-cmd)
|
tst-dl_mseal-static-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
ifeq ($(have-z-no-memory-seal),yes)
|
||||||
|
tests-static += \
|
||||||
|
tst-dl_mseal-static-no-memory-seal \
|
||||||
|
# tests-static
|
||||||
|
|
||||||
|
tests += \
|
||||||
|
tst-dl_mseal-no-memory-seal \
|
||||||
|
tst-dl_mseal-static-no-memory-seal \
|
||||||
|
# tests
|
||||||
|
|
||||||
|
modules-names += \
|
||||||
|
tst-dl_mseal-dlopen-no-memory-seal-2 \
|
||||||
|
tst-dl_mseal-dlopen-no-memory-seal-2-1 \
|
||||||
|
tst-dl_mseal-mod-no-memory-seal-1 \
|
||||||
|
tst-dl_mseal-mod-no-memory-seal-2 \
|
||||||
|
tst-dl_mseal-no-memory-seal-auditmod \
|
||||||
|
tst-dl_mseal-no-memory-seal-preload \
|
||||||
|
# modules-names
|
||||||
|
|
||||||
|
$(objpfx)tst-dl_mseal-no-memory-seal.out: \
|
||||||
|
$(objpfx)tst-dl_mseal-no-memory-seal-auditmod.so \
|
||||||
|
$(objpfx)tst-dl_mseal-no-memory-seal-preload.so \
|
||||||
|
$(objpfx)tst-dl_mseal-mod-no-memory-seal-1.so \
|
||||||
|
$(objpfx)tst-dl_mseal-mod-no-memory-seal-2.so \
|
||||||
|
$(objpfx)tst-dl_mseal-dlopen-1.so \
|
||||||
|
$(objpfx)tst-dl_mseal-dlopen-1-1.so \
|
||||||
|
$(objpfx)tst-dl_mseal-dlopen-no-memory-seal-2.so \
|
||||||
|
$(objpfx)tst-dl_mseal-dlopen-no-memory-seal-2-1.so
|
||||||
|
|
||||||
|
tst-dl_mseal-no-memory-seal-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
LDFLAGS-tst-dl_mseal-no-memory-seal-preload.so = -Wl,-z,no-memory-seal
|
||||||
|
|
||||||
|
LDFLAGS-tst-dl_mseal-no-memory-seal-auditmod.so = -Wl,-z,no-memory-seal
|
||||||
|
$(objpfx)tst-dl_mseal-no-memory-seal: $(objpfx)tst-dl_mseal-mod-no-memory-seal-1.so
|
||||||
|
LDFLAGS-tst-dl_mseal-no-memory-seal = -Wl,-z,no-memory-seal -Wl,--no-as-needed
|
||||||
|
$(objpfx)tst-dl_mseal-mod-no-memory-seal-1.so: $(objpfx)tst-dl_mseal-mod-no-memory-seal-2.so
|
||||||
|
LDFLAGS-tst-dl_mseal-mod-no-memory-seal-1.so = -Wl,--no-as-needed
|
||||||
|
LDFLAGS-tst-dl_mseal-mod-no-memory-seal-2.so = -Wl,-z,no-memory-seal -Wl,--no-as-needed
|
||||||
|
$(objpfx)tst-dl_mseal-dlopen-no-memory-seal-2.so: $(objpfx)tst-dl_mseal-dlopen-no-memory-seal-2-1.so
|
||||||
|
LDFLAGS-tst-dl_mseal-dlopen-no-memory-seal-2.so = -Wl,--no-as-needed -Wl,-z,no-memory-seal
|
||||||
|
|
||||||
|
LDFLAGS-tst-dl_mseal-static-no-memory-seal = -Wl,-z,no-memory-seal
|
||||||
|
tst-dl_mseal-static-no-memory-seal-ARGS = -- $(host-test-program-cmd)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(subdir),rt)
|
ifeq ($(subdir),rt)
|
||||||
|
@ -25,5 +25,3 @@
|
|||||||
Return 0 in case of success or a negative value otherwise (a negative
|
Return 0 in case of success or a negative value otherwise (a negative
|
||||||
errno). */
|
errno). */
|
||||||
int _dl_mseal (void *addr, size_t len) attribute_hidden;
|
int _dl_mseal (void *addr, size_t len) attribute_hidden;
|
||||||
|
|
||||||
#define SUPPORT_MSEAL lt_seal_toseal
|
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
/* Additional module for tst-dl_mseal test.
|
||||||
|
Copyright (C) 2024 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
int bar2_1 (void) { return 42; }
|
@ -0,0 +1,19 @@
|
|||||||
|
/* Additional module for tst-dl_mseal test.
|
||||||
|
Copyright (C) 2024 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
int bar2 (void) { return 42; }
|
19
sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-1.c
Normal file
19
sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-1.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* Additional module for tst-dl_mseal test.
|
||||||
|
Copyright (C) 2024 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
int foo1 (void) { return 42; }
|
19
sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-2.c
Normal file
19
sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-2.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* Additional module for tst-dl_mseal test.
|
||||||
|
Copyright (C) 2024 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
int bar1 (void) { return 42; }
|
@ -0,0 +1 @@
|
|||||||
|
#include "tst-dl_mseal-auditmod.c"
|
@ -0,0 +1 @@
|
|||||||
|
#include "tst-dl_mseal-preload.c"
|
65
sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal.c
Normal file
65
sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/* Basic tests for sealing.
|
||||||
|
Copyright (C) 2024 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <gnu/lib-names.h>
|
||||||
|
|
||||||
|
/* This test checks the GNU_PROPERTY_NO_MEMORY_SEAL handling on multiple
|
||||||
|
places:
|
||||||
|
|
||||||
|
- On the binary itself.
|
||||||
|
- On a LD_PRELOAD library.
|
||||||
|
- On a depedency module (tst-dl_mseal-mod-no-memory-seal-2.so).
|
||||||
|
- On a audit modules (tst-dl_mseal-no-memory-seal-auditmod.so).
|
||||||
|
- On a dlopen dependency opened with RTLD_NODELET
|
||||||
|
(tst-dl_mseal-dlopen-no-memory-seal-2.so).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIB_PRELOAD "tst-dl_mseal-no-memory-seal-preload.so"
|
||||||
|
#define GLIBC_RTLD_SEAL "1"
|
||||||
|
|
||||||
|
#define LIB_DLOPEN_DEFAULT "tst-dl_mseal-dlopen-1.so"
|
||||||
|
#define LIB_DLOPEN_DEFAULT_DEP "tst-dl_mseal-dlopen-1-1.so"
|
||||||
|
#define LIB_DLOPEN_NODELETE "tst-dl_mseal-dlopen-no-memory-seal-2.so"
|
||||||
|
#define LIB_DLOPEN_NODELETE_DEP "tst-dl_mseal-dlopen-no-memory-seal-2-1.so"
|
||||||
|
|
||||||
|
#define LIB_AUDIT "tst-dl_mseal-no-memory-seal-auditmod.so"
|
||||||
|
|
||||||
|
/* Expected libraries that loader will seal. */
|
||||||
|
static const char *expected_sealed_libs[] =
|
||||||
|
{
|
||||||
|
"libc.so",
|
||||||
|
"ld.so",
|
||||||
|
"tst-dl_mseal-mod-no-memory-seal-1.so",
|
||||||
|
LIB_DLOPEN_NODELETE_DEP,
|
||||||
|
LIBGCC_S_SO,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Expected non sealed libraries. */
|
||||||
|
static const char *expected_non_sealed_libs[] =
|
||||||
|
{
|
||||||
|
"[vdso]",
|
||||||
|
"tst-dl_mseal-no-memory-seal",
|
||||||
|
LIB_PRELOAD,
|
||||||
|
LIB_AUDIT,
|
||||||
|
"tst-dl_mseal-mod-no-memory-seal-2.so",
|
||||||
|
LIB_DLOPEN_DEFAULT,
|
||||||
|
LIB_DLOPEN_DEFAULT_DEP,
|
||||||
|
LIB_DLOPEN_NODELETE,
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "tst-dl_mseal-skeleton.c"
|
@ -1,4 +1,4 @@
|
|||||||
/* Basic tests for sealing. Static version.
|
/* Basic tests for sealing.
|
||||||
Copyright (C) 2024 Free Software Foundation, Inc.
|
Copyright (C) 2024 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ handle_restart (void)
|
|||||||
|
|
||||||
/* Also check if all the expected sealed maps were found. */
|
/* Also check if all the expected sealed maps were found. */
|
||||||
for (int i = 0; i < array_length (expected_sealed_libs); i++)
|
for (int i = 0; i < array_length (expected_sealed_libs); i++)
|
||||||
if (!found_expected[i])
|
if (expected_sealed_libs[i][0] && !found_expected[i])
|
||||||
FAIL_EXIT1 ("expected VMA %s not sealed\n", expected_sealed_libs[i]);
|
FAIL_EXIT1 ("expected VMA %s not sealed\n", expected_sealed_libs[i]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -239,7 +239,7 @@ do_test (int argc, char *argv[])
|
|||||||
spargv[i] = NULL;
|
spargv[i] = NULL;
|
||||||
|
|
||||||
char *envvarss[4];
|
char *envvarss[4];
|
||||||
envvarss[0] = (char *) "GLIBC_TUNABLES=glibc.rtld.seal=2";
|
envvarss[0] = (char *) "GLIBC_TUNABLES=glibc.rtld.seal=" GLIBC_RTLD_SEAL;
|
||||||
#ifndef TEST_STATIC
|
#ifndef TEST_STATIC
|
||||||
envvarss[1] = (char *) "LD_PRELOAD=" LIB_PRELOAD;
|
envvarss[1] = (char *) "LD_PRELOAD=" LIB_PRELOAD;
|
||||||
envvarss[2] = (char *) "LD_AUDIT=" LIB_AUDIT,
|
envvarss[2] = (char *) "LD_AUDIT=" LIB_AUDIT,
|
||||||
|
38
sysdeps/unix/sysv/linux/tst-dl_mseal-static-no-memory-seal.c
Normal file
38
sysdeps/unix/sysv/linux/tst-dl_mseal-static-no-memory-seal.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* Basic tests for sealing. Static version.
|
||||||
|
Copyright (C) 2024 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This test checks the GNU_PROPERTY_NO_MEMORY_SEAL handling on a statically
|
||||||
|
built binary. In this case only the vDSO (if existent) will be sealed. */
|
||||||
|
|
||||||
|
#define GLIBC_RTLD_SEAL "1"
|
||||||
|
#define TEST_STATIC 1
|
||||||
|
|
||||||
|
/* Expected libraries that loader will seal. */
|
||||||
|
static const char *expected_sealed_libs[] =
|
||||||
|
{
|
||||||
|
"",
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Expected non sealed libraries. */
|
||||||
|
static const char *expected_non_sealed_libs[] =
|
||||||
|
{
|
||||||
|
"[vdso]",
|
||||||
|
"tst-dl_mseal-static-no-memory-seal",
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "tst-dl_mseal-skeleton.c"
|
@ -19,6 +19,7 @@
|
|||||||
#ifndef _DL_PROP_H
|
#ifndef _DL_PROP_H
|
||||||
#define _DL_PROP_H
|
#define _DL_PROP_H
|
||||||
|
|
||||||
|
#include <dl-prop-mseal.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
|
|
||||||
extern void _dl_cet_check (struct link_map *, const char *)
|
extern void _dl_cet_check (struct link_map *, const char *)
|
||||||
@ -241,6 +242,9 @@ _dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
|
|||||||
uint32_t datasz, void *data)
|
uint32_t datasz, void *data)
|
||||||
{
|
{
|
||||||
/* This is called on each GNU property. */
|
/* This is called on each GNU property. */
|
||||||
|
if (_dl_process_gnu_property_seal (l, fd, type, datasz, data))
|
||||||
|
return 0;
|
||||||
|
|
||||||
unsigned int needed_1 = 0;
|
unsigned int needed_1 = 0;
|
||||||
unsigned int feature_1_and = 0;
|
unsigned int feature_1_and = 0;
|
||||||
unsigned int isa_1_needed = 0;
|
unsigned int isa_1_needed = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user