Merge branch 'freebsd/current/main' into hardened/current/master

This commit is contained in:
HardenedBSD Sync Services 2024-11-07 00:01:30 -07:00
commit 2b9c987a1b
No known key found for this signature in database
12 changed files with 250 additions and 36 deletions

View File

@ -275,6 +275,7 @@ MAN+= alarm.3 \
raise.3 \
rand48.3 \
readpassphrase.3 \
rtld_get_var.3 \
scandir.3 \
sem_destroy.3 \
sem_getvalue.3 \
@ -481,6 +482,8 @@ MLINKS+=rand48.3 _rand48.3 \
rand48.3 nrand48.3 \
rand48.3 seed48.3 \
rand48.3 srand48.3
MLINKS+=rtld_get_var.3 \
rtld_set_var.3
MLINKS+=scandir.3 alphasort.3 \
scandir.3 scandirat.3 \
scandir.3 scandir_b.3 \

View File

@ -456,6 +456,8 @@ FBSD_1.8 {
aio_read2;
aio_write2;
execvpe;
rtld_get_var;
rtld_set_var;
};
FBSDprivate_1.0 {

View File

@ -35,6 +35,7 @@
#include <sys/mman.h>
#include <machine/atomic.h>
#include <dlfcn.h>
#include <errno.h>
#include <link.h>
#include <stddef.h>
#include <string.h>
@ -345,4 +346,20 @@ _rtld_is_dlopened(void *arg __unused)
return (0);
}
#pragma weak rtld_get_var
const char *
rtld_get_var(const char *name __unused)
{
_rtld_error(sorry);
return (NULL);
}
#pragma weak rtld_set_var
int
rtld_set_var(const char *name __unused, const char *val __unused)
{
_rtld_error(sorry);
return (EINVAL);
}
#endif /* !defined(IN_LIBDL) || defined(PIC) */

106
lib/libc/gen/rtld_get_var.3 Normal file
View File

@ -0,0 +1,106 @@
.\" Copyright (c) 2024 The FreeBSD Foundation
.\"
.\" This documentation was written by
.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship
.\" from the FreeBSD Foundation.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd October 31, 2024
.Dt RTLD_GET_VAR 3
.Os
.Sh NAME
.Nm rtld_get_var ,
.Nm rtld_set_var
.Nd query or change run-time linker parameters after image activation
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In sys/errno.h
.In link.h
.Ft const char *
.Fn rtld_get_var "const char *name"
.Ft int
.Fn rtld_set_var "const char *name" "const char *value"
.Sh DESCRIPTION
The dynamic linker
.Xr rtld 1
can be configured be setting some environment variables for the process,
before image activation.
Sometimes it is desirable to query the current effective settings or
change them afterward.
.Pp
Since the process environment variables are maintained by higher-level
libraries, the run-time linker cannot access them after the image
activation.
The described functions make it possible to operate on rtld settings.
.Pp
The
.Fn rtld_get_var
function returns the current value of the named parameter.
.Pp
The
.Fn rtld_set_var
functions changes the value of the parameter to the new
.Fa value
value, if possible.
The
.Fa name
argument to both functions is the name of the parameter, which
is same as the corresponding environment variable
.Pq see Xr rtld 1
but without the
.Ev LD_
(or
.Ev LD_32_
or any other ABI-specific) prefix.
.Sh RETURN VALUES
The
.Fn rtld_get_var
returns the current value of the named parameter, or
.Dv NULL
if the name is invalid.
.Pp
The
.Fn rtld_set_var
returns 0 on success, or an integer indicating the error condition
which prevented the operation.
.Sh ERRORS
Possible errors returned from
.Fn rtld_set_var :
.Bl -tag -width Er
.It Bq Er EPERM
The requested change cannot be made at runtime, either because the
runtime linker can only take this parameter at initialization time,
or because the current process is executing with elevated privileges.
.It Bq ENOENT
The supplied parameter
.Fa name
is unknown.
.El
.Sh SEE ALSO
.Xr rtld 1
.Sh HISTORY
The
.Nm
function first appeared in
.Fx 15.0 .

View File

