git: e02f64d9b88c - main - freebsd32: add real abort2
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 17 Nov 2021 20:22:41 UTC
The branch main has been updated by brooks: URL: https://cgit.FreeBSD.org/src/commit/?id=e02f64d9b88ce33313755f4a94c46a7839a23f10 commit e02f64d9b88ce33313755f4a94c46a7839a23f10 Author: Brooks Davis <brooks@FreeBSD.org> AuthorDate: 2021-11-17 20:12:25 +0000 Commit: Brooks Davis <brooks@FreeBSD.org> CommitDate: 2021-11-17 20:12:25 +0000 freebsd32: add real abort2 Previously, the code would copy twice as many pointers as specified and print pairs of them a single 64-bit pointer. abort2 doesn't return so make the return type void freebsd32_abort2 is in it's own file with a 2-clause BSD license based on a discussion with Wojciech many years ago. Reviewed by: kevans --- sys/compat/freebsd32/freebsd32_abort2.c | 69 ++++++++++++++++++++++++++ sys/compat/freebsd32/freebsd32_proto.h | 7 +++ sys/compat/freebsd32/freebsd32_syscall.h | 2 +- sys/compat/freebsd32/freebsd32_syscalls.c | 2 +- sys/compat/freebsd32/freebsd32_sysent.c | 2 +- sys/compat/freebsd32/freebsd32_systrace_args.c | 10 ++-- sys/compat/freebsd32/syscalls.master | 2 +- sys/conf/files | 1 + sys/kern/kern_exit.c | 52 ++++++++++++++----- sys/sys/syscallsubr.h | 2 + 10 files changed, 127 insertions(+), 22 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_abort2.c b/sys/compat/freebsd32/freebsd32_abort2.c new file mode 100644 index 000000000000..615dd5e95345 --- /dev/null +++ b/sys/compat/freebsd32/freebsd32_abort2.c @@ -0,0 +1,69 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2005 Wojciech A. Koszek + * All rights reserved. + * + * 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 <sys/proc.h> +#include <sys/sbuf.h> +#include <sys/syscallsubr.h> +#include <sys/syslog.h> + +#include <compat/freebsd32/freebsd32_proto.h> + +int +freebsd32_abort2(struct thread *td, struct freebsd32_abort2_args *uap) +{ + void *uargs[16]; + void *uargsp; + uint32_t *uargsptr; + uint32_t ptr; + int i, nargs; + + nargs = uap->nargs; + if (nargs < 0 || nargs > nitems(uargs)) + nargs = -1; + uargsp = NULL; + if (nargs > 0) { + if (uap->args != NULL) { + uargsptr = uap->args; + for (i = 0; i < nargs; i++) { + if (fueword32(uargsptr + i, &ptr) != 0) { + nargs = -1; + break; + } else + uargs[i] = (void *)(uintptr_t)ptr; + } + if (nargs > 0) + uargsp = &uargs; + } else + nargs = -1; + } + return (kern_abort2(td, uap->why, nargs, uargsp)); +} diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index aab791780818..f86fb5dfa96f 100644 --- a/sys/compat/freebsd32/freebsd32_proto.h +++ b/sys/compat/freebsd32/freebsd32_proto.h @@ -396,6 +396,11 @@ struct freebsd32_kmq_notify_args { char mqd_l_[PADL_(int)]; int mqd; char mqd_r_[PADR_(int)]; char sigev_l_[PADL_(const struct sigevent32 *)]; const struct sigevent32 * sigev; char sigev_r_[PADR_(const struct sigevent32 *)]; }; +struct freebsd32_abort2_args { + char why_l_[PADL_(const char *)]; const char * why; char why_r_[PADR_(const char *)]; + char nargs_l_[PADL_(int)]; int nargs; char nargs_r_[PADR_(int)]; + char args_l_[PADL_(uint32_t *)]; uint32_t * args; char args_r_[PADR_(uint32_t *)]; +}; struct freebsd32_aio_fsync_args { char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)]; char aiocbp_l_[PADL_(struct aiocb32 *)]; struct aiocb32 * aiocbp; char aiocbp_r_[PADR_(struct aiocb32 *)]; @@ -827,6 +832,7 @@ int freebsd32_kmq_setattr(struct thread *, struct freebsd32_kmq_setattr_args *); int freebsd32_kmq_timedreceive(struct thread *, struct freebsd32_kmq_timedreceive_args *); int freebsd32_kmq_timedsend(struct thread *, struct freebsd32_kmq_timedsend_args *); int freebsd32_kmq_notify(struct thread *, struct freebsd32_kmq_notify_args *); +int freebsd32_abort2(struct thread *, struct freebsd32_abort2_args *); int freebsd32_aio_fsync(struct thread *, struct freebsd32_aio_fsync_args *); #ifdef PAD64_REQUIRED int freebsd32_pread(struct thread *, struct freebsd32_pread_args *); @@ -1409,6 +1415,7 @@ int freebsd11_freebsd32_fstatat(struct thread *, struct freebsd11_freebsd32_fsta #define FREEBSD32_SYS_AUE_freebsd32_kmq_timedreceive AUE_MQ_TIMEDRECEIVE #define FREEBSD32_SYS_AUE_freebsd32_kmq_timedsend AUE_MQ_TIMEDSEND #define FREEBSD32_SYS_AUE_freebsd32_kmq_notify AUE_MQ_NOTIFY +#define FREEBSD32_SYS_AUE_freebsd32_abort2 AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_aio_fsync AUE_AIO_FSYNC #define FREEBSD32_SYS_AUE_freebsd32_pread AUE_PREAD #define FREEBSD32_SYS_AUE_freebsd32_pwrite AUE_PWRITE diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index 169615446373..c57cce7c5343 100644 --- a/sys/compat/freebsd32/freebsd32_syscall.h +++ b/sys/compat/freebsd32/freebsd32_syscall.h @@ -386,7 +386,7 @@ #define FREEBSD32_SYS_freebsd32_kmq_timedsend 460 #define FREEBSD32_SYS_freebsd32_kmq_notify 461 #define FREEBSD32_SYS_kmq_unlink 462 -#define FREEBSD32_SYS_abort2 463 +#define FREEBSD32_SYS_freebsd32_abort2 463 #define FREEBSD32_SYS_thr_set_name 464 #define FREEBSD32_SYS_freebsd32_aio_fsync 465 #define FREEBSD32_SYS_rtprio_thread 466 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index 8277b29843f0..4ab6adb56b4a 100644 --- a/sys/compat/freebsd32/freebsd32_syscalls.c +++ b/sys/compat/freebsd32/freebsd32_syscalls.c @@ -472,7 +472,7 @@ const char *freebsd32_syscallnames[] = { "freebsd32_kmq_timedsend", /* 460 = freebsd32_kmq_timedsend */ "freebsd32_kmq_notify", /* 461 = freebsd32_kmq_notify */ "kmq_unlink", /* 462 = kmq_unlink */ - "abort2", /* 463 = abort2 */ + "freebsd32_abort2", /* 463 = freebsd32_abort2 */ "thr_set_name", /* 464 = thr_set_name */ "freebsd32_aio_fsync", /* 465 = freebsd32_aio_fsync */ "rtprio_thread", /* 466 = rtprio_thread */ diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index 808e01fd3afd..c25ee1edaab7 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -525,7 +525,7 @@ struct sysent freebsd32_sysent[] = { { .sy_narg = AS(freebsd32_kmq_timedsend_args), .sy_call = (sy_call_t *)lkmressys, .sy_auevent = AUE_NULL, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_ABSENT }, /* 460 = freebsd32_kmq_timedsend */ { .sy_narg = AS(freebsd32_kmq_notify_args), .sy_call = (sy_call_t *)lkmressys, .sy_auevent = AUE_NULL, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_ABSENT }, /* 461 = freebsd32_kmq_notify */ { .sy_narg = AS(kmq_unlink_args), .sy_call = (sy_call_t *)lkmressys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 462 = kmq_unlink */ - { .sy_narg = AS(abort2_args), .sy_call = (sy_call_t *)sys_abort2, .sy_auevent = AUE_NULL, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 463 = abort2 */ + { .sy_narg = AS(freebsd32_abort2_args), .sy_call = (sy_call_t *)freebsd32_abort2, .sy_auevent = AUE_NULL, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 463 = freebsd32_abort2 */ { .sy_narg = AS(thr_set_name_args), .sy_call = (sy_call_t *)sys_thr_set_name, .sy_auevent = AUE_NULL, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 464 = thr_set_name */ { .sy_narg = AS(freebsd32_aio_fsync_args), .sy_call = (sy_call_t *)freebsd32_aio_fsync, .sy_auevent = AUE_AIO_FSYNC, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 465 = freebsd32_aio_fsync */ { .sy_narg = AS(rtprio_thread_args), .sy_call = (sy_call_t *)sys_rtprio_thread, .sy_auevent = AUE_RTPRIO, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 466 = rtprio_thread */ diff --git a/sys/compat/freebsd32/freebsd32_systrace_args.c b/sys/compat/freebsd32/freebsd32_systrace_args.c index f4695b07d422..98fb1dea15a8 100644 --- a/sys/compat/freebsd32/freebsd32_systrace_args.c +++ b/sys/compat/freebsd32/freebsd32_systrace_args.c @@ -2271,9 +2271,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 1; break; } - /* abort2 */ + /* freebsd32_abort2 */ case 463: { - struct abort2_args *p = params; + struct freebsd32_abort2_args *p = params; uarg[0] = (intptr_t)p->why; /* const char * */ iarg[1] = p->nargs; /* int */ uarg[2] = (intptr_t)p->args; /* uint32_t * */ @@ -7099,7 +7099,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* abort2 */ + /* freebsd32_abort2 */ case 463: switch (ndx) { case 0: @@ -10582,10 +10582,10 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* abort2 */ + /* freebsd32_abort2 */ case 463: if (ndx == 0 || ndx == 1) - p = "int"; + p = "void"; break; /* thr_set_name */ case 464: diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 90b93fbd64e8..a85b72c7fb6e 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -860,7 +860,7 @@ 461 AUE_MQ_NOTIFY NOSTD { int freebsd32_kmq_notify(int mqd, \ const struct sigevent32 *sigev); } 462 AUE_MQ_UNLINK NOPROTO|NOSTD { int kmq_unlink(const char *path); } -463 AUE_NULL NOPROTO { int abort2(const char *why, int nargs, uint32_t *args); } +463 AUE_NULL STD { void freebsd32_abort2(const char *why, int nargs, uint32_t *args); } 464 AUE_NULL NOPROTO { int thr_set_name(int32_t id, const char *name); } 465 AUE_AIO_FSYNC STD { int freebsd32_aio_fsync(int op, \ struct aiocb32 *aiocbp); } diff --git a/sys/conf/files b/sys/conf/files index aceaac1bd95e..8854d827bcc3 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -379,6 +379,7 @@ cddl/dev/fbt/fbt.c optional dtrace_fbt | dtraceall compile-with "${FBT_C} cddl/dev/systrace/systrace.c optional dtrace_systrace | dtraceall compile-with "${CDDL_C}" cddl/dev/prototype.c optional dtrace_prototype | dtraceall compile-with "${CDDL_C}" fs/nfsclient/nfs_clkdtrace.c optional dtnfscl nfscl | dtraceall nfscl compile-with "${CDDL_C}" +compat/freebsd32/freebsd32_abort2.c optional compat_freebsd32 compat/freebsd32/freebsd32_capability.c optional compat_freebsd32 compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32 compat/freebsd32/freebsd32_misc.c optional compat_freebsd32 diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 14be2425511d..2f1cfb2a25d2 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -735,10 +735,41 @@ struct abort2_args { int sys_abort2(struct thread *td, struct abort2_args *uap) +{ + void *uargs[16]; + void **uargsp; + int error, nargs; + + nargs = uap->nargs; + if (nargs < 0 || nargs > nitems(uargs)) + nargs = -1; + uargsp = NULL; + if (nargs > 0) { + if (uap->args != NULL) { + error = copyin(uap->args, uargs, + nargs * sizeof(void *)); + if (error != 0) + nargs = -1; + else + uargsp = uargs; + } else + nargs = -1; + } + return (kern_abort2(td, uap->why, nargs, uargsp)); +} + +/* + * kern_abort2() + * Arguments: + * why - user pointer to why + * nargs - number of arguments copied or -1 if an error occured in copying + * args - pointer to an array of pointers in kernel format + */ +int +kern_abort2(struct thread *td, const char *why, int nargs, void **uargs) { struct proc *p = td->td_proc; struct sbuf *sb; - void *uargs[16]; int error, i, sig; /* @@ -756,29 +787,24 @@ sys_abort2(struct thread *td, struct abort2_args *uap) */ sig = SIGKILL; /* Prevent from DoSes from user-space. */ - if (uap->nargs < 0 || uap->nargs > 16) + if (nargs == -1) goto out; - if (uap->nargs > 0) { - if (uap->args == NULL) - goto out; - error = copyin(uap->args, uargs, uap->nargs * sizeof(void *)); - if (error != 0) - goto out; - } + KASSERT(nargs >= 0 && nargs <= 16, ("called with too many args (%d)", + nargs)); /* * Limit size of 'reason' string to 128. Will fit even when * maximal number of arguments was chosen to be logged. */ - if (uap->why != NULL) { - error = sbuf_copyin(sb, uap->why, 128); + if (why != NULL) { + error = sbuf_copyin(sb, why, 128); if (error < 0) goto out; } else { sbuf_printf(sb, "(null)"); } - if (uap->nargs > 0) { + if (nargs > 0) { sbuf_printf(sb, "("); - for (i = 0;i < uap->nargs; i++) + for (i = 0;i < nargs; i++) sbuf_printf(sb, "%s%p", i == 0 ? "" : ", ", uargs[i]); sbuf_printf(sb, ")"); } diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index a10c84cd2ab7..5032df4be874 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -81,6 +81,8 @@ struct mmap_req { int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, size_t buflen, size_t path_max); +int kern_abort2(struct thread *td, const char *why, int nargs, + void **uargs); int kern_accept(struct thread *td, int s, struct sockaddr **name, socklen_t *namelen, struct file **fp); int kern_accept4(struct thread *td, int s, struct sockaddr **name,