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 Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above 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: # The following ports must be installed:
# #
@ -88,7 +88,11 @@ stamp-pf: addr.py pf.conf
FRAG6_SCRIPTS !!= cd ${.CURDIR} && ls -1 frag6*.py FRAG6_SCRIPTS !!= cd ${.CURDIR} && ls -1 frag6*.py
run-stack-frag6_queuelimit.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 @echo DISABLED
run-stack-frag6_doubleatomic.py: addr.py stamp-stack 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 <sys/syscall.h>
#include <machine/asm.h> #include <machine/asm.h>
@ -12,11 +12,13 @@
.type gadget_getpid,_ASM_TYPE_FUNCTION .type gadget_getpid,_ASM_TYPE_FUNCTION
gadget_getpid: gadget_getpid:
#if defined(__amd64__) #if defined(__amd64__)
endbr64
mov $SYS_getpid, %eax mov $SYS_getpid, %eax
syscall syscall
ret ret
#elif defined(__aarch64__) #elif defined(__aarch64__)
ldr x8, #SYS_getpid bti c
mov x8, #SYS_getpid
svc 0 svc 0
dsb nsh dsb nsh
isb 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) 2014 Patrick Wildt <patrick@blueri.se>
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org> * 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); return sysctl_rdquad(oldp, oldlenp, newp, value);
case CPU_ID_AA64PFR1: case CPU_ID_AA64PFR1:
value = 0; value = 0;
value |= cpu_id_aa64pfr1 & ID_AA64PFR1_BT_MASK;
value |= cpu_id_aa64pfr1 & ID_AA64PFR1_SBSS_MASK; value |= cpu_id_aa64pfr1 & ID_AA64PFR1_SBSS_MASK;
return sysctl_rdquad(oldp, oldlenp, newp, value); return sysctl_rdquad(oldp, oldlenp, newp, value);
case CPU_ID_AA64ISAR2: 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 # Machine-independent option; used by all architectures for their
# GENERIC kernel # GENERIC kernel
@ -16,7 +16,7 @@ option KMEMSTATS # collect malloc(9) statistics
option PTRACE # ptrace(2) system call option PTRACE # ptrace(2) system call
#option KVA_GUARDPAGES # slow virtual address recycling (+ guarding) #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 VFSLCKDEBUG # VFS locking checks
option CRYPTO # Cryptographic framework 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> * Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
@ -53,13 +53,13 @@ int
dt_prov_profile_init(void) dt_prov_profile_init(void)
{ {
dtpp_profile = dt_dev_alloc_probe("hz", "97", &dt_prov_profile); dtpp_profile = dt_dev_alloc_probe("hz", "97", &dt_prov_profile);
dt_dev_register_probe(dtpp_profile);
if (dtpp_profile == NULL) if (dtpp_profile == NULL)
return 0; return 0;
dt_dev_register_probe(dtpp_profile);
dtpp_interval = dt_dev_alloc_probe("hz", "1", &dt_prov_interval); dtpp_interval = dt_dev_alloc_probe("hz", "1", &dt_prov_interval);
dt_dev_register_probe(dtpp_interval);
if (dtpp_interval == NULL) if (dtpp_interval == NULL)
return 1; return 1;
dt_dev_register_probe(dtpp_interval);
return 2; 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> .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\" .\"
@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" 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 .Dt TMUX 1
.Os .Os
.Sh NAME .Sh NAME
@ -1036,9 +1036,17 @@ The following commands are available to manage clients and sessions:
.D1 Pq alias: Ic attach .D1 Pq alias: Ic attach
If run from outside If run from outside
.Nm , .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 . .Ar target-session .
If used from inside, switch the current client.
If If
.Fl d .Fl d
is specified, any other clients attached to the session are detached. 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> * Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
@ -23,6 +23,7 @@
#include <err.h> #include <err.h>
#include <fcntl.h> #include <fcntl.h>
#include <gelf.h> #include <gelf.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -30,60 +31,149 @@
#include "btrace.h" #include "btrace.h"
struct syms { struct sym {
int fd; char *sym_name;
Elf *elf; unsigned long sym_value; /* from st_value */
Elf_Scn *symtab; unsigned long sym_size; /* from st_size */
size_t strtabndx, nsymb;
}; };
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 * struct syms *
kelf_open(const char *path) kelf_open(const char *path)
{ {
struct syms *syms; char *name;
int error; 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) if (elf_version(EV_CURRENT) == EV_NONE)
errx(1, "elf_version: %s", elf_errmsg(-1)); errx(1, "elf_version: %s", elf_errmsg(-1));
if ((syms = calloc(1, sizeof(*syms))) == NULL) fd = open(path, O_RDONLY);
err(1, NULL); if (fd == -1) {
syms->fd = open(path, O_RDONLY);
if (syms->fd == -1) {
warn("open: %s", path); warn("open: %s", path);
free(syms);
return NULL; 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)); warnx("elf_begin: %s", elf_errmsg(-1));
goto bad; goto bad;
} }
if (elf_kind(syms->elf) != ELF_K_ELF) if (elf_kind(elf) != ELF_K_ELF)
goto bad; goto bad;
error = kelf_parse(syms); if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
if (error) 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; 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: bad:
kelf_close(syms); elf_end(elf);
return NULL; close(fd);
return syms;
} }
void void
kelf_close(struct syms *syms) kelf_close(struct syms *syms)
{ {
size_t i;
if (syms == NULL) if (syms == NULL)
return; 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); free(syms);
} }
@ -91,106 +181,46 @@ int
kelf_snprintsym(struct syms *syms, char *str, size_t size, unsigned long pc, kelf_snprintsym(struct syms *syms, char *str, size_t size, unsigned long pc,
unsigned long off) unsigned long off)
{ {
GElf_Sym sym; struct sym key = { .sym_value = pc + off };
Elf_Data *data = NULL; struct sym *entry;
Elf_Addr offset, bestoff = 0; Elf_Addr offset;
size_t i, bestidx = 0;
char *name;
int cnt;
if (syms == NULL) if (syms == NULL)
goto fallback; goto fallback;
data = elf_rawdata(syms->symtab, data); entry = bsearch(&key, syms->table, syms->nsymb, sizeof *syms->table,
if (data == NULL) sym_compare_search);
if (entry == NULL)
goto fallback; goto fallback;
for (i = 0; i < syms->nsymb; i++) { offset = pc - (entry->sym_value + off);
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);
if (offset != 0) { if (offset != 0) {
int l; return snprintf(str, size, "\n%s+0x%llx",
entry->sym_name, (unsigned long long)offset);
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 cnt; return snprintf(str, size, "\n%s", entry->sym_name);
fallback: fallback:
return snprintf(str, size, "\n0x%lx", pc); return snprintf(str, size, "\n0x%lx", pc);
} }
int int
kelf_parse(struct syms *syms) sym_compare_sort(const void *ap, const void *bp)
{ {
GElf_Shdr shdr; const struct sym *a = ap, *b = bp;
Elf_Scn *scn, *scnctf;
char *name;
size_t shstrndx;
if (elf_getshdrstrndx(syms->elf, &shstrndx) != 0) { if (a->sym_value < b->sym_value)
warnx("elf_getshdrstrndx: %s", elf_errmsg(-1)); return -1;
return 1; return a->sym_value > b->sym_value;
} }
scn = scnctf = NULL; int
while ((scn = elf_nextscn(syms->elf, scn)) != NULL) { sym_compare_search(const void *keyp, const void *entryp)
if (gelf_getshdr(scn, &shdr) != &shdr) { {
warnx("elf_getshdr: %s", elf_errmsg(-1)); const struct sym *entry = entryp, *key = keyp;
return 1;
} if (key->sym_value < entry->sym_value)
return -1;
if ((name = elf_strptr(syms->elf, shstrndx, return key->sym_value >= entry->sym_value + entry->sym_size;
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;
} }