[osiris-devel] Re: Hunting down lstat "bug" in scanner

Douglas K. Fischer fischerdk at fidoki.com
Wed Sep 14 14:04:40 EDT 2005


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 


More information about the osiris-devel mailing list