From owner-freebsd-emulation@FreeBSD.ORG Sun Jul 27 08:38:49 2008 Return-Path: Delivered-To: freebsd-emulation@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1FF1F106564A for ; Sun, 27 Jul 2008 08:38:49 +0000 (UTC) (envelope-from alexander@leidinger.net) Received: from redbull.bpaserver.net (redbullneu.bpaserver.net [213.198.78.217]) by mx1.freebsd.org (Postfix) with ESMTP id B91898FC08 for ; Sun, 27 Jul 2008 08:38:48 +0000 (UTC) (envelope-from alexander@leidinger.net) Received: from outgoing.leidinger.net (p54A55DC2.dip.t-dialin.net [84.165.93.194]) by redbull.bpaserver.net (Postfix) with ESMTP id 3E2972E4E7; Sat, 26 Jul 2008 09:17:22 +0200 (CEST) Received: from deskjail (deskjail.Leidinger.net [192.168.1.109]) by outgoing.leidinger.net (Postfix) with ESMTP id B59A26CAFA; Sat, 26 Jul 2008 09:10:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=Leidinger.net; s=outgoing-alex; t=1217056236; bh=0eVn/wXgW2lHAUtUNyZTTMI2UYmA7rBdw b1IktoTW6c=; h=Date:From:To:Cc:Subject:Message-ID:In-Reply-To: References:Mime-Version:Content-Type:Content-Transfer-Encoding; b=n5rGspdncQ0vxvSAvNrkeseMILj56aYnMxBk53IZDPgrp0fvRTTuvHNEQScOVQKxi 3wGEwuVn/MfMxGq48+bOYjrWbK4SWXSqKaFopQogiWk0sDGcSFbj80Wjhe2t/I+tIqr eA662Y4RvThOZaR0hVcreMxPeimQ/hdFQxzgVGhzQ0awx4UFI43al3fVnF8eRonHFkm Bs8N1ffoOFHTpXBDxgu+ITLndnMUZ+Yv2l9o77+hif09lnrK0ZcEp+Jk3q+YDBApooR lM3H8notsweyyfIsapCelRztt2tNUVeGsR/BXcr607QASZ5nQl+MLKowtsweJH6VPXI gy9zbnpXw== Date: Sat, 26 Jul 2008 09:10:45 +0200 From: Alexander Leidinger To: Chagin Dmitry Message-ID: <20080726091045.4c617dc7@deskjail> In-Reply-To: <200807250700.m6P70FSF036132@freefall.freebsd.org> References: <200807250700.m6P70FSF036132@freefall.freebsd.org> X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.11; i686-portbld-freebsd8.0) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-BPAnet-MailScanner-Information: Please contact the ISP for more information X-MailScanner-ID: 3E2972E4E7.A6BDE X-BPAnet-MailScanner: Found to be clean X-BPAnet-MailScanner-SpamCheck: not spam, ORDB-RBL, SpamAssassin (not cached, score=-14.823, required 6, BAYES_00 -15.00, DKIM_SIGNED 0.00, DKIM_VERIFIED -0.00, RDNS_DYNAMIC 0.10, TW_BD 0.08) X-BPAnet-MailScanner-From: alexander@leidinger.net X-Spam-Status: No Cc: freebsd-emulation@FreeBSD.org Subject: Re: kern/117010: [linux] linux_getdents() get somethinng like buffer overflow X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Jul 2008 08:38:49 -0000 Quoting Chagin Dmitry (Fri, 25 Jul 2008 07:00:15 GMT): > The following reply was made to PR kern/117010; it has been noted by GNATS. > > From: Chagin Dmitry > To: bug-followup@freebsd.org, samflanker@gmail.com > Cc: > Subject: Re: kern/117010: [linux] linux_getdents() get somethinng like buffer > overflow > Date: Fri, 25 Jul 2008 10:22:46 +0400 (MSD) > > Please, try a patch below: > > diff --git a/src/sys/compat/linux/linux_file.c b/src/sys/compat/linux/linux_file > index 303bc3f..d88f95f 100644 > --- a/src/sys/compat/linux/linux_file.c > +++ b/src/sys/compat/linux/linux_file.c > @@ -303,8 +303,8 @@ struct l_dirent64 { > char d_name[LINUX_NAME_MAX + 1]; > }; > > -#define LINUX_RECLEN(de,namlen) \ > - ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + 1)) > +#define LINUX_RECLEN(de,namlen,trail) \ > + ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + trail)) The start of de->d_name minus the start of de should be the same as the offset of d_name in de, so I would expect that this is expressed with the offsetof maro instead of handmade. So the result of this is the offset plus a len + something. > #define LINUX_DIRBLKSIZ 512 > > @@ -436,8 +436,8 @@ again: > } I try to understand the code before this. There's "if (reclen & 3)" error out. Does it mean it has to be a multiple of 4? If yes it should be changed to some modulo calculation to make it obvious (the compiler should be able to do such micro optimisations, but I doubt the error case needs to be micro optimized). > linuxreclen = (is64bit) > - ? LINUX_RECLEN(&linux_dirent64, bdp->d_namlen) > - : LINUX_RECLEN(&linux_dirent, bdp->d_namlen); > + ? LINUX_RECLEN(&linux_dirent64, bdp->d_namlen, 1) > + : LINUX_RECLEN(&linux_dirent, bdp->d_namlen, 2); Translated: The length of the linux record is the offset plus the FreeBSD size plus something. Doesn't make sense to me. sizeof(linux_dirent) sound more suitable for this variable name. From the code it can not be the length of the linux record, but the size of a linux dirent struct which would be required to put all info inside (+ some more space... very suspicious). > if (reclen > len || resid < linuxreclen) { > outp++; First part: if the length of the current record is larger than the remaining free space (if it does not fit) go out of the loop... ok. Second part: if the length (in bytes?) is smaller than the theoretical size of the linux struct, go out of the loop. Ouch. Please tell me this is wrong (I didn't had breakfast yet, I really hope I misanalysed this because of this fact). I smell buffer mismanagement because of the strange 1 or 2 being added to the size, and I smell some convoluted logic there. Instead of trying to poke the thing until it works, I suggest to step back and have a look at the big picture if the entire part of the function can be improved. > it solves getdents() problem (at least at x86_64 emulation with > linux_base-f8) > > ps, be not bared, linux really has such features... What I would expect is to compare the strlen of the FreeBSD record with the size of the place in linux_dirent. If the FreeBSD record does not fit, fail (ENAMETOOLONG?). Compare the remaining space with the size of linux_dirent, if it is '<=' fill in the data into the fixed size struct. Bye, Alexander. -- The best way to inspire fresh thoughts is to seal the letter. http://www.Leidinger.net Alexander @ Leidinger.net: PGP ID = B0063FE7 http://www.FreeBSD.org netchild @ FreeBSD.org : PGP ID = 72077137