stack abuse by linux_ioctl_cdrom
Andriy Gapon
avg at freebsd.org
Wed May 20 12:10:01 UTC 2009
This is a patch that I currently use to fix the problem for myself - both 2KB
structs are allocated on the heap.
I am not sure what is the proper style for chained calls using chained if-else,
but I think that the chaining is the best way to organize that piece of code, so
that there is only one exit point from case-block to make sure that FREE is always
called.
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index 8e42ec1..7e3453c 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -1538,23 +1538,28 @@ linux_ioctl_cdrom(struct thread *td, struct
linux_ioctl_args *args)
/* LINUX_CDROMAUDIOBUFSIZ */
case LINUX_DVD_READ_STRUCT: {
- l_dvd_struct lds;
- struct dvd_struct bds;
+ l_dvd_struct *p_lds;
+ struct dvd_struct *p_bds;
- error = copyin((void *)args->arg, &lds, sizeof(lds));
- if (error)
- break;
- error = linux_to_bsd_dvd_struct(&lds, &bds);
- if (error)
- break;
- error = fo_ioctl(fp, DVDIOCREADSTRUCTURE, (caddr_t)&bds,
- td->td_ucred, td);
- if (error)
- break;
- error = bsd_to_linux_dvd_struct(&bds, &lds);
- if (error)
- break;
- error = copyout(&lds, (void *)args->arg, sizeof(lds));
+ MALLOC(p_lds, l_dvd_struct *, sizeof(*p_lds),
+ M_LINUX, M_WAITOK);
+ MALLOC(p_bds, struct dvd_struct *, sizeof(*p_bds),
+ M_LINUX, M_WAITOK);
+ if ((error = copyin((void *)args->arg, p_lds, sizeof(*p_lds)))
+ != 0)
+ ; /* nothing */
+ else if ((error = linux_to_bsd_dvd_struct(p_lds, p_bds)) != 0)
+ ; /* nothing */
+ else if ((error = fo_ioctl(fp, DVDIOCREADSTRUCTURE,
+ (caddr_t)p_bds, td->td_ucred, td)) != 0)
+ ; /* nothing */
+ else if ((error = bsd_to_linux_dvd_struct(p_bds, p_lds)) != 0)
+ ; /* nothing */
+ else
+ error = copyout(p_lds, (void *)args->arg,
+ sizeof(*p_lds));
+ FREE(p_bds, M_LINUX);
+ FREE(p_lds, M_LINUX);
break;
}
--
Andriy Gapon
More information about the freebsd-stable
mailing list