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
This commit is contained in:
Brooks Davis 2021-11-17 20:12:25 +00:00
parent e3e811a3f8
commit e02f64d9b8
10 changed files with 127 additions and 22 deletions

View File

@ -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));
}

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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:

View File

@ -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); }

View File

@ -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

View File

@ -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, ")");
}

View File

@ -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,