Wrap kmq_notify(2) for compat32 to properly consume struct sigevent32
argument. Reviewed and tested by: Petr Salinger <Petr.Salinger@seznam.cz> Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
ab751a525b
commit
058262c69a
@ -825,8 +825,8 @@
|
||||
const char *msg_ptr, size_t msg_len,\
|
||||
unsigned msg_prio, \
|
||||
const struct timespec32 *abs_timeout);}
|
||||
461 AUE_NULL NOPROTO|NOSTD { int kmq_notify(int mqd, \
|
||||
const struct sigevent *sigev); }
|
||||
461 AUE_NULL NOSTD { int freebsd32_kmq_notify(int mqd, \
|
||||
const struct sigevent32 *sigev); }
|
||||
462 AUE_NULL NOPROTO|NOSTD { int kmq_unlink(const char *path); }
|
||||
463 AUE_NULL NOPROTO { int abort2(const char *why, int nargs, void **args); }
|
||||
464 AUE_NULL NOPROTO { int thr_set_name(long id, const char *name); }
|
||||
|
@ -2235,10 +2235,9 @@ sys_kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
|
||||
static int
|
||||
kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev)
|
||||
{
|
||||
struct sigevent ev;
|
||||
struct filedesc *fdp;
|
||||
struct proc *p;
|
||||
struct mqueue *mq;
|
||||
@ -2246,34 +2245,31 @@ sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
|
||||
struct mqueue_notifier *nt, *newnt = NULL;
|
||||
int error;
|
||||
|
||||
p = td->td_proc;
|
||||
fdp = td->td_proc->p_fd;
|
||||
if (uap->sigev) {
|
||||
error = copyin(uap->sigev, &ev, sizeof(ev));
|
||||
if (error)
|
||||
return (error);
|
||||
if (ev.sigev_notify != SIGEV_SIGNAL &&
|
||||
ev.sigev_notify != SIGEV_THREAD_ID &&
|
||||
ev.sigev_notify != SIGEV_NONE)
|
||||
if (sigev != NULL) {
|
||||
if (sigev->sigev_notify != SIGEV_SIGNAL &&
|
||||
sigev->sigev_notify != SIGEV_THREAD_ID &&
|
||||
sigev->sigev_notify != SIGEV_NONE)
|
||||
return (EINVAL);
|
||||
if ((ev.sigev_notify == SIGEV_SIGNAL ||
|
||||
ev.sigev_notify == SIGEV_THREAD_ID) &&
|
||||
!_SIG_VALID(ev.sigev_signo))
|
||||
if ((sigev->sigev_notify == SIGEV_SIGNAL ||
|
||||
sigev->sigev_notify == SIGEV_THREAD_ID) &&
|
||||
!_SIG_VALID(sigev->sigev_signo))
|
||||
return (EINVAL);
|
||||
}
|
||||
error = getmq(td, uap->mqd, &fp, NULL, &mq);
|
||||
p = td->td_proc;
|
||||
fdp = td->td_proc->p_fd;
|
||||
error = getmq(td, mqd, &fp, NULL, &mq);
|
||||
if (error)
|
||||
return (error);
|
||||
again:
|
||||
FILEDESC_SLOCK(fdp);
|
||||
fp2 = fget_locked(fdp, uap->mqd);
|
||||
fp2 = fget_locked(fdp, mqd);
|
||||
if (fp2 == NULL) {
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
error = EBADF;
|
||||
goto out;
|
||||
}
|
||||
#ifdef CAPABILITIES
|
||||
error = cap_check(cap_rights(fdp, uap->mqd), CAP_POLL_EVENT);
|
||||
error = cap_check(cap_rights(fdp, mqd), CAP_POLL_EVENT);
|
||||
if (error) {
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
goto out;
|
||||
@ -2286,12 +2282,12 @@ sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
|
||||
}
|
||||
mtx_lock(&mq->mq_mutex);
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
if (uap->sigev != NULL) {
|
||||
if (sigev != NULL) {
|
||||
if (mq->mq_notifier != NULL) {
|
||||
error = EBUSY;
|
||||
} else {
|
||||
PROC_LOCK(p);
|
||||
nt = notifier_search(p, uap->mqd);
|
||||
nt = notifier_search(p, mqd);
|
||||
if (nt == NULL) {
|
||||
if (newnt == NULL) {
|
||||
PROC_UNLOCK(p);
|
||||
@ -2314,10 +2310,10 @@ sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
|
||||
nt->nt_ksi.ksi_flags |= KSI_INS | KSI_EXT;
|
||||
nt->nt_ksi.ksi_code = SI_MESGQ;
|
||||
nt->nt_proc = p;
|
||||
nt->nt_ksi.ksi_mqd = uap->mqd;
|
||||
nt->nt_ksi.ksi_mqd = mqd;
|
||||
notifier_insert(p, nt);
|
||||
}
|
||||
nt->nt_sigev = ev;
|
||||
nt->nt_sigev = *sigev;
|
||||
mq->mq_notifier = nt;
|
||||
PROC_UNLOCK(p);
|
||||
/*
|
||||
@ -2330,7 +2326,7 @@ sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
|
||||
mqueue_send_notification(mq);
|
||||
}
|
||||
} else {
|
||||
notifier_remove(p, mq, uap->mqd);
|
||||
notifier_remove(p, mq, mqd);
|
||||
}
|
||||
mtx_unlock(&mq->mq_mutex);
|
||||
|
||||
@ -2341,6 +2337,23 @@ sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
|
||||
{
|
||||
struct sigevent ev, *evp;
|
||||
int error;
|
||||
|
||||
if (uap->sigev == NULL) {
|
||||
evp = NULL;
|
||||
} else {
|
||||
error = copyin(uap->sigev, &ev, sizeof(ev));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
evp = &ev;
|
||||
}
|
||||
return (kern_kmq_notify(td, uap->mqd, evp));
|
||||
}
|
||||
|
||||
static void
|
||||
mqueue_fdclose(struct thread *td, int fd, struct file *fp)
|
||||
{
|
||||
@ -2637,6 +2650,7 @@ static struct syscall_helper_data mq_syscalls[] = {
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
#include <compat/freebsd32/freebsd32.h>
|
||||
#include <compat/freebsd32/freebsd32_proto.h>
|
||||
#include <compat/freebsd32/freebsd32_signal.h>
|
||||
#include <compat/freebsd32/freebsd32_syscall.h>
|
||||
#include <compat/freebsd32/freebsd32_util.h>
|
||||
|
||||
@ -2763,12 +2777,33 @@ freebsd32_kmq_timedreceive(struct thread *td,
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_kmq_notify(struct thread *td, struct freebsd32_kmq_notify_args *uap)
|
||||
{
|
||||
struct sigevent ev, *evp;
|
||||
struct sigevent32 ev32;
|
||||
int error;
|
||||
|
||||
if (uap->sigev == NULL) {
|
||||
evp = NULL;
|
||||
} else {
|
||||
error = copyin(uap->sigev, &ev32, sizeof(ev32));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = convert_sigevent32(&ev32, &ev);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
evp = &ev;
|
||||
}
|
||||
return (kern_kmq_notify(td, uap->mqd, evp));
|
||||
}
|
||||
|
||||
static struct syscall_helper_data mq32_syscalls[] = {
|
||||
SYSCALL32_INIT_HELPER(freebsd32_kmq_open),
|
||||
SYSCALL32_INIT_HELPER(freebsd32_kmq_setattr),
|
||||
SYSCALL32_INIT_HELPER(freebsd32_kmq_timedsend),
|
||||
SYSCALL32_INIT_HELPER(freebsd32_kmq_timedreceive),
|
||||
SYSCALL32_INIT_HELPER_COMPAT(kmq_notify),
|
||||
SYSCALL32_INIT_HELPER(freebsd32_kmq_notify),
|
||||
SYSCALL32_INIT_HELPER_COMPAT(kmq_unlink),
|
||||
SYSCALL_INIT_LAST
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user