sync with OpenBSD -current

This commit is contained in:
purplerain 2024-03-13 18:28:34 +00:00
parent 25869dc67a
commit 14b4e966dd
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
10 changed files with 311 additions and 124 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2012-2020 Alexander Bluhm <bluhm@openbsd.org>
Copyright (c) 2012-2024 Alexander Bluhm <bluhm@openbsd.org>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.29 2023/09/08 21:15:02 bluhm Exp $
# $OpenBSD: Makefile,v 1.30 2024/03/12 21:31:29 bluhm Exp $
# The following ports must be installed:
#
@ -88,7 +88,11 @@ stamp-pf: addr.py pf.conf
FRAG6_SCRIPTS !!= cd ${.CURDIR} && ls -1 frag6*.py
run-stack-frag6_queuelimit.py:
# the stack does not limit the amount of fragments during reassembly
# stack does not limit the amount of fragments during reassembly
@echo DISABLED
run-pf-frag6_oversize.py run-pf-frag6_unfragsize.py:
# pf does not send icmp parameter problem, so test does not work
@echo DISABLED
run-stack-frag6_doubleatomic.py: addr.py stamp-stack

View File

@ -0,0 +1,65 @@
#!/usr/local/bin/python3
print("ping6 fragments in total larger than IP maximum packet")
# |---------|
# |--------|
# ... ...
# |--------|
import os
from addr import *
from scapy.all import *
pid=os.getpid()
eid=pid & 0xffff
payload=b"ABCDEFGHIJKLMNOP"
packet=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/ \
ICMPv6EchoRequest(id=eid, data=4095*payload)
plen=IPv6(raw(packet)).plen
print("plen=%u" % (plen))
if plen != 0xfff8:
print("PLEN!=%u" % (0xfff8))
exit(2)
bytes=bytes(packet)+b"12345678"
frag=[]
fid=pid & 0xffffffff
frag.append(IPv6ExtHdrFragment(nh=58, id=fid, m=1)/bytes[40:40+2**10])
off=2**7
while off < 2**13:
frag.append(IPv6ExtHdrFragment(nh=58, id=fid, offset=off)/ \
bytes[40+off*8:40+off*8+2**10])
off+=2**7
eth=[]
for f in frag:
pkt=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/f
eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/pkt)
if os.fork() == 0:
time.sleep(1)
sendp(eth, iface=LOCAL_IF)
os._exit(0)
ans=sniff(iface=LOCAL_IF, timeout=3, filter=
"ip6 and src "+REMOTE_ADDR6+" and dst "+LOCAL_ADDR6+" and icmp6")
for a in ans:
print("type %d" % (a.payload.payload.type))
print("icmp %s" % (icmp6types[a.payload.payload.type]))
if a and a.type == ETH_P_IPV6 and \
ipv6nh[a.payload.nh] == 'ICMPv6' and \
icmp6types[a.payload.payload.type] == 'Parameter problem':
print("code=%u" % (a.payload.payload.code))
# 0: 'erroneous header field encountered'
if a.payload.payload.code != 0:
print("WRONG PARAMETER PROBLEM CODE")
exit(1)
ptr=a.payload.payload.ptr
print("ptr=%u" % (ptr))
# 42: sizeof IPv6 header + offset in fragment header
if ptr != 42:
print("PTR!=%u" % (ptr))
exit(1)
exit(0)
print("NO ICMP PARAMETER PROBLEM")
exit(2)

View File

