From fischerdk at fidoki.com Tue Sep 13 16:46:53 2005 From: fischerdk at fidoki.com (Douglas K. Fischer) Date: Tue, 13 Sep 2005 16:46:53 -0400 Subject: [osiris-devel] Hunting down lstat "bug" in scanner Message-ID: <43273ABD.40308@fidoki.com> Hi Brian, I've been doing some prelim work on hunting down what appears to be a bug in the osirisd scanner. I have been getting spurious "error conducting lstat on file" errors on scanning numerous hosts. What is peculiar is that A) it is not always the same filenames or directories, and B) the filename is always the form of PATH/CTL, where PATH is an arbitrary path and CTL is a control char (\1, \2, etc, showing as ^A, ^B, etc). >From what time I've had to work on this, I've run some basic straces and found that the scanner process is indeed trying to lstat a file by this name: 19109 lstat64("/var/lib/mysql/myisam/data/test/^B", 0xbffde810) = -1 EACCES (Permission denied) and since it doesn't have perms to the directory hierarchy it is of course then attempting rootpriv lstat-ing: 19109 write(3, "\3", 1) = 1 19109 write(3, "/var/lib/mysql/myisam/data/test/\2", 33) = 33 19105 read(4, "/var/lib/mysql/myisam/data/test/\2", 256) = 33 19105 lstat64("/var/lib/mysql/myisam/data/test/^B", 0xbffec6f0) = -1 ENOENT (No such file or directory) which of course results in the error: [503][dev01][err] error conducting lstat on file "/var/lib/mysql/myisam/data/test/^B" So the point I'm at is trying to determine where the trailing control char is coming from. It appears that the errant filename is attempted after all of the existing entries for a directory have been completed. An strace of the getdents() call does not show any garbling of the dirents, nor is there an extra one that would account for the errant entry. As a sanity check I'm going to verify that there are no filesystem problems, etc. Does any of this ring a bell? Thanks, Doug From brian at hostintegrity.com Tue Sep 13 16:58:21 2005 From: brian at hostintegrity.com (Brian Wotring) Date: Tue, 13 Sep 2005 12:58:21 -0800 Subject: [osiris-devel] Re: Hunting down lstat "bug" in scanner In-Reply-To: <43273ABD.40308@fidoki.com> References: <43273ABD.40308@fidoki.com> Message-ID: <43273D6D.8010103@hostintegrity.com> No, it doesn't ring a bell. Thank you for the detailed analysis :) In my experience, this sounds like it's likely one of the following: 1) bad string manipulation code. 2) race condition on temporary files. What version of osiris is this? What platforms are you seeing this on? How often do you see these errors, on (almost) every scan or is it infrequent? -brian Douglas K. Fischer wrote: > Hi Brian, > > I've been doing some prelim work on hunting down what appears to be a > bug in the osirisd scanner. I have been getting spurious "error > conducting lstat on file" errors on scanning numerous hosts. What is > peculiar is that A) it is not always the same filenames or directories, > and B) the filename is always the form of PATH/CTL, where PATH is an > arbitrary path and CTL is a control char (\1, \2, etc, showing as ^A, > ^B, etc). > >>From what time I've had to work on this, I've run some basic straces and > found that the scanner process is indeed trying to lstat a file by this > name: > > 19109 lstat64("/var/lib/mysql/myisam/data/test/^B", 0xbffde810) = -1 > EACCES (Permission denied) > > and since it doesn't have perms to the directory hierarchy it is of > course then attempting rootpriv lstat-ing: > > 19109 write(3, "\3", 1) = 1 > 19109 write(3, "/var/lib/mysql/myisam/data/test/\2", 33) = 33 > > 19105 read(4, "/var/lib/mysql/myisam/data/test/\2", 256) = 33 > 19105 lstat64("/var/lib/mysql/myisam/data/test/^B", 0xbffec6f0) = -1 > ENOENT (No such file or directory) > > which of course results in the error: > > [503][dev01][err] error conducting lstat on file "/var/lib/mysql/myisam/data/test/^B" > > > So the point I'm at is trying to determine where the trailing control > char is coming from. > > It appears that the errant filename is attempted after all of the > existing entries for a directory have been completed. An strace of the > getdents() call does not show any garbling of the dirents, nor is there > an extra one that would account for the errant entry. As a sanity check > I'm going to verify that there are no filesystem problems, etc. > > Does any of this ring a bell? > > Thanks, > > Doug > > _______________________________________________ > osiris-devel mailing list > osiris-devel at lists.shmoo.com > https://lists.shmoo.com/mailman/listinfo/osiris-devel From fischerdk at fidoki.com Tue Sep 13 18:04:42 2005 From: fischerdk at fidoki.com (Douglas K. Fischer) Date: Tue, 13 Sep 2005 18:04:42 -0400 Subject: [osiris-devel] Re: Hunting down lstat "bug" in scanner In-Reply-To: <43273D6D.8010103@hostintegrity.com> References: <43273ABD.40308@fidoki.com> <43273D6D.8010103@hostintegrity.com> Message-ID: <43274CFA.806@fidoki.com> Brian Wotring wrote: >No, it doesn't ring a bell. Thank you for the detailed analysis :) In >my experience, this sounds like it's likely one of the following: > >1) bad string manipulation code. >2) race condition on temporary files. > >What version of osiris is this? > 4.1.9 >What platforms are you seeing this on? > > Linux >How often do you see these errors, on (almost) every scan or is it >infrequent? > > Every scan. It also appears to be the same directories, which is why directory entry corruption also comes to mind. Otherwise, if it's in the scanner code, it would probably involve either the OSI_DIRECTORY struct that's used in process_directory() or the file_path array, so it would likely be in one of the following: process_directory() osi_open_directory() (not too likely) osi_get_next_file() osi_readdir() osi_strlcopy() I haven't seen anything obvious, but I would guess either a buffer is being reused without being zeroed out or a buffer is being overflowed (not likely given the careful checking being done that I've seen). I haven't seen anywhere that a race condition could come in. At least the troubleshooting let's me exercise my paltry C skills :-) Thanks, Doug From brian at hostintegrity.com Wed Sep 14 02:28:29 2005 From: brian at hostintegrity.com (Brian Wotring) Date: Tue, 13 Sep 2005 22:28:29 -0800 Subject: [osiris-devel] Re: Hunting down lstat "bug" in scanner In-Reply-To: <43274CFA.806@fidoki.com> References: <43273ABD.40308@fidoki.com> <43273D6D.8010103@hostintegrity.com> <43274CFA.806@fidoki.com> Message-ID: <4327C30D.4050000@hostintegrity.com> It's possible there is a buffer problem. The scanner makes use of opendir() and readdir(). However, when the scanner encounters root-only readable files, the privsep module opens the file, passes down the file descriptor, and the scanner then makes use of getdirentries() or getdents(), depending upon which one it has. The scanner tries to use getdirentries() first, then resorts to getdents(). Check your config.h and verify that HAVE_GETDIRENTRIES is defined. Are these 64 bit systems? -brian Douglas K. Fischer wrote: > Brian Wotring wrote: > > >>No, it doesn't ring a bell. Thank you for the detailed analysis :) In >>my experience, this sounds like it's likely one of the following: >> >>1) bad string manipulation code. >>2) race condition on temporary files. >> >>What version of osiris is this? >> > > 4.1.9 > > >>What platforms are you seeing this on? >> >> > > Linux > > >>How often do you see these errors, on (almost) every scan or is it >>infrequent? >> >> > > Every scan. > > It also appears to be the same directories, which is why directory entry > corruption also comes to mind. Otherwise, if it's in the scanner code, > it would probably involve either the OSI_DIRECTORY struct that's used in > process_directory() or the file_path array, so it would likely be in one > of the following: > > process_directory() > osi_open_directory() (not too likely) > osi_get_next_file() > osi_readdir() > osi_strlcopy() > > I haven't seen anything obvious, but I would guess either a buffer is > being reused without being zeroed out or a buffer is being overflowed > (not likely given the careful checking being done that I've seen). I > haven't seen anywhere that a race condition could come in. > > At least the troubleshooting let's me exercise my paltry C skills :-) > > Thanks, > > Doug > > _______________________________________________ > osiris-devel mailing list > osiris-devel at lists.shmoo.com > https://lists.shmoo.com/mailman/listinfo/osiris-devel From fischerdk at fidoki.com Wed Sep 14 11:59:05 2005 From: fischerdk at fidoki.com (Douglas K. Fischer) Date: Wed, 14 Sep 2005 11:59:05 -0400 Subject: [osiris-devel] Re: Hunting down lstat "bug" in scanner In-Reply-To: <4327C30D.4050000@hostintegrity.com> References: <43273ABD.40308@fidoki.com> <43273D6D.8010103@hostintegrity.com> <43274CFA.806@fidoki.com> <4327C30D.4050000@hostintegrity.com> Message-ID: <432848C9.1010303@fidoki.com> Brian Wotring wrote: >It's possible there is a buffer problem. The scanner makes use of >opendir() and readdir(). However, when the scanner encounters root-only >readable files, the privsep module opens the file, passes down the file >descriptor, and the scanner then makes use of getdirentries() or >getdents(), depending upon which one it has. > > Hmm... well we can narrow down a little more. From looking at the logs of all the systems I'm getting these errors on, all of the errors involve root-only perms, so the privsep module is used for all of them. So, all of the errors involve privsep, but only a small subset of privsep-using requests result in the errors. I hadn't delved into the privsep code yet, so that'll be my next area to look at. >The scanner tries to use getdirentries() first, then resorts to >getdents(). Check your config.h and verify that HAVE_GETDIRENTRIES is >defined. > > Yup. >Are these 64 bit systems? > > No. Doug From fischerdk at fidoki.com Wed Sep 14 14:04:40 2005 From: fischerdk at fidoki.com (Douglas K. Fischer) Date: Wed, 14 Sep 2005 14:04:40 -0400 Subject: [osiris-devel] Re: Hunting down lstat "bug" in scanner In-Reply-To: <432848C9.1010303@fidoki.com> References: <43273ABD.40308@fidoki.com> <43273D6D.8010103@hostintegrity.com> <43274CFA.806@fidoki.com> <4327C30D.4050000@hostintegrity.com> <432848C9.1010303@fidoki.com> Message-ID: <43286638.4010707@fidoki.com> Douglas K. Fischer wrote: > Brian Wotring wrote: > >> It's possible there is a buffer problem. The scanner makes use of >> opendir() and readdir(). However, when the scanner encounters >> root-only readable files, the privsep module opens the file, >> passes down the file descriptor, and the scanner then makes use >> of getdirentries() or getdents(), depending upon which one it >> has. >> >> > Hmm... well we can narrow down a little more. From looking at the > logs of all the systems I'm getting these errors on, all of the > errors involve root-only perms, so the privsep module is used for > all of them. So, all of the errors involve privsep, but only a > small subset of privsep-using requests result in the errors. I > hadn't delved into the privsep code yet, so that'll be my next area > to look at. The privsep code itself looks fine, since it doesn't actually do any buffer manipulations itself, just opening and fd passing. >From what I can deduce from glibc source (*ugh*), readdir(), getdirentries(), and getdents() all effectively do the same thing underneath, namely the getdents() system call. The main difference is in how large directories are managed. readdir() does it automagically, making multiple getdents() calls as needed to refill the buffer when the end is reached. getdirentries() only fetches a single buffer's worth of entries, but it will update basep if there's more (i.e. it's up to the app code to check basep and refill the buffer when the end is reached if there are more entries). getdents() is bare-boned in that it will fetch a single buffer's worth, and that's pretty much it. It's up to the app code to both detect that there are more dirents and to fetch them. So, it would seem that in the event that a directory contains > 8192 bytes of dirents, osi_readdir() is going to miss any entries beyond 8192 bytes since neither getdirentries() nor getdents() will fetch the remainder on its own. This can only happen when privsep is used, as non-privsep invokes readdir(), which manages multiple fetches internally. Dunno if this is what's causing the problem, but it would appear to be something that needs to be addressed either way. Doug -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.shmoo.com/pipermail/osiris-devel/attachments/20050914/6ee556d9/attachment.htm From brian at hostintegrity.com Thu Sep 15 02:01:33 2005 From: brian at hostintegrity.com (Brian Wotring) Date: Wed, 14 Sep 2005 22:01:33 -0800 Subject: [osiris-devel] Re: Hunting down lstat "bug" in scanner In-Reply-To: <43286638.4010707@fidoki.com> References: <43273ABD.40308@fidoki.com> <43273D6D.8010103@hostintegrity.com> <43274CFA.806@fidoki.com> <4327C30D.4050000@hostintegrity.com> <432848C9.1010303@fidoki.com> <43286638.4010707@fidoki.com> Message-ID: <43290E3D.9090407@hostintegrity.com> At this point, it makes sense to write a test app that makes use of the osi_readdir() code to see if this problem can be duplicated. If I am unable to duplicate it, do you have a system that demonstrates this problem that you would be willing to try to duplicate it on? I'll post the app shortly. -brian Douglas K. Fischer wrote: > Douglas K. Fischer wrote: > >> Brian Wotring wrote: >> >> > It's possible there is a buffer problem. The scanner makes use of >> > opendir() and readdir(). However, when the scanner encounters >> > root-only readable files, the privsep module opens the file, >> > passes down the file descriptor, and the scanner then makes use >> > of getdirentries() or getdents(), depending upon which one it >> > has. >> > >> > >> Hmm... well we can narrow down a little more. From looking at the >> logs of all the systems I'm getting these errors on, all of the >> errors involve root-only perms, so the privsep module is used for >> all of them. So, all of the errors involve privsep, but only a >> small subset of privsep-using requests result in the errors. I >> hadn't delved into the privsep code yet, so that'll be my next area >> to look at. > > The privsep code itself looks fine, since it doesn't actually do any > buffer manipulations itself, just opening and fd passing. > > >From what I can deduce from glibc source (*ugh*), readdir(), > getdirentries(), and getdents() all effectively do the same thing > underneath, namely the getdents() system call. The main difference is > in how large directories are managed. > > readdir() does it automagically, making multiple getdents() calls as > needed to refill the buffer when the end is reached. > > getdirentries() only fetches a single buffer's worth of entries, but > it will update basep if there's more (i.e. it's up to the app code to > check basep and refill the buffer when the end is reached if there are > more entries). > > getdents() is bare-boned in that it will fetch a single buffer's > worth, and that's pretty much it. It's up to the app code to both > detect that there are more dirents and to fetch them. > > So, it would seem that in the event that a directory contains > 8192 > bytes of dirents, osi_readdir() is going to miss any entries beyond > 8192 bytes since neither getdirentries() nor getdents() will fetch the > remainder on its own. This can only happen when privsep is used, as > non-privsep invokes readdir(), which manages multiple fetches internally. > > Dunno if this is what's causing the problem, but it would appear to be > something that needs to be addressed either way. > > Doug > > > ------------------------------------------------------------------------ > > _______________________________________________ > osiris-devel mailing list > osiris-devel at lists.shmoo.com > https://lists.shmoo.com/mailman/listinfo/osiris-devel From brian at hostintegrity.com Thu Sep 15 02:41:14 2005 From: brian at hostintegrity.com (Brian Wotring) Date: Wed, 14 Sep 2005 22:41:14 -0800 Subject: [osiris-devel] Re: Hunting down lstat "bug" in scanner In-Reply-To: <43290E3D.9090407@hostintegrity.com> References: <43273ABD.40308@fidoki.com> <43273D6D.8010103@hostintegrity.com> <43274CFA.806@fidoki.com> <4327C30D.4050000@hostintegrity.com> <432848C9.1010303@fidoki.com> <43286638.4010707@fidoki.com> <43290E3D.9090407@hostintegrity.com> Message-ID: <4329178A.20708@hostintegrity.com> Attached is a sample application that makes use of osi_readdir() to traverse a directory and list the entries, the same way the privsep code does. -brian Brian Wotring wrote: > At this point, it makes sense to write a test app that makes use of the > osi_readdir() code to see if this problem can be duplicated. > > If I am unable to duplicate it, do you have a system that demonstrates > this problem that you would be willing to try to duplicate it on? I'll > post the app shortly. > > -brian > > Douglas K. Fischer wrote: > >>Douglas K. Fischer wrote: >> >> >>> Brian Wotring wrote: >>> >>> >>>>It's possible there is a buffer problem. The scanner makes use of >>>>opendir() and readdir(). However, when the scanner encounters >>>>root-only readable files, the privsep module opens the file, >>>>passes down the file descriptor, and the scanner then makes use >>>>of getdirentries() or getdents(), depending upon which one it >>>>has. >>>> >>>> >>> >>> Hmm... well we can narrow down a little more. From looking at the >>> logs of all the systems I'm getting these errors on, all of the >>> errors involve root-only perms, so the privsep module is used for >>> all of them. So, all of the errors involve privsep, but only a >>> small subset of privsep-using requests result in the errors. I >>> hadn't delved into the privsep code yet, so that'll be my next area >>> to look at. >> >>The privsep code itself looks fine, since it doesn't actually do any >>buffer manipulations itself, just opening and fd passing. >> >> >From what I can deduce from glibc source (*ugh*), readdir(), >>getdirentries(), and getdents() all effectively do the same thing >>underneath, namely the getdents() system call. The main difference is >>in how large directories are managed. >> >>readdir() does it automagically, making multiple getdents() calls as >>needed to refill the buffer when the end is reached. >> >>getdirentries() only fetches a single buffer's worth of entries, but >>it will update basep if there's more (i.e. it's up to the app code to >>check basep and refill the buffer when the end is reached if there are >>more entries). >> >>getdents() is bare-boned in that it will fetch a single buffer's >>worth, and that's pretty much it. It's up to the app code to both >>detect that there are more dirents and to fetch them. >> >>So, it would seem that in the event that a directory contains > 8192 >>bytes of dirents, osi_readdir() is going to miss any entries beyond >>8192 bytes since neither getdirentries() nor getdents() will fetch the >>remainder on its own. This can only happen when privsep is used, as >>non-privsep invokes readdir(), which manages multiple fetches internally. >> >>Dunno if this is what's causing the problem, but it would appear to be >>something that needs to be addressed either way. >> >>Doug >> >> >>------------------------------------------------------------------------ >> >>_______________________________________________ >>osiris-devel mailing list >>osiris-devel at lists.shmoo.com >>https://lists.shmoo.com/mailman/listinfo/osiris-devel > > > _______________________________________________ > osiris-devel mailing list > osiris-devel at lists.shmoo.com > https://lists.shmoo.com/mailman/listinfo/osiris-devel -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: dir.c Url: http://lists.shmoo.com/pipermail/osiris-devel/attachments/20050914/67115c71/attachment.txt From fischerdk at fidoki.com Thu Sep 15 12:07:58 2005 From: fischerdk at fidoki.com (Douglas K. Fischer) Date: Thu, 15 Sep 2005 12:07:58 -0400 Subject: [osiris-devel] Re: Hunting down lstat "bug" in scanner In-Reply-To: <4329178A.20708@hostintegrity.com> References: <43273ABD.40308@fidoki.com> <43273D6D.8010103@hostintegrity.com> <43274CFA.806@fidoki.com> <4327C30D.4050000@hostintegrity.com> <432848C9.1010303@fidoki.com> <43286638.4010707@fidoki.com> <43290E3D.9090407@hostintegrity.com> <4329178A.20708@hostintegrity.com> Message-ID: <43299C5E.7080804@fidoki.com> Bingo. I was readily able to replicate it, and the problem appears to be with the exit conditions of osi_readdir(). The if( dp->d_reclen <= 0 || dp->d_reclen > d->dd_len + 1 - d->dd_loc ) statement does not correctly catch the case when we've reached the last dirent entry that was returned by the fetch. We need to look at dd_size compared with dd_loc to determine if we've reached the end of the fetched entries (from glibc readdir() code). The outcome is otherwise determined by the contents of the buffer past dd_size. In most of the cases the resulting next read would fail the above condition and exit with NULL, or fail one of the other NULL-returning conditions. However, in some cases the buffer contents were such that a non-NULL return resulted. I've attached a version of osi_readdir() that should solve this, as well as deal with the aforementioned case where we need to perform one or more additional getdirentries() in order to get the rest of the dirents. The code is very similar to the glibc readdir() code, so it should behave is almost exactly the same manner. I don't have access to a system with getdents() instead of getdirentries(), so I can't vouch for correct operation of the re-fetching with getdents(). However, I've attached a simple patch to my version of osi_readdir() that will disable the re-fetching for getdents() if it doesn't work. (Provided that the underlying system call keeps the fd seek pointer at the end of the last read from getdents(), this should work I believe.) Also, the restructuring of the osi_readdir() loop resulted in the exclusion of the IRIX #ifndef around the zero inode checking. This may or may not cause the problem to return on IRIX. I didn't see anything in the glibc code that was different for IRIX. Was it all versions of IRIX or a specific one? I've attached another patch in case this does cause a problem with IRIX. Cheers, Doug Brian Wotring wrote: > Attached is a sample application that makes use of osi_readdir() to > traverse a directory and list the entries, the same way the privsep > code does. > > -brian > > Brian Wotring wrote: > >> At this point, it makes sense to write a test app that makes use of >> the osi_readdir() code to see if this problem can be duplicated. >> >> If I am unable to duplicate it, do you have a system that >> demonstrates this problem that you would be willing to try to >> duplicate it on? I'll post the app shortly. >> >> -brian > -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: osi_readdir.c Url: http://lists.shmoo.com/pipermail/osiris-devel/attachments/20050915/2a4ce091/attachment.txt -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: osi_readdir-getdents.patch Url: http://lists.shmoo.com/pipermail/osiris-devel/attachments/20050915/2a4ce091/attachment-0001.txt -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: osi_readdir-irix.patch Url: http://lists.shmoo.com/pipermail/osiris-devel/attachments/20050915/2a4ce091/attachment-0002.txt From brian at hostintegrity.com Fri Sep 16 21:26:26 2005 From: brian at hostintegrity.com (Brian Wotring) Date: Fri, 16 Sep 2005 17:26:26 -0800 Subject: [osiris-devel] Re: Hunting down lstat "bug" in scanner In-Reply-To: <43299C5E.7080804@fidoki.com> References: <43273ABD.40308@fidoki.com> <43273D6D.8010103@hostintegrity.com> <43274CFA.806@fidoki.com> <4327C30D.4050000@hostintegrity.com> <432848C9.1010303@fidoki.com> <43286638.4010707@fidoki.com> <43290E3D.9090407@hostintegrity.com> <4329178A.20708@hostintegrity.com> <43299C5E.7080804@fidoki.com> Message-ID: <432B70C2.9080600@hostintegrity.com> Awesome. Thanks for testing that. I'll verify this and the getdents() portions. -brian Douglas K. Fischer wrote: > Bingo. I was readily able to replicate it, and the problem appears to be > with the exit conditions of osi_readdir(). The > > if( dp->d_reclen <= 0 || dp->d_reclen > d->dd_len + 1 - d->dd_loc ) > > statement does not correctly catch the case when we've reached the last > dirent entry that was returned by the fetch. We need to look at dd_size > compared with dd_loc to determine if we've reached the end of the > fetched entries (from glibc readdir() code). The outcome is otherwise > determined by the contents of the buffer past dd_size. In most of the > cases the resulting next read would fail the above condition and exit > with NULL, or fail one of the other NULL-returning conditions. However, > in some cases the buffer contents were such that a non-NULL return resulted. > > I've attached a version of osi_readdir() that should solve this, as well > as deal with the aforementioned case where we need to perform one or > more additional getdirentries() in order to get the rest of the dirents. > The code is very similar to the glibc readdir() code, so it should > behave is almost exactly the same manner. > > I don't have access to a system with getdents() instead of > getdirentries(), so I can't vouch for correct operation of the > re-fetching with getdents(). However, I've attached a simple patch to my > version of osi_readdir() that will disable the re-fetching for > getdents() if it doesn't work. (Provided that the underlying system call > keeps the fd seek pointer at the end of the last read from getdents(), > this should work I believe.) > > Also, the restructuring of the osi_readdir() loop resulted in the > exclusion of the IRIX #ifndef around the zero inode checking. This may > or may not cause the problem to return on IRIX. I didn't see anything in > the glibc code that was different for IRIX. Was it all versions of IRIX > or a specific one? I've attached another patch in case this does cause a > problem with IRIX. > > Cheers, > > Doug > > Brian Wotring wrote: > > >>Attached is a sample application that makes use of osi_readdir() to >>traverse a directory and list the entries, the same way the privsep >>code does. >> >>-brian >> >>Brian Wotring wrote: >> >> >>>At this point, it makes sense to write a test app that makes use of >>>the osi_readdir() code to see if this problem can be duplicated. >>> >>>If I am unable to duplicate it, do you have a system that >>>demonstrates this problem that you would be willing to try to >>>duplicate it on? I'll post the app shortly. >>> >>>-brian >> > > > > ------------------------------------------------------------------------ > > struct dirent *osi_readdir( OSI_DIRECTORY *d ) > { > #if defined(HAVE_GETDIRENTRIES) || defined(HAVE_GETDENTS) > > register struct dirent *dp; > > if( d == NULL ) > { > return NULL; > } > > do > { > /* > * We want to fetch new dirents if either: > * 1. This is our first read of the directory > * 2. We've reached the end of a previous fetch for this directory > * and there might be more dirents to fetch > */ > if( d->dd_loc >= d->dd_size ) > { > #ifdef HAVE_GETDIRENTRIES > d->dd_size = getdirentries( d->dd_fd, d->buffer, > d->dd_len, &d->dd_seek ); > #else > d->dd_size = getdents( d->dd_fd, (struct dirent *)d->buffer, > d->dd_len ); > #endif > > if( d->dd_size <= 0 ) > { > return NULL; > } > > d->dd_loc = 0; /* Reset if this is a secondary fetch */ > } > > dp = (struct dirent *)(d->buffer + d->dd_loc); > > if( dp == NULL ) > { > return NULL; > } > > d->dd_loc += dp->d_reclen; > > } while( dp->d_ino == 0 ); /* Skip deleted entries */ > > d->file = dp; > > if( d->file->d_name[0] == '\0' ) > { > return NULL; > } > > return dp; > > #endif /* HAVE_GETDIRENTRIES */ > > return NULL; > } > > > ------------------------------------------------------------------------ > > --- osi_readdir.c.orig Thu Sep 15 11:37:48 2005 > +++ osi_readdir.c Thu Sep 15 11:39:24 2005 > @@ -15,17 +15,19 @@ > * We want to fetch new dirents if either: > * 1. This is our first read of the directory > * 2. We've reached the end of a previous fetch for this directory > - * and there might be more dirents to fetch > + * and there might be more dirents to fetch (getdirentries only) > */ > + #ifdef HAVE_GETDIRENTRIES > if( d->dd_loc >= d->dd_size ) > { > - #ifdef HAVE_GETDIRENTRIES > d->dd_size = getdirentries( d->dd_fd, d->buffer, > d->dd_len, &d->dd_seek ); > - #else > + #else > + if( d->dd_loc == 0 ) > + { > d->dd_size = getdents( d->dd_fd, (struct dirent *)d->buffer, > d->dd_len ); > - #endif > + #endif > > if( d->dd_size <= 0 ) > { > > > ------------------------------------------------------------------------ > > --- osi_readdir.c.orig Thu Sep 15 11:37:48 2005 > +++ osi_readdir.c Thu Sep 15 12:06:16 2005 > @@ -44,7 +44,11 @@ > > d->dd_loc += dp->d_reclen; > > +#ifndef SYSTEM_IRIX > } while( dp->d_ino == 0 ); /* Skip deleted entries */ > +#else > + } while( 1 ); > +#endif > > d->file = dp; > > > > ------------------------------------------------------------------------ > > _______________________________________________ > osiris-devel mailing list > osiris-devel at lists.shmoo.com > https://lists.shmoo.com/mailman/listinfo/osiris-devel