<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1"
 http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Douglas K. Fischer wrote:<br>
<br>
<span style="white-space: pre;">&gt; Brian Wotring wrote:<br>
&gt; <br>
&gt;&gt; It's possible there is a buffer problem. The scanner makes
use of<br>
&gt;&gt; opendir() and readdir(). However, when the scanner encounters<br>
&gt;&gt; root-only readable files, the privsep module opens the file,<br>
&gt;&gt; passes down the file descriptor, and the scanner then makes
use<br>
&gt;&gt; of getdirentries() or getdents(), depending upon which one it<br>
&gt;&gt; has.<br>
&gt;&gt; <br>
&gt;&gt; <br>
&gt; Hmm... well we can narrow down a little more. From looking at the<br>
&gt; logs of all the systems I'm getting these errors on, all of the<br>
&gt; errors involve root-only perms, so the privsep module is used for<br>
&gt; all of them. So, all of the errors involve privsep, but only a<br>
&gt; small subset of privsep-using requests result in the errors. I<br>
&gt; hadn't delved into the privsep code yet, so that'll be my next
area<br>
&gt; to look at.</span><br>
<br>
The privsep code itself looks fine, since it doesn't actually do any<br>
buffer manipulations itself, just opening and fd passing.<br>
<br>
>From what I can deduce from glibc source (*ugh*), readdir(),<br>
getdirentries(), and getdents() all effectively do the same thing<br>
underneath, namely the getdents() system call. The main difference is<br>
in how large directories are managed.<br>
<br>
readdir() does it automagically, making multiple getdents() calls as<br>
needed to refill the buffer when the end is reached.<br>
<br>
getdirentries() only fetches a single buffer's worth of entries, but<br>
it will update basep if there's more (i.e. it's up to the app code to<br>
check basep and refill the buffer when the end is reached if there are<br>
more entries).<br>
<br>
getdents() is bare-boned in that it will fetch a single buffer's<br>
worth, and that's pretty much it. It's up to the app code to both<br>
detect that there are more dirents and to fetch them.<br>
<br>
So, it would seem that in the event that a directory contains &gt;
8192<br>
bytes of dirents, osi_readdir() is going to miss any entries beyond<br>
8192 bytes since neither getdirentries() nor getdents() will fetch the<br>
remainder on its own. This can only happen when privsep is used, as<br>
non-privsep invokes readdir(), which manages multiple fetches
internally.<br>
<br>
Dunno if this is what's causing the problem, but it would appear to be<br>
something that needs to be addressed either way.<br>
<br>
Doug<br>
<br>
</body>
</html>