[osiris-devel] Re: Hunting down lstat "bug" in scanner
Brian Wotring
brian at hostintegrity.com
Thu Sep 15 02:01:33 EDT 2005
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
More information about the osiris-devel
mailing list