@ -0,0 +1,77 @@
#!/usr/local/bin/python3
print("ping6 fragments with options total larger than IP maximum packet")
# |--------|
# ... ...
# |--------|
# drop first fragment with ECN conflict, reinsert with longer unfrag part
# |---------|
# HopByHop|---------|
import os
from addr import *
from scapy.all import *
pid=os.getpid()
eid=pid & 0xffff
payload=b"ABCDEFGHIJKLMNOP"
packet=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/ \
ICMPv6EchoRequest(id=eid, data=4095*payload)
plen=IPv6(raw(packet)).plen
print("plen=%u" % (plen))
if plen != 0xfff8:
print("PLEN!=%u" % (0xfff8))
exit(2)
bytes=bytes(packet)
frag=[]
fid=pid & 0xffffffff
off=2**7
while off < 2**13:
frag.append(IPv6ExtHdrFragment(nh=58, id=fid, offset=off)/ \
bytes[40+off*8:40+off*8+2**10])
off+=2**7
eth=[]
for f in frag:
pkt=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/f
eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/pkt)
# first fragment with ECN to be dropped
eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/
IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6, tc=3)/
IPv6ExtHdrFragment(nh=58, id=fid, m=1)/bytes[40:40+2**10])
# resend first fragment with unfragmentable part too long for IP plen
eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/
IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/
IPv6ExtHdrHopByHop(options=PadN(optdata="\0"*4))/
IPv6ExtHdrFragment(nh=58, id=fid, m=1)/bytes[40:40+2**10])
if os.fork() == 0:
time.sleep(1)
sendp(eth, iface=LOCAL_IF)
os._exit(0)
ans=sniff(iface=LOCAL_IF, timeout=3, filter=
"ip6 and src "+REMOTE_ADDR6+" and dst "+LOCAL_ADDR6+" and icmp6")
for a in ans:
print("type %d" % (a.payload.payload.type))
print("icmp %s" % (icmp6types[a.payload.payload.type]))
if a and a.type == ETH_P_IPV6 and \
ipv6nh[a.payload.nh] == 'ICMPv6' and \
icmp6types[a.payload.payload.type] == 'Parameter problem':
print("code=%u" % (a.payload.payload.code))
# 0: 'erroneous header field encountered'
if a.payload.payload.code != 0:
print("WRONG PARAMETER PROBLEM CODE")
exit(1)
ptr=a.payload.payload.ptr
print("ptr=%u" % (ptr))
# 42: sizeof IPv6 header + offset in fragment header
if ptr != 42:
print("PTR!=%u" % (ptr))
exit(1)
exit(0)
print("NO ICMP PARAMETER PROBLEM")
exit(2)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: gadget.S,v 1.1 2023/01/09 11:50:01 anton Exp $ */
/* $OpenBSD: gadget.S,v 1.2 2024/03/13 11:18:42 kettenis Exp $ */
#include <sys/syscall.h>
#include <machine/asm.h>
@ -12,11 +12,13 @@
.type gadget_getpid,_ASM_TYPE_FUNCTION
gadget_getpid:
#if defined(__amd64__)
endbr64
mov $SYS_getpid, %eax
syscall
ret
#elif defined(__aarch64__)
ldr x8, #SYS_getpid
bti c
mov x8, #SYS_getpid
svc 0
dsb nsh
isb

View File

