summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
Diffstat (limited to 'regress')
-rw-r--r--regress/sys/kern/ptrace/Makefile4
-rw-r--r--regress/sys/kern/ptrace/xstate/Makefile26
-rw-r--r--regress/sys/kern/ptrace/xstate/avx.S79
-rw-r--r--regress/sys/kern/ptrace/xstate/xstate.c259
-rw-r--r--regress/usr.bin/ssh/hostkey-agent.sh26
5 files changed, 392 insertions, 2 deletions
diff --git a/regress/sys/kern/ptrace/Makefile b/regress/sys/kern/ptrace/Makefile
index 5a41ee05a49..e4f4c38e86b 100644
--- a/regress/sys/kern/ptrace/Makefile
+++ b/regress/sys/kern/ptrace/Makefile
@@ -1,4 +1,6 @@
-# $OpenBSD: Makefile,v 1.3 2016/09/23 18:56:49 bluhm Exp $
+# $OpenBSD: Makefile,v 1.4 2024/11/27 05:27:21 anton Exp $
+
+SUBDIR+= xstate
PROG= ptrace
diff --git a/regress/sys/kern/ptrace/xstate/Makefile b/regress/sys/kern/ptrace/xstate/Makefile
new file mode 100644
index 00000000000..d42929434d3
--- /dev/null
+++ b/regress/sys/kern/ptrace/xstate/Makefile
@@ -0,0 +1,26 @@
+# $OpenBSD: Makefile,v 1.1 2024/11/27 05:26:58 anton Exp $
+
+.if ${MACHINE} == "amd64"
+
+WARNINGS= yes
+
+PROG= xstate
+SRCS+= xstate.c
+SRCS+= avx.S
+
+REGRESS_SETUP_ONCE=${PROG}
+
+.for t in xstate-ymm-get xstate-ymm-set
+${t}:
+ ${.OBJDIR}/xstate ${t}
+REGRESS_TARGETS+=${t}
+.endfor
+
+.else
+
+regress:
+ @echo SKIPPED
+
+.endif
+
+.include <bsd.regress.mk>
diff --git a/regress/sys/kern/ptrace/xstate/avx.S b/regress/sys/kern/ptrace/xstate/avx.S
new file mode 100644
index 00000000000..5571a2e634e
--- /dev/null
+++ b/regress/sys/kern/ptrace/xstate/avx.S
@@ -0,0 +1,79 @@
+/* $OpenBSD */
+
+#include <machine/asm.h>
+
+ .intel_syntax noprefix
+
+/* void ymm_write(void) */
+ENTRY(ymm_write)
+ vmovdqu ymm0, [rip + .Lymm0]
+ vmovdqu ymm1, [rip + .Lymm1]
+ vmovdqu ymm2, [rip + .Lymm2]
+ vmovdqu ymm3, [rip + .Lymm3]
+ vmovdqu ymm4, [rip + .Lymm4]
+ vmovdqu ymm5, [rip + .Lymm5]
+ vmovdqu ymm6, [rip + .Lymm6]
+ vmovdqu ymm7, [rip + .Lymm7]
+ vmovdqu ymm8, [rip + .Lymm8]
+ vmovdqu ymm9, [rip + .Lymm9]
+ vmovdqu ymm10, [rip + .Lymm10]
+ vmovdqu ymm11, [rip + .Lymm11]
+ vmovdqu ymm12, [rip + .Lymm12]
+ vmovdqu ymm13, [rip + .Lymm13]
+ vmovdqu ymm14, [rip + .Lymm14]
+ vmovdqu ymm15, [rip + .Lymm15]
+ ret
+
+/* void ymm_read(struct ymm[16]) */
+ENTRY(ymm_read)
+ vmovdqu [rdi + 0x000], ymm0
+ vmovdqu [rdi + 0x020], ymm1
+ vmovdqu [rdi + 0x040], ymm2
+ vmovdqu [rdi + 0x060], ymm3
+ vmovdqu [rdi + 0x080], ymm4
+ vmovdqu [rdi + 0x0a0], ymm5
+ vmovdqu [rdi + 0x0c0], ymm6
+ vmovdqu [rdi + 0x0e0], ymm7
+ vmovdqu [rdi + 0x100], ymm8
+ vmovdqu [rdi + 0x120], ymm9
+ vmovdqu [rdi + 0x140], ymm10
+ vmovdqu [rdi + 0x160], ymm11
+ vmovdqu [rdi + 0x180], ymm12
+ vmovdqu [rdi + 0x1a0], ymm13
+ vmovdqu [rdi + 0x1c0], ymm14
+ vmovdqu [rdi + 0x1e0], ymm15
+ ret
+
+ .rodata
+.Lymm0:
+ .rept 4; .quad 0x0000000000000000; .endr
+.Lymm1:
+ .rept 4; .quad 0x1111111111111111; .endr
+.Lymm2:
+ .rept 4; .quad 0x2222222222222222; .endr
+.Lymm3:
+ .rept 4; .quad 0x3333333333333333; .endr
+.Lymm4:
+ .rept 4; .quad 0x4444444444444444; .endr
+.Lymm5:
+ .rept 4; .quad 0x5555555555555555; .endr
+.Lymm6:
+ .rept 4; .quad 0x6666666666666666; .endr
+.Lymm7:
+ .rept 4; .quad 0x7777777777777777; .endr
+.Lymm8:
+ .rept 4; .quad 0x8888888888888888; .endr
+.Lymm9:
+ .rept 4; .quad 0x9999999999999999; .endr
+.Lymm10:
+ .rept 4; .quad 0xaaaaaaaaaaaaaaaa; .endr
+.Lymm11:
+ .rept 4; .quad 0xbbbbbbbbbbbbbbbb; .endr
+.Lymm12:
+ .rept 4; .quad 0xcccccccccccccccc; .endr
+.Lymm13:
+ .rept 4; .quad 0xdddddddddddddddd; .endr
+.Lymm14:
+ .rept 4; .quad 0xeeeeeeeeeeeeeeee; .endr
+.Lymm15:
+ .rept 4; .quad 0xffffffffffffffff; .endr
diff --git a/regress/sys/kern/ptrace/xstate/xstate.c b/regress/sys/kern/ptrace/xstate/xstate.c
new file mode 100644
index 00000000000..bee551463f8
--- /dev/null
+++ b/regress/sys/kern/ptrace/xstate/xstate.c
@@ -0,0 +1,259 @@
+/* $OpenBSD */
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+struct cpuid {
+ uint32_t a, b, c, d;
+};
+
+struct xstate {
+ struct {
+ uint8_t buf[1024];
+ uint32_t size;
+ } area;
+
+ struct {
+ uint32_t supported;
+ uint32_t offset;
+ uint32_t size;
+ } components[3];
+#define XSTATE_COMPONENT_X87 0
+#define XSTATE_COMPONENT_SSE 1
+#define XSTATE_COMPONENT_AVX 2
+};
+
+struct u128 {
+ uint64_t v[2];
+} __attribute__((packed));
+
+struct ymm {
+ struct u128 xmm;
+ struct u128 ymm;
+} __attribute__((packed));
+
+extern void ymm_write(void);
+extern void ymm_read(struct ymm[16]);
+
+static inline void
+cpuid(uint32_t leaf, uint32_t subleaf, struct cpuid *out)
+{
+ __asm__("cpuid"
+ : "=a" (out->a), "=b" (out->b), "=c" (out->c), "=d" (out->d)
+ : "a" (leaf), "c" (subleaf));
+}
+
+static int
+xstate_init(struct xstate *xstate, pid_t pid)
+{
+#define CPUID_01_C_XSAVE_MASK (1 << 26)
+#define XCR0_XMM_MASK (1 << 1)
+#define XCR0_YMM_MASK (1 << 2)
+
+ struct cpuid leaf;
+ struct ptrace_xstate_info info;
+
+ cpuid(0x1, 0, &leaf);
+ if ((leaf.c & CPUID_01_C_XSAVE_MASK) == 0) {
+ printf("SKIPPED: XSAVE not enumerated");
+ return 1;
+ }
+
+ memset(xstate, 0, sizeof(*xstate));
+
+ if (ptrace(PT_GETXSTATE_INFO, pid,
+ (caddr_t)&info, sizeof(info)) == -1)
+ err(1, "ptrace: PT_GETXSTATE_INFO");
+ if (info.xsave_len > sizeof(xstate->area.buf))
+ errx(1, "xstate buffer too small");
+ xstate->area.size = info.xsave_len;
+
+ if ((info.xsave_mask & XCR0_XMM_MASK) == 0 ||
+ (info.xsave_mask & XCR0_YMM_MASK) == 0) {
+ printf("SKIPPED: SSE/AVX disabled in XCR0\n");
+ return 1;
+ }
+
+ xstate->components[XSTATE_COMPONENT_SSE].supported = 1;
+ /* Part of legacy region in XSAVE area. */
+ xstate->components[XSTATE_COMPONENT_SSE].offset = 160;
+ xstate->components[XSTATE_COMPONENT_SSE].size = 256;
+
+ cpuid(0xd, XSTATE_COMPONENT_AVX, &leaf);
+ xstate->components[XSTATE_COMPONENT_AVX].supported = 1;
+ xstate->components[XSTATE_COMPONENT_AVX].offset = leaf.b;
+ xstate->components[XSTATE_COMPONENT_AVX].size = leaf.a;
+
+ return 0;
+}
+
+static void
+xstate_ymm_read(struct xstate *xstate, int regno, struct ymm *rd)
+{
+ struct u128 *xmm = (struct u128 *)(xstate->area.buf +
+ xstate->components[XSTATE_COMPONENT_SSE].offset);
+ struct u128 *ymm = (struct u128 *)(xstate->area.buf +
+ xstate->components[XSTATE_COMPONENT_AVX].offset);
+
+ rd->xmm = xmm[regno];
+ rd->ymm = ymm[regno];
+}
+
+static void
+xstate_ymm_write(struct xstate *xstate, int regno, struct ymm *wr)
+{
+ struct u128 *xmm = (struct u128 *)(xstate->area.buf +
+ xstate->components[XSTATE_COMPONENT_SSE].offset);
+ struct u128 *ymm = (struct u128 *)(xstate->area.buf +
+ xstate->components[XSTATE_COMPONENT_AVX].offset);
+
+ xmm[regno] = wr->xmm;
+ ymm[regno] = wr->ymm;
+}
+
+static void
+wait_until_stopped(pid_t pid)
+{
+ int status;
+
+ if (waitpid(pid, &status, 0) == -1)
+ err(1, "waitpid");
+ if (!WIFSTOPPED(status))
+ errx(1, "expected traced process to be stopped");
+}
+
+static int
+check_ymm(const struct ymm ymm[16])
+{
+ int error = 0;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ struct ymm exp;
+
+ memset(&exp, (i << 4) | i, 32);
+ if (memcmp(&exp, &ymm[i], 32) == 0)
+ continue;
+
+ warnx("ymm%d: expected %016llx%016llx%016llx%016llx,"
+ " got %016llx%016llx%016llx%016llx", i,
+ exp.ymm.v[1], exp.ymm.v[0],
+ exp.xmm.v[1], exp.xmm.v[0],
+ ymm[i].ymm.v[1], ymm[i].ymm.v[0],
+ ymm[i].xmm.v[1], ymm[i].xmm.v[0]);
+ error = 1;
+ }
+
+ return error;
+}
+
+static int
+test_ymm_get(struct xstate *xstate)
+{
+ struct ymm ymm[16];
+ pid_t pid;
+ int i;
+
+ pid = fork();
+ if (pid == 0) {
+ ptrace(PT_TRACE_ME, 0, 0, 0);
+ ymm_write();
+ raise(SIGSTOP);
+ /* UNREACHABLE */
+ }
+
+ wait_until_stopped(pid);
+
+ if (xstate_init(xstate, pid))
+ return 0;
+
+ if (ptrace(PT_GETXSTATE, pid,
+ xstate->area.buf, xstate->area.size) == -1)
+ err(1, "ptrace: PT_GETXSTATE");
+ for (i = 0; i < 16; i++)
+ xstate_ymm_read(xstate, i, &ymm[i]);
+ return check_ymm(ymm);
+}
+
+static int
+test_ymm_set(struct xstate *xstate)
+{
+ pid_t pid;
+ int i, status;
+
+ pid = fork();
+ if (pid == 0) {
+ struct ymm ymm[16];
+
+ ptrace(PT_TRACE_ME, 0, 0, 0);
+ raise(SIGSTOP);
+ ymm_read(ymm);
+ _exit(check_ymm(ymm));
+ }
+
+ wait_until_stopped(pid);
+
+ if (xstate_init(xstate, pid))
+ return 0;
+
+ if (ptrace(PT_GETXSTATE, pid,
+ xstate->area.buf, xstate->area.size) == -1)
+ err(1, "ptrace: PT_GETXSTATE");
+ for (i = 0; i < 16; i++) {
+ struct ymm ymm;
+
+ memset(&ymm, (i << 4) | i, 32);
+ xstate_ymm_write(xstate, i, &ymm);
+ }
+
+ if (ptrace(PT_SETXSTATE, pid,
+ xstate->area.buf, xstate->area.size) == -1)
+ err(1, "ptrace: PT_SETXSTATE");
+
+ if (ptrace(PT_CONTINUE, pid, (caddr_t)1, 0) == -1)
+ err(1, "ptrace: PT_CONTINUE");
+ if (waitpid(pid, &status, 0) == -1)
+ err(1, "waitpid");
+ return WIFEXITED(status) && WEXITSTATUS(status) == 0 ? 0 : 1;
+}
+
+static void __attribute__((noreturn))
+usage(void)
+{
+ fprintf(stderr, "usage: xstate test-case\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct {
+ const char *name;
+ int (*test)(struct xstate *);
+ } tests[] = {
+ { "xstate-ymm-get", test_ymm_get },
+ { "xstate-ymm-set", test_ymm_set },
+ };
+ struct xstate xstate;
+ unsigned int i;
+
+ if (argc != 2)
+ usage();
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ if (strcmp(argv[1], tests[i].name) == 0)
+ return tests[i].test(&xstate);
+ }
+
+ warnx("no such test case");
+ return 1;
+}
diff --git a/regress/usr.bin/ssh/hostkey-agent.sh b/regress/usr.bin/ssh/hostkey-agent.sh
index 222d424bd34..38486585701 100644
--- a/regress/usr.bin/ssh/hostkey-agent.sh
+++ b/regress/usr.bin/ssh/hostkey-agent.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: hostkey-agent.sh,v 1.13 2021/09/30 05:20:08 dtucker Exp $
+# $OpenBSD: hostkey-agent.sh,v 1.14 2024/11/26 22:02:28 djm Exp $
# Placed in the Public Domain.
tid="hostkey agent"
@@ -82,6 +82,30 @@ for k in $SSH_CERTTYPES ; do
fi
done
+verbose "multiple hostkeys"
+cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
+cp $OBJ/ssh_proxy $OBJ/ssh_proxy.orig
+grep -vi 'globalknownhostsfile' $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy
+echo "UpdateHostkeys=yes" >> $OBJ/ssh_proxy
+echo "GlobalKnownHostsFile=none" >> $OBJ/ssh_proxy
+
+for k in $SSH_KEYTYPES ; do
+ verbose "Addkey type $k"
+ echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy
+
+ ( printf 'localhost-with-alias ' ;
+ cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts
+done
+
+opts="-oStrictHostKeyChecking=yes -F $OBJ/ssh_proxy"
+SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`
+if [ $? -ne 0 ]; then
+ fail "connection to server with multiple hostkeys failed"
+fi
+if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
+ fail "bad SSH_CONNECTION key while using multiple hostkeys"
+fi
+
trace "kill agent"
${SSHAGENT} -k > /dev/null