Date: Sun, 10 Mar 1996 18:44:33 -0800 From: David Greenman <davidg@Root.COM> To: Mostyn/Annabella <mrl@teleport.com> Cc: current@freebsd.org Subject: Re: Today's -current + cd9660 Message-ID: <199603110244.SAA15891@Root.COM> In-Reply-To: Your message of "Sun, 10 Mar 1996 17:28:53 PST." <199603110128.RAA22856@linda.teleport.com>
next in thread | previous in thread | raw e-mail | index | archive | help
>Hi All, >It's alreadi been reported that cd9660_readdir panics at 0x1a7 with >a movzbl 0(%ecx),%esi - well it still does - and examining the code >points to the line > >isoflags = isonum_711(imp->iso_ftype == ISO_FTYPE_HIGH_SIERRA? > &ep->date[6]: ep->flags); > >In that routine - it seems that the dereference of ep causes the >panic. Seems the system buffer is not mapped?! Bruce's fix for this is attached. -DG David Greenman Core-team/Principal Architect, The FreeBSD Project Date: Fri, 8 Mar 1996 06:53:48 +1100 From: Bruce Evans <bde@zeta.org.au> >I can reliably reproduce a "Fatal trap 12: page fault while in kernel >mode" in a current kernel (up to date as of a few hours ago). I reproduce >it by mounting the FreeBSD 2.1 "live file system" CD and doing some file >name completion in the Xlib source tree (using bash), e.g. > $ more /cdrom/usr/X11R6/src/xc/lib/X11/<TAB> >The fault address on one instance was 0xf08aa001, and the fault code is >"supervisor read, page not present". The instruction pointer is at: > _cd9660_readdir+0x1a7: movzbl 0(%ecx),%esi >%ecx is the fault address. This is easy to reproduce and seems to be a bug in cd9660_readdir(). An invalid directory entry is accessed one statment before the check that finds it to be invalid. My fix delays the access and some other access until the reclen and namlen checks are done. Apparently it is OK to access the parts of the directory entry containing the reclen and the namlen, although there is no such thing as a partial struct in C. Skipping the faulting instructing in ddb happens to work safely. For some reason the bug wasn't reproducible after that (even after switching to another cdrom and back). Bruce *** cd9660_vnops.c~ Mon Dec 4 15:44:02 1995 --- cd9660_vnops.c Fri Mar 8 05:54:13 1996 *************** *** 559,562 **** --- 559,563 ---- struct iso_directory_record *ep; u_short elen; + int namlen; int reclen; int isoflags; *************** *** 620,625 **** reclen = isonum_711 (ep->length); - isoflags = isonum_711(imp->iso_ftype == ISO_FTYPE_HIGH_SIERRA? - &ep->date[6]: ep->flags); if (reclen == 0) { /* skip to next block, if any */ --- 621,624 ---- *************** *** 641,648 **** } /* XXX: be more intelligent if we can */ idp->current.d_type = DT_UNKNOWN; ! idp->current.d_namlen = isonum_711 (ep->name_len); if (isoflags & 2) isodirino(&idp->current.d_fileno,ep,imp); --- 640,656 ---- } + namlen = isonum_711 (ep->name_len); + if (reclen < ISO_DIRECTORY_RECORD_SIZE + namlen) { + error = EINVAL; + /* illegal entry, stop */ + break; + } + /* XXX: be more intelligent if we can */ idp->current.d_type = DT_UNKNOWN; ! idp->current.d_namlen = namlen; ! isoflags = isonum_711(imp->iso_ftype == ISO_FTYPE_HIGH_SIERRA? ! &ep->date[6]: ep->flags); if (isoflags & 2) isodirino(&idp->current.d_fileno,ep,imp); *************** *** 650,659 **** idp->current.d_fileno = dbtob(bp->b_blkno) + idp->curroff; - - if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { - error = EINVAL; - /* illegal entry, stop */ - break; - } idp->curroff += reclen; --- 658,661 ----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199603110244.SAA15891>