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:
parent
e3e811a3f8
commit
e02f64d9b8
69
sys/compat/freebsd32/freebsd32_abort2.c
Normal file
69
sys/compat/freebsd32/freebsd32_abort2.c
Normal 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));
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
|
@ -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); }
|
||||
|
@ -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
|
||||
|
@ -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, ")");
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user