Unverified Commit 3430f024 authored by Shawn Webb's avatar Shawn Webb
Browse files

Merge remote-tracking branch 'upstream/stable/12' into hardened/12-stable/master

parents 2c1bca49 37c18e6c
......@@ -143,12 +143,18 @@ dtrace_dof_init(void)
return;
}
#ifdef __FreeBSD__
elf = (void *)lmp->l_base;
#else
elf = (void *)lmp->l_addr;
#endif
dh.dofhp_dof = (uintptr_t)dof;
dh.dofhp_addr = elf->e_type == ET_DYN ? (uintptr_t) lmp->l_addr : 0;
#ifdef __FreeBSD__
dh.dofhp_addr = elf->e_type == ET_DYN ? (uintptr_t) lmp->l_base : 0;
dh.dofhp_pid = getpid();
#else
dh.dofhp_addr = elf->e_type == ET_DYN ? (uintptr_t) lmp->l_addr : 0;
#endif
if (lmid == 0) {
......
......@@ -1358,14 +1358,18 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
drv = bsd_get_drvindex(global, ifm->ifm_index);
if (drv == NULL)
return;
if ((ifm->ifm_flags & IFF_UP) == 0 &&
(drv->flags & IFF_UP) != 0) {
if (((ifm->ifm_flags & IFF_UP) == 0 ||
(ifm->ifm_flags & IFF_RUNNING) == 0) &&
(drv->flags & IFF_UP) != 0 &&
(drv->flags & IFF_RUNNING) != 0) {
wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
drv->ifname);
wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED,
NULL);
} else if ((ifm->ifm_flags & IFF_UP) != 0 &&
(drv->flags & IFF_UP) == 0) {
(ifm->ifm_flags & IFF_RUNNING) != 0 &&
((drv->flags & IFF_UP) == 0 ||
(drv->flags & IFF_RUNNING) == 0)) {
wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP",
drv->ifname);
wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
......
/* $FreeBSD$ */
#if __STDC__
#error "<malloc.h> has been replaced by <stdlib.h>"
#else
/*-
* This file is in the public domain.
* $FreeBSD$
*/
#include <stdlib.h>
#endif
#include <malloc_np.h>
......@@ -122,6 +122,9 @@ size_t __sallocx(const void *ptr, int flags);
void __dallocx(void *ptr, int flags);
void __sdallocx(void *ptr, size_t size, int flags);
size_t __nallocx(size_t size, int flags);
void *memalign(size_t, size_t) __malloc_like __alloc_align(1)
__alloc_size(2);
__END_DECLS
#undef __MyBool
......
......@@ -90,6 +90,7 @@ SRCS+= __getosreldate.c \
libc_dlopen.c \
lockf.c \
lrand48.c \
memalign.c \
mrand48.c \
nftw.c \
nice.c \
......
......@@ -423,6 +423,7 @@ FBSD_1.5 {
};
FBSD_1.6 {
memalign;
sigandset;
sigisemptyset;
sigorset;
......
......@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 14, 2003
.Dd May 21, 2020
.Dt DLINFO 3
.Os
.Sh NAME
......@@ -105,14 +105,16 @@ structure is defined in
.In link.h
and has the following members:
.Bd -literal -offset indent
caddr_t l_addr; /* Base Address of library */
caddr_t l_base; /* Base Address of library */
const char *l_name; /* Absolute Path to Library */
const void *l_ld; /* Pointer to .dynamic in memory */
struct link_map *l_next, /* linked list of mapped libs */
*l_prev;
caddr_t l_addr; /* Load Offset of library */
const char *l_refname; /* Object this one filters for */
.Ed
.Bl -tag -width ".Va l_addr"
.It Va l_addr
.It Va l_base
The base address of the object loaded into memory.
.It Va l_name
The full name of the loaded shared object.
......@@ -128,6 +130,15 @@ structure on the link-map list.
The previous
.Vt Link_map
structure on the link-map list.
.It Va l_addr
The load offset of the object, that is, the difference between
the actual load address and the base virtual address the object
was linked at.
.It Va l_refname
A name of the object this object filters for, if any.
If there are more then one filtee, a name from the first
.Dv DT_FILTER
dynamic entry is supplied.
.El
.It Dv RTLD_DI_SERINFO
Retrieve the library search paths associated with the given
......
/*-
* Copyright (c) 2020 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Konstantin Belousov
* 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 AUTHOR 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 AUTHOR 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <stdlib.h>
void *
memalign(size_t align, size_t size)
{
return (aligned_alloc(align, roundup(size, align)));
}
......@@ -270,9 +270,6 @@ ATF_TC_BODY(symbol_lookup, tc)
u_long saved;
int error;
if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
atf_tc_skip("https://bugs.freebsd.org/244732");
phdl = start_prog(tc, false);
error = proc_name2sym(phdl, target_prog_file, "main", &main_sym, NULL);
......
......@@ -160,9 +160,12 @@ rd_err_e
rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data)
{
struct kinfo_vmentry *kves, *kve;
const char *path;
uint64_t fileid;
rd_loadobj_t rdl;
rd_err_e ret;
int cnt, i, lastvn;
uintptr_t base;
int cnt, i;
DPRINTF("%s\n", __func__);
......@@ -171,27 +174,38 @@ rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data)
return (RD_ERR);
}
base = 0;
fileid = 0;
path = NULL;
ret = RD_OK;
lastvn = 0;
for (i = 0; i < cnt; i++) {
kve = kves + i;
if (kve->kve_type == KVME_TYPE_VNODE)
lastvn = i;
kve = &kves[i];
/*
* Cache the base offset of the file mapping. The kve_offset
* field gives the file offset of a particular mapping into the
* file, but we want the mapping offset relative to the base
* mapping.
*/
if (kve->kve_type == KVME_TYPE_VNODE &&
kve->kve_vn_fileid != fileid) {
base = kve->kve_start;
fileid = kve->kve_vn_fileid;
path = kve->kve_path;
}
memset(&rdl, 0, sizeof(rdl));
/*
* Map the kinfo_vmentry struct to the rd_loadobj structure.
*/
rdl.rdl_saddr = kve->kve_start;
rdl.rdl_eaddr = kve->kve_end;
rdl.rdl_offset = kve->kve_offset;
rdl.rdl_offset = kve->kve_start - base;
if (kve->kve_protection & KVME_PROT_READ)
rdl.rdl_prot |= RD_RDL_R;
if (kve->kve_protection & KVME_PROT_WRITE)
rdl.rdl_prot |= RD_RDL_W;
if (kve->kve_protection & KVME_PROT_EXEC)
rdl.rdl_prot |= RD_RDL_X;
strlcpy(rdl.rdl_path, kves[lastvn].kve_path,
sizeof(rdl.rdl_path));
strlcpy(rdl.rdl_path, path, sizeof(rdl.rdl_path));
if ((*cb)(&rdl, clnt_data) != 0) {
ret = RD_ERR;
break;
......
......@@ -32,4 +32,6 @@ FBSDprivate_1.0 {
_rtld_get_stack_prot;
_rtld_is_dlopened;
_r_debug_postinit;
_rtld_version__FreeBSD_version;
_rtld_version_laddr_offset;
};
......@@ -355,6 +355,54 @@ ignores
and is naturally prone to race conditions.
Environments which rely on such restrictions are weak
and breakable on their own.
.Sh VERSIONING
Newer
.Nm
might provide some features or changes in runtime behavior that cannot be
easily detected at runtime by checking of the normal exported symbols.
Note that it is almost always wrong to verify
.Dv __FreeBSD_version
in userspace to detect features, either at compile or at run time,
because either kernel, or libc, or environment variables could not
match the running
.Nm .
.Pp
To solve the problem,
.Nm
exports some feature indicators in the
.Fx
private symbols namespace
.Dv FBSDprivate_1.0 .
Symbols start with the
.Dv _rtld_version
prefix.
Current list of defined symbols and corresponding features is:
.Bl -tag -width indent
.It Dv _rtld_version__FreeBSD_version
Symbol exports the value of the
.Dv __FreeBSD_version
definition as it was provided during the
.Nm
build.
The symbol is always present since the
.Dv _rtld_version
facility was introduced.
.It Dv _rtld_version_laddr_offset
The
.Va l_addr
member of the
.Vt link_map
structure contains the load offset of the shared object.
Before that,
.Va l_addr
contained the base address of the library.
See
.Xr dlinfo 3 .
.Pp
Also it indicates the presence of
.Va l_refname
member of the structure.
.El
.Sh FILES
.Bl -tag -width ".Pa /var/run/ld-elf32.so.hints" -compact
.It Pa /var/run/ld-elf.so.hints
......@@ -369,6 +417,7 @@ The libmap configuration file for 32-bit binaries on 64-bit system.
.Sh SEE ALSO
.Xr ld 1 ,
.Xr ldd 1 ,
.Xr dlinfo 3 ,
.Xr capsicum 4 ,
.Xr elf 5 ,
.Xr libmap.conf 5 ,
......
......@@ -1198,6 +1198,9 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
*needed_filtees_tail = nep;
needed_filtees_tail = &nep->next;
if (obj->linkmap.l_refname == NULL)
obj->linkmap.l_refname = (char *)dynp->d_un.d_val;
}
break;
......@@ -1380,6 +1383,10 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
}
obj->dynsymcount += obj->symndx_gnu;
}
if (obj->linkmap.l_refname != NULL)
obj->linkmap.l_refname = obj->strtab + (unsigned long)obj->
linkmap.l_refname;
}
static bool
......@@ -4089,52 +4096,50 @@ rtld_dirname_abs(const char *path, char *base)
static void
linkmap_add(Obj_Entry *obj)
{
struct link_map *l = &obj->linkmap;
struct link_map *prev;
struct link_map *l, *prev;
obj->linkmap.l_name = obj->path;
obj->linkmap.l_addr = obj->mapbase;
obj->linkmap.l_ld = obj->dynamic;
#ifdef __mips__
/* GDB needs load offset on MIPS to use the symbols */
obj->linkmap.l_offs = obj->relocbase;
#endif
l = &obj->linkmap;
l->l_name = obj->path;
l->l_base = obj->mapbase;
l->l_ld = obj->dynamic;
l->l_addr = obj->relocbase;
if (r_debug.r_map == NULL) {
r_debug.r_map = l;
return;
}
if (r_debug.r_map == NULL) {
r_debug.r_map = l;
return;
}
/*
* Scan to the end of the list, but not past the entry for the
* dynamic linker, which we want to keep at the very end.
*/
for (prev = r_debug.r_map;
prev->l_next != NULL && prev->l_next != &obj_rtld.linkmap;
prev = prev->l_next)
;
/*
* Scan to the end of the list, but not past the entry for the
* dynamic linker, which we want to keep at the very end.
*/
for (prev = r_debug.r_map;
prev->l_next != NULL && prev->l_next != &obj_rtld.linkmap;
prev = prev->l_next)
;
/* Link in the new entry. */
l->l_prev = prev;
l->l_next = prev->l_next;
if (l->l_next != NULL)
l->l_next->l_prev = l;
prev->l_next = l;
/* Link in the new entry. */
l->l_prev = prev;
l->l_next = prev->l_next;
if (l->l_next != NULL)
l->l_next->l_prev = l;
prev->l_next = l;
}
static void
linkmap_delete(Obj_Entry *obj)
{
struct link_map *l = &obj->linkmap;
struct link_map *l;
if (l->l_prev == NULL) {
if ((r_debug.r_map = l->l_next) != NULL)
l->l_next->l_prev = NULL;
return;
}
l = &obj->linkmap;
if (l->l_prev == NULL) {
if ((r_debug.r_map = l->l_next) != NULL)
l->l_next->l_prev = NULL;
return;
}
if ((l->l_prev->l_next = l->l_next) != NULL)
l->l_next->l_prev = l->l_prev;
if ((l->l_prev->l_next = l->l_next) != NULL)
l->l_next->l_prev = l->l_prev;
}
/*
......@@ -5883,3 +5888,9 @@ realloc(void *cp, size_t nbytes)
return (__crt_realloc(cp, nbytes));
}
extern int _rtld_version__FreeBSD_version __exported;
int _rtld_version__FreeBSD_version = __FreeBSD_version;
extern char _rtld_version_laddr_offset __exported;
char _rtld_version_laddr_offset;
......@@ -308,10 +308,10 @@ kz.kst.kbd:da:Kasakhisk
kz.kst.kbd:de:Kasachisch
kz.kst.kbd:fr:Kazakh
kz.io.kbd:en:Kazakh
kz.io.kbd:da:Kasakhisk
kz.io.kbd:de:Kasachisch
kz.io.kbd:fr:Kazakh
kz.io.kbd:en:Kazakh (with IO)
kz.io.kbd:da:Kasakhisk (IO)
kz.io.kbd:de:Kasachisch (mit IO)
kz.io.kbd:fr:Kazakh (avec IO)
latinamerican.kbd:en:Latin American
latinamerican.kbd:da:Latinamerikansk
......@@ -411,6 +411,13 @@ es.dvorak.kbd:fr:Espagnol Dvorak
es.dvorak.kbd:pt:Espanhol Dvorak
es.dvorak.kbd:es:Español Dvorak
es.kbd:en:Spanish
es.kbd:da:Spansk
es.kbd:de:Spanisch
es.kbd:fr:Espagnol
es.kbd:pt:Espanhol
es.kbd:es:Español
es.acc.kbd:en:Spanish (accent keys)
es.acc.kbd:da:Spansk (accenttaster)
es.acc.kbd:de:Spanisch (accent keys)
......@@ -418,13 +425,6 @@ es.acc.kbd:fr:Espagnol (avec accents)
es.acc.kbd:pt:Espanhol (com acentos)
es.acc.kbd:es:Español (con acentos)
es.kbd:en:Spanish (accent keys)
es.kbd:da:Spansk (accenttaster)
es.kbd:de:Spanisch (accent keys)
es.kbd:fr:Espagnol (avec accents)
es.kbd:pt:Espanhol (com acentos)
es.kbd:es:Español (con acentos)
si.kbd:en:Slovenian
si.kbd:da:Slovensk
si.kbd:de:Slovenisch
......
......@@ -45,8 +45,17 @@ __FBSDID("$FreeBSD$");
void
interact(void)
{
static char input[256]; /* big enough? */
static char input[256]; /* big enough? */
const char * volatile interp_identifier;
/*
* Because interp_identifier is volatile, it cannot be optimized out by
* the compiler as it's considered an externally observable event. This
* prevents the compiler from optimizing out our carefully placed
* $Interpreter:4th string that userboot may use to determine that
* we need to switch interpreters.
*/
interp_identifier = bootprog_interp;
interp_init();
printf("\n");
......
......@@ -233,6 +233,8 @@ done_load_dr:
movq %rax,(%rsp)
movq PCPU(CURTHREAD),%rdi
call fpu_activate_sw
cmpb $0,cpu_flush_rsb_ctxsw(%rip)
jne rsb_flush
ret
/*
......
......@@ -269,12 +269,24 @@ initializecpu(void)
cr4 |= CR4_PKE;
/*
* If SMEP is present, we only need to flush RSB (by default)
* on context switches, to prevent cross-process ret2spec
* attacks. Do it automatically if ibrs_disable is set, to
* complete the mitigation.
*
* Postpone enabling the SMEP on the boot CPU until the page
* tables are switched from the boot loader identity mapping
* to the kernel tables. The boot loader enables the U bit in
* its tables.
*/
if (!IS_BSP()) {
if (IS_BSP()) {
if (cpu_stdext_feature & CPUID_STDEXT_SMEP &&
!TUNABLE_INT_FETCH(
"machdep.mitigations.cpu_flush_rsb_ctxsw",
&cpu_flush_rsb_ctxsw) &&
hw_ibrs_disable)
cpu_flush_rsb_ctxsw = 1;
} else {
if (cpu_stdext_feature & CPUID_STDEXT_SMEP)
cr4 |= CR4_SMEP;
if (cpu_stdext_feature & CPUID_STDEXT_SMAP)
......
......@@ -1528,23 +1528,27 @@ ENTRY(pmap_pti_pcid_invlrng)
retq
.altmacro
.macro ibrs_seq_label l
handle_ibrs_\l:
.macro rsb_seq_label l
rsb_seq_\l:
.endm
.macro ibrs_call_label l
call handle_ibrs_\l
.macro rsb_call_label l
call rsb_seq_\l
.endm
.macro ibrs_seq count
.macro rsb_seq count
ll=1
.rept \count
ibrs_call_label %(ll)
rsb_call_label %(ll)
nop
ibrs_seq_label %(ll)
rsb_seq_label %(ll)
addq $8,%rsp
ll=ll+1
.endr
.endm
ENTRY(rsb_flush)
rsb_seq 32
ret
/* all callers already saved %rax, %rdx, and %rcx */
ENTRY(handle_ibrs_entry)
cmpb $0,hw_ibrs_ibpb_active(%rip)
......@@ -1556,8 +1560,7 @@ ENTRY(handle_ibrs_entry)
wrmsr
movb $1,PCPU(IBPB_SET)
testl $CPUID_STDEXT_SMEP,cpu_stdext_feature(%rip)
jne 1f
ibrs_seq 32
je rsb_flush
1: ret
END(handle_ibrs_entry)
......
......@@ -445,6 +445,28 @@ msr_onfault:
movl $EFAULT,%eax
ret
.altmacro
.macro rsb_seq_label l
rsb_seq_\l:
.endm
.macro rsb_call_label l
call rsb_seq_\l
.endm
.macro rsb_seq count
ll=1
.rept \count
rsb_call_label %(ll)
nop
rsb_seq_label %(ll)
addl $4,%esp
ll=ll+1
.endr
.endm
ENTRY(rsb_flush)
rsb_seq 32
ret
ENTRY(handle_ibrs_entry)
cmpb $0,hw_ibrs_ibpb_active
je 1f
......@@ -455,10 +477,9 @@ ENTRY(handle_ibrs_entry)
wrmsr
movb $1,PCPU(IBPB_SET)
/*
* i386 does not implement SMEP, but the 4/4 split makes this not
* that important.
* i386 does not implement SMEP.
*/
1: ret
1: jmp rsb_flush
END(handle_ibrs_entry)
ENTRY(handle_ibrs_exit)
......
......@@ -371,8 +371,7 @@ linker_file_register_modules(linker_file_t lf)
sx_assert(&kld_sx, SA_XLOCKED);