The arg parameter is passed by value in Linux, but not in FreeBSD.

We still have to account for a copyin. Make sure the copyin will
succeed by passing the FreeBSD syscall a pointer to userspace,
albeit one that's automagically mapped into kernel space.

Reported by: mr, Mitsuru IWASAKI <iwasaki@jp.FreeBSD.org>
Tested by: Mitsuru IWASAKI <iwasaki@jp.FreeBSD.org>
This commit is contained in:
Marcel Moolenaar 2001-09-26 05:39:59 +00:00
parent 88b1d98f31
commit b18013f823

View File

@ -224,9 +224,14 @@ linux_semctl(struct thread *td, struct linux_semctl_args *args)
caddr_t sg;
sg = stackgap_init();
/* Make sure the arg parameter can be copied in. */
unptr = stackgap_alloc(&sg, sizeof(union semun));
bcopy(unptr, &args->arg, sizeof(union semun));
bsd_args.semid = args->semid;
bsd_args.semnum = args->semnum;
bsd_args.arg = (union semun *)&args->arg;
bsd_args.arg = unptr;
switch (args->cmd) {
case LINUX_IPC_RMID:
@ -253,10 +258,8 @@ linux_semctl(struct thread *td, struct linux_semctl_args *args)
sizeof(linux_semid));
if (error)
return (error);
unptr = stackgap_alloc(&sg, sizeof(union semun));
unptr->buf = stackgap_alloc(&sg, sizeof(struct semid_ds));
linux_to_bsd_semid_ds(&linux_semid, unptr->buf);
bsd_args.arg = unptr;
return __semctl(td, &bsd_args);
case LINUX_IPC_STAT:
case LINUX_SEM_STAT:
@ -264,9 +267,7 @@ linux_semctl(struct thread *td, struct linux_semctl_args *args)
bsd_args.cmd = IPC_STAT;
else
bsd_args.cmd = SEM_STAT;
unptr = stackgap_alloc(&sg, sizeof(union semun));
unptr->buf = stackgap_alloc(&sg, sizeof(struct semid_ds));
bsd_args.arg = unptr;
error = __semctl(td, &bsd_args);
if (error)
return error;