@ -17,3 +17,8 @@ FBSD_1.0 {
FBSD_1.3 {
fdlopen;
};
FBSD_1.8 {
rtld_get_var;
rtld_set_var;
};

View File

@ -21,6 +21,11 @@ FBSD_1.3 {
fdlopen;
};
FBSD_1.8 {
rtld_get_var;
rtld_set_var;
};
FBSDprivate_1.0 {
_rtld_thread_init;
_rtld_allocate_tls;

View File

@ -138,6 +138,15 @@ all the environment variables listed below, but is being prefixed with
for example:
.Ev LD_32_TRACE_LOADED_OBJECTS .
If the activated image is setuid or setgid, the variables are ignored.
.Pp
The run-time linker is able to access the environment provided
at process startup.
After startup, environment variables are maintained by higher-level
libraries and are not accessible by the run-time linker.
At run-time, effective settings can be queried using
.Xr rtld_get_var 3 ,
and some of them can be changed with
.Xr rtld_set_var 3 .
.Bl -tag -width ".Ev LD_LIBMAP_DISABLE"
.It Ev LD_DUMP_REL_POST
If set,
@ -527,6 +536,7 @@ The libmap configuration file for 32-bit binaries on 64-bit system.
.Xr ld 1 ,
.Xr ldd 1 ,
.Xr dlinfo 3 ,
.Xr rtld_get_var 3 ,
.Xr capsicum 4 ,
.Xr elf 5 ,
.Xr libmap.conf 5 ,

View File

@ -278,6 +278,8 @@ int _rtld_get_stack_prot(void) __exported;
Elf_Word _rtld_get_pax_flags(void) __exported;
int _rtld_is_dlopened(void *) __exported;
void _rtld_error(const char *, ...) __exported;
const char *rtld_get_var(const char *name) __exported;
int rtld_set_var(const char *name, const char *val) __exported;
/* Only here to fix -Wmissing-prototypes warnings */
int __getosreldate(void);
@ -386,29 +388,36 @@ ld_utrace_log(int event, void *handle, void *mapbase, size_t mapsize,
struct ld_env_var_desc {
const char * const n;
const char *val;
const bool unsecure;
const bool unsecure:1;
const bool can_update:1;
const bool debug:1;
bool owned:1;
};
#define LD_ENV_DESC(var, unsec) \
[LD_##var] = { .n = #var, .unsecure = unsec }
#define LD_ENV_DESC(var, unsec, ...) \
[LD_##var] = { \
.n = #var, \
.unsecure = unsec, \
__VA_ARGS__ \
}
static struct ld_env_var_desc ld_env_vars[] = {
LD_ENV_DESC(BIND_NOW, false),
LD_ENV_DESC(PRELOAD, true),
LD_ENV_DESC(LIBMAP, true),
LD_ENV_DESC(LIBRARY_PATH, true),
LD_ENV_DESC(LIBRARY_PATH_FDS, true),
LD_ENV_DESC(LIBRARY_PATH, true, .can_update = true),
LD_ENV_DESC(LIBRARY_PATH_FDS, true, .can_update = true),
LD_ENV_DESC(LIBMAP_DISABLE, true),
LD_ENV_DESC(BIND_NOT, true),
LD_ENV_DESC(DEBUG, true),
LD_ENV_DESC(DEBUG, true, .can_update = true, .debug = true),
LD_ENV_DESC(ELF_HINTS_PATH, true),
LD_ENV_DESC(LOADFLTR, true),
LD_ENV_DESC(LIBRARY_PATH_RPATH, true),
LD_ENV_DESC(LIBRARY_PATH_RPATH, true, .can_update = true),
LD_ENV_DESC(PRELOAD_FDS, true),
LD_ENV_DESC(DYNAMIC_WEAK, true),
LD_ENV_DESC(DYNAMIC_WEAK, true, .can_update = true),
LD_ENV_DESC(TRACE_LOADED_OBJECTS, false),
LD_ENV_DESC(UTRACE, false),
LD_ENV_DESC(DUMP_REL_PRE, false),
LD_ENV_DESC(DUMP_REL_POST, false),
LD_ENV_DESC(UTRACE, false, .can_update = true),
LD_ENV_DESC(DUMP_REL_PRE, false, .can_update = true),
LD_ENV_DESC(DUMP_REL_POST, false, .can_update = true),
LD_ENV_DESC(TRACE_LOADED_OBJECTS_PROGNAME, false),
LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT1, false),
LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT2, false),
@ -6520,6 +6529,46 @@ dump_auxv(Elf_Auxinfo **aux_info)
}
}
const char *
rtld_get_var(const char *name)
{
const struct ld_env_var_desc *lvd;
u_int i;
for (i = 0; i < nitems(ld_env_vars); i++) {
lvd = &ld_env_vars[i];
if (strcmp(lvd->n, name) == 0)
return (lvd->val);
}
return (NULL);
}
int
rtld_set_var(const char *name, const char *val)
{
struct ld_env_var_desc *lvd;
u_int i;
for (i = 0; i < nitems(ld_env_vars); i++) {
lvd = &ld_env_vars[i];
if (strcmp(lvd->n, name) != 0)
continue;
if (!lvd->can_update || (lvd->unsecure && !trust))
return (EPERM);
if (lvd->owned)
free(__DECONST(char *, lvd->val));
if (val != NULL)
lvd->val = xstrdup(val);
else
lvd->val = NULL;
lvd->owned = true;
if (lvd->debug)
debug = lvd->val != NULL && *lvd->val != '\0';
return (0);
}
return (ENOENT);
}
/*
* Overrides for libc_pic-provided functions.
*/

View File

@ -1686,20 +1686,19 @@ static s32 e1000_get_media_type_82575(struct e1000_hw *hw)
break;
}
/* do not change link mode for 100BaseFX */
if (dev_spec->eth_flags.e100_base_fx)
break;
/* change current link mode setting */
ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
if (hw->phy.media_type == e1000_media_type_copper)
if (dev_spec->sgmii_active)
ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII;
else
ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
break;
default:
DEBUGOUT("e1000_get_media_type_82575 unknown link type\n");
break;
}
@ -1750,24 +1749,27 @@ static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw)
/* Check if there is some SFP module plugged and powered */
if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) ||
(tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) {
(tranceiver_type == E1000_SFF_IDENTIFIER_SFF))
dev_spec->module_plugged = true;
if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) {
hw->phy.media_type = e1000_media_type_internal_serdes;
} else if (eth_flags->e100_base_fx) {
dev_spec->sgmii_active = true;
hw->phy.media_type = e1000_media_type_internal_serdes;
} else if (eth_flags->e1000_base_t) {
dev_spec->sgmii_active = true;
hw->phy.media_type = e1000_media_type_copper;
} else {
hw->phy.media_type = e1000_media_type_unknown;
DEBUGOUT("PHY module has not been recognized\n");
goto out;
}
else
DEBUGOUT("PHY module is not SFP/SFF %x\n", tranceiver_type);
if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) {
hw->phy.media_type = e1000_media_type_internal_serdes;
DEBUGOUT("PHY module is 1000_base_lxsx\n");
} else if (eth_flags->e100_base_fx || eth_flags->e100_base_lx) {
dev_spec->sgmii_active = true;
hw->phy.media_type = e1000_media_type_internal_serdes;
DEBUGOUT("PHY module is 100_base_fxlx\n");
} else if (eth_flags->e1000_base_t) {
dev_spec->sgmii_active = true;
hw->phy.media_type = e1000_media_type_copper;
DEBUGOUT("PHY module is 1000_base_t\n");
} else {
hw->phy.media_type = e1000_media_type_unknown;
DEBUGOUT("PHY module has not been recognized\n");
}
ret_val = E1000_SUCCESS;
out:
/* Restore I2C interface setting */

