[PATCH][saslauthd] cyrus-sasl-2.1.10/saslauthd credential caching
Paul M Fleming
pfleming at siumed.edu
Wed Jan 15 14:27:20 EST 2003
_My_ original plan was to use libmm.. Jeremy already had a similiar
solution that he modified.
libmm does have the advantage that it is platform neutral -- no need for
fancy autoconf tricks to figure out what kinda of shm we have. not to
mention it can do the locking in a platform neutral format. If I have
time I might try to mangle Jeremy's code to use libmm..
We must be on the right track -- Rob and I both voiced the same concern
;-)
Rob Siemborski wrote:
>
> On Wed, 15 Jan 2003, Jeremy Rumpf wrote:
>
> > Ok, I've set things up on a Solaris 8 machine for testing. After a few tweaks,
> > things appear to be working ok. One thing though, it seems that the maximum
> > shared memory segment size on Solaris is 1M by default. Solaris users will
> > have to tweak their system settings if a larger cache is desired. Due to
> > this, I've set the default cache size to under 1M (down from ~4M). This way
> > saslauthd will always start with the cache enabled under default
> > circumstances.
>
> I've taken a look at this new code, and I have a number concerns right off
> the bat. (The idea is sound, I think, but it looks like the current
> implementation is a security nightmare).
>
> The biggie:
>
> cache_lookup() writes the user-provided password hash into the hash table
> BEFORE it is verfied. There's now a race where an attacker can submit an
> arbitrary string as a password, (if there's currently an entry in the
> cache, it will be evicted), then while the real lookup is happening he'll
> try a second authentication, which will succeed if cache_purge has not yet
> been called.
>
> I think I have a general problem with cache_lookup writing to the hash
> table, I'd expect "lookup" to be a read-only operation. If it fails, we
> do a lookup to the backend anyway, and then only if we SUCCEED in that
> lookup do we write the good password to the table.
>
> Another important one:
>
> No locking of any kind is used on the shared memory segment. I'm not sure
> this is directly exploitable, but it could give odd behavior.
>
> Let's assume that we've fixed the above problem. Now we have a
> cache_write() (that looks similar to the writing portion of the
> current cache_lookup()) instead of a cache_purge().
>
> If two processes are in cache_write at the same time, there's a race where
> they could both pick the same block to evict, and the result could be some
> mangled combination of both (or one or the other, but not both).
>
> Take this for instance (we assume that we had two cache misses, and that
> we only have one processor):
>
> processes
> time (a) (b)
> 1 find old bucket
> 2 find old bucket
>
> -they now have the same bucket-
>
> 3 compute pw hash
> 4 write pw hash
> 5 compute pw hash
> 6 write pw hash
> 7 write offsets
> 8 write offsets
> 9 write creds
> 10 write creds
>
> -uh-oh, now we have a bucket with offesets for one entry but
> -credentials and password for another
>
> 11 update timestamp
> 12 update timestamp
>
> There clearly needs to be some sort of semaphore on the table (or on
> entries, or something).
>
> Wasn't this originally going to use libmm?
>
> Finally:
>
> I think shared memory is way overkill for the doors version, since it all
> takes place within one process. Though, we'd still need to use some sort
> of councurrancy control.
>
> -Rob
>
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Rob Siemborski * Andrew Systems Group * Cyert Hall 207 * 412-268-7456
> Research Systems Programmer * /usr/contributed Gatekeeper
More information about the Info-cyrus
mailing list