@ -1,4 +1,4 @@
/* $OpenBSD: machdep.c,v 1.86 2024/02/21 01:45:14 dlg Exp $ */
/* $OpenBSD: machdep.c,v 1.87 2024/03/13 14:57:08 kettenis Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
@ -366,6 +366,7 @@ cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
return sysctl_rdquad(oldp, oldlenp, newp, value);
case CPU_ID_AA64PFR1:
value = 0;
value |= cpu_id_aa64pfr1 & ID_AA64PFR1_BT_MASK;
value |= cpu_id_aa64pfr1 & ID_AA64PFR1_SBSS_MASK;
return sysctl_rdquad(oldp, oldlenp, newp, value);
case CPU_ID_AA64ISAR2:

View File

@ -1,4 +1,4 @@
# $OpenBSD: GENERIC,v 1.294 2024/03/10 13:25:10 jsg Exp $
# $OpenBSD: GENERIC,v 1.295 2024/03/13 14:43:31 bluhm Exp $
#
# Machine-independent option; used by all architectures for their
# GENERIC kernel
@ -16,7 +16,7 @@ option KMEMSTATS # collect malloc(9) statistics
option PTRACE # ptrace(2) system call
#option KVA_GUARDPAGES # slow virtual address recycling (+ guarding)
#option POOL_DEBUG # pool corruption detection
option POOL_DEBUG # pool corruption detection
#option VFSLCKDEBUG # VFS locking checks
option CRYPTO # Cryptographic framework

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dt_prov_profile.c,v 1.6 2024/02/09 17:42:18 cheloha Exp $ */
/* $OpenBSD: dt_prov_profile.c,v 1.7 2024/03/13 13:13:57 bluhm Exp $ */
/*
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
@ -53,13 +53,13 @@ int
dt_prov_profile_init(void)
{
dtpp_profile = dt_dev_alloc_probe("hz", "97", &dt_prov_profile);
dt_dev_register_probe(dtpp_profile);
if (dtpp_profile == NULL)
return 0;
dt_dev_register_probe(dtpp_profile);
dtpp_interval = dt_dev_alloc_probe("hz", "1", &dt_prov_interval);
dt_dev_register_probe(dtpp_interval);
if (dtpp_interval == NULL)
return 1;
dt_dev_register_probe(dtpp_interval);
return 2;
}

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: tmux.1,v 1.936 2024/02/13 08:10:23 nicm Exp $
.\" $OpenBSD: tmux.1,v 1.937 2024/03/13 11:25:50 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: February 13 2024 $
.Dd $Mdocdate: March 13 2024 $
.Dt TMUX 1
.Os
.Sh NAME
@ -1036,9 +1036,17 @@ The following commands are available to manage clients and sessions:
.D1 Pq alias: Ic attach
If run from outside
.Nm ,
create a new client in the current terminal and attach it to
attach to
.Ar target-session
in the current terminal.
.Ar target-session
must already exist - to create a new session, see the
.Ic new-session
command (with
.Fl A
to create or attach).
If used from inside, switch the currently attached session to
.Ar target-session .
If used from inside, switch the current client.
If
.Fl d
is specified, any other clients attached to the session are detached.

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ksyms.c,v 1.6 2023/11/10 18:56:21 jasper Exp $ */
/* $OpenBSD: ksyms.c,v 1.7 2024/03/12 17:22:24 cheloha Exp $ */
/*
* Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
@ -23,6 +23,7 @@
#include <err.h>
#include <fcntl.h>
#include <gelf.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -30,60 +31,149 @@
#include "btrace.h"
struct syms {
int fd;
Elf *elf;
Elf_Scn *symtab;
size_t strtabndx, nsymb;
struct sym {
char *sym_name;
unsigned long sym_value; /* from st_value */
unsigned long sym_size; /* from st_size */
};
int kelf_parse(struct syms *);
struct syms {
struct sym *table;
size_t nsymb;
};
int sym_compare_search(const void *, const void *);
int sym_compare_sort(const void *, const void *);
struct syms *
kelf_open(const char *path)
{
struct syms *syms;
int error;
char *name;
Elf *elf;
Elf_Data *data = NULL;
Elf_Scn *scn = NULL, *symtab;
GElf_Sym sym;
GElf_Shdr shdr;
size_t i, shstrndx, strtabndx = SIZE_MAX, symtab_size;
unsigned long diff;
struct sym *tmp;
struct syms *syms = NULL;
int fd;
if (elf_version(EV_CURRENT) == EV_NONE)
errx(1, "elf_version: %s", elf_errmsg(-1));
if ((syms = calloc(1, sizeof(*syms))) == NULL)
err(1, NULL);
syms->fd = open(path, O_RDONLY);
if (syms->fd == -1) {
fd = open(path, O_RDONLY);
if (fd == -1) {
warn("open: %s", path);
free(syms);
return NULL;
}
if ((syms->elf = elf_begin(syms->fd, ELF_C_READ, NULL)) == NULL) {
if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
warnx("elf_begin: %s", elf_errmsg(-1));
goto bad;
}
if (elf_kind(syms->elf) != ELF_K_ELF)
if (elf_kind(elf) != ELF_K_ELF)
goto bad;
error = kelf_parse(syms);
if (error)
if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
warnx("elf_getshdrstrndx: %s", elf_errmsg(-1));
goto bad;
}
while ((scn = elf_nextscn(elf, scn)) != NULL) {
if (gelf_getshdr(scn, &shdr) != &shdr) {
warnx("elf_getshdr: %s", elf_errmsg(-1));
goto bad;
}
if ((name = elf_strptr(elf, shstrndx, shdr.sh_name)) == NULL) {
warnx("elf_strptr: %s", elf_errmsg(-1));
goto bad;
}
if (strcmp(name, ELF_SYMTAB) == 0 &&
shdr.sh_type == SHT_SYMTAB && shdr.sh_entsize != 0) {
symtab = scn;
symtab_size = shdr.sh_size / shdr.sh_entsize;
}
if (strcmp(name, ELF_STRTAB) == 0 &&
shdr.sh_type == SHT_STRTAB) {
strtabndx = elf_ndxscn(scn);
}
}
if (symtab == NULL) {
warnx("%s: %s: section not found", path, ELF_SYMTAB);
goto bad;
}
if (strtabndx == SIZE_MAX) {
warnx("%s: %s: section not found", path, ELF_STRTAB);
goto bad;
}
data = elf_rawdata(symtab, data);
if (data == NULL)
goto bad;
return syms;
if ((syms = calloc(1, sizeof(*syms))) == NULL)
err(1, NULL);
syms->table = calloc(symtab_size, sizeof *syms->table);
if (syms->table == NULL)
err(1, NULL);
for (i = 0; i < symtab_size; i++) {
if (gelf_getsym(data, i, &sym) == NULL)
continue;
if (GELF_ST_TYPE(sym.st_info) != STT_FUNC)
continue;
name = elf_strptr(elf, strtabndx, sym.st_name);
if (name == NULL)
continue;
syms->table[syms->nsymb].sym_name = strdup(name);
if (syms->table[syms->nsymb].sym_name == NULL)
err(1, NULL);
syms->table[syms->nsymb].sym_value = sym.st_value;
syms->table[syms->nsymb].sym_size = sym.st_size;
syms->nsymb++;
}
tmp = reallocarray(syms->table, syms->nsymb, sizeof *syms->table);
if (tmp == NULL)
err(1, NULL);
syms->table = tmp;
/* Sort symbols in ascending order by address. */
qsort(syms->table, syms->nsymb, sizeof *syms->table, sym_compare_sort);
/*
* Some functions, particularly those written in assembly, have an
* st_size of zero. We can approximate a size for these by assuming
* that they extend from their st_value to that of the next function.
*/
for (i = 0; i < syms->nsymb; i++) {
if (syms->table[i].sym_size != 0)
continue;
/* Can't do anything for the last symbol. */
if (i + 1 == syms->nsymb)
continue;
diff = syms->table[i + 1].sym_value - syms->table[i].sym_value;
syms->table[i].sym_size = diff;
}
bad:
kelf_close(syms);
return NULL;
elf_end(elf);
close(fd);
return syms;
}
void
kelf_close(struct syms *syms)
{
size_t i;
if (syms == NULL)
return;
elf_end(syms->elf);
close(syms->fd);
for (i = 0; i < syms->nsymb; i++)
free(syms->table[i].sym_name);
free(syms->table);
free(syms);
}
@ -91,106 +181,46 @@ int
kelf_snprintsym(struct syms *syms, char *str, size_t size, unsigned long pc,
unsigned long off)
{
GElf_Sym sym;
Elf_Data *data = NULL;
Elf_Addr offset, bestoff = 0;
size_t i, bestidx = 0;
char *name;
int cnt;
struct sym key = { .sym_value = pc + off };
struct sym *entry;
Elf_Addr offset;
if (syms == NULL)
goto fallback;
data = elf_rawdata(syms->symtab, data);
if (data == NULL)
entry = bsearch(&key, syms->table, syms->nsymb, sizeof *syms->table,
sym_compare_search);
if (entry == NULL)
goto fallback;
for (i = 0; i < syms->nsymb; i++) {
if (gelf_getsym(data, i, &sym) == NULL)
continue;
if (GELF_ST_TYPE(sym.st_info) != STT_FUNC)
continue;
if (pc >= sym.st_value + off) {
if (pc < (sym.st_value + off + sym.st_size))
break;
/* Workaround for symbols w/o size, usually asm ones. */
if (sym.st_size == 0 && sym.st_value + off > bestoff) {
bestidx = i;
bestoff = sym.st_value + off;
}
}
}
if (i == syms->nsymb) {
if (bestidx == 0 || gelf_getsym(data, bestidx, &sym) == NULL)
goto fallback;
}
name = elf_strptr(syms->elf, syms->strtabndx, sym.st_name);
if (name != NULL)
cnt = snprintf(str, size, "\n%s", name);
else
cnt = snprintf(str, size, "\n0x%llx", sym.st_value);
if (cnt < 0)
return cnt;
offset = pc - (sym.st_value + off);
offset = pc - (entry->sym_value + off);
if (offset != 0) {
int l;
l = snprintf(str + cnt, size > (size_t)cnt ? size - cnt : 0,
"+0x%llx", (unsigned long long)offset);
if (l < 0)
return l;
cnt += l;
return snprintf(str, size, "\n%s+0x%llx",
entry->sym_name, (unsigned long long)offset);
}
return cnt;
return snprintf(str, size, "\n%s", entry->sym_name);
fallback:
return snprintf(str, size, "\n0x%lx", pc);
}
int
kelf_parse(struct syms *syms)
sym_compare_sort(const void *ap, const void *bp)
{
GElf_Shdr shdr;
Elf_Scn *scn, *scnctf;
char *name;
size_t shstrndx;
const struct sym *a = ap, *b = bp;
if (elf_getshdrstrndx(syms->elf, &shstrndx) != 0) {
warnx("elf_getshdrstrndx: %s", elf_errmsg(-1));
return 1;
}
scn = scnctf = NULL;
while ((scn = elf_nextscn(syms->elf, scn)) != NULL) {
if (gelf_getshdr(scn, &shdr) != &shdr) {
warnx("elf_getshdr: %s", elf_errmsg(-1));
return 1;
}
if ((name = elf_strptr(syms->elf, shstrndx,
shdr.sh_name)) == NULL) {
warnx("elf_strptr: %s", elf_errmsg(-1));
return 1;
}
if (strcmp(name, ELF_SYMTAB) == 0 &&
shdr.sh_type == SHT_SYMTAB && shdr.sh_entsize != 0) {
syms->symtab = scn;
syms->nsymb = shdr.sh_size / shdr.sh_entsize;
}
if (strcmp(name, ELF_STRTAB) == 0 &&
shdr.sh_type == SHT_STRTAB) {
syms->strtabndx = elf_ndxscn(scn);
}
}
if (syms->symtab == NULL)
warnx("symbol table not found");
return 0;
if (a->sym_value < b->sym_value)
return -1;
return a->sym_value > b->sym_value;
}
int
sym_compare_search(const void *keyp, const void *entryp)
{
const struct sym *entry = entryp, *key = keyp;
if (key->sym_value < entry->sym_value)
return -1;
return key->sym_value >= entry->sym_value + entry->sym_size;
}