View File

@ -93,11 +93,13 @@ struct dl_phdr_info
__BEGIN_DECLS
typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t, void *);
extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *);
int dl_iterate_phdr(__dl_iterate_hdr_callback, void *);
int _rtld_addr_phdr(const void *, struct dl_phdr_info *);
Elf_Word _rtld_get_pax_flags(void);
int _rtld_get_stack_prot(void);
int _rtld_is_dlopened(void *);
const char *rtld_get_var(const char *name);
int rtld_set_var(const char *name, const char *val);
#ifdef __ARM_EABI__
void * dl_unwind_find_exidx(const void *, int *);

View File

@ -137,10 +137,8 @@ main(int argc, char *argv[])
break;
case 'e':
eflag = 1;
if ((temp_arg = malloc(strlen(optarg) + 2)) == NULL)
err(1, "malloc");
strcpy(temp_arg, optarg);
strcat(temp_arg, "\n");
if (asprintf(&temp_arg, "%s\n", optarg) == -1)
err(1, "asprintf");
add_compunit(CU_STRING, temp_arg);
break;
case 'f':
@ -173,7 +171,9 @@ main(int argc, char *argv[])
/* First usage case; script is the first arg */
if (!eflag && !fflag && *argv) {
add_compunit(CU_STRING, *argv);
if (asprintf(&temp_arg, "%s\n", *argv) == -1)
err(1, "asprintf");
add_compunit(CU_STRING, temp_arg);
argv++;
}

View File

@ -147,6 +147,18 @@ bracket_y_body()
echo 'bra[ke]' | sed 'y[\[][ct['
}
atf_test_case minus_e
minus_e_head()
{
atf_set "descr" "Verify that -e and implicit arg do the same thing"
}
minus_e_body()
{
printf "ab\n" > a
atf_check -o 'inline:--\nab\n' sed -e $'1 i\\\n--' a
atf_check -o 'inline:--\nab\n' sed $'1 i\\\n--' a
}
atf_init_test_cases()
{
atf_add_test_case inplace_command_q
@ -156,4 +168,5 @@ atf_init_test_cases()
atf_add_test_case commands_on_stdin
atf_add_test_case hex_subst
atf_add_test_case bracket_y
atf_add_test_case minus_e
}