From owner-freebsd-stable@FreeBSD.ORG Wed May 20 12:09:50 2009 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C1D0B1065A97; Wed, 20 May 2009 12:09:49 +0000 (UTC) (envelope-from avg@freebsd.org) Received: from citadel.icyb.net.ua (citadel.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id BA64F8FC08; Wed, 20 May 2009 12:09:48 +0000 (UTC) (envelope-from avg@freebsd.org) Received: from odyssey.starpoint.kiev.ua (alpha-e.starpoint.kiev.ua [212.40.38.101]) by citadel.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id PAA15002; Wed, 20 May 2009 15:09:47 +0300 (EEST) (envelope-from avg@freebsd.org) Message-ID: <4A13F30A.2090401@freebsd.org> Date: Wed, 20 May 2009 15:09:46 +0300 From: Andriy Gapon User-Agent: Thunderbird 2.0.0.21 (X11/20090406) MIME-Version: 1.0 To: freebsd-stable@freebsd.org, Chagin Dmitry References: <4A1165A0.6000800@icyb.net.ua> <4A1167A2.6040407@freebsd.org> In-Reply-To: <4A1167A2.6040407@freebsd.org> X-Enigmail-Version: 0.95.7 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Cc: John Baldwin Subject: Re: stack abuse by linux_ioctl_cdrom X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 May 2009 12:10:01 -0000 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