[PATCH] Fix use after free in closedir
Corinna Vinschen
vinschen@redhat.com
Wed Nov 13 15:17:00 GMT 2013
Hi Federico,
On Nov 13 12:22, Federico Terraneo wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> closedir() calls _cleanupdir() on a pointer to DIR after a free().
> If HAVE_DD_LOCK is defined, it also dereferences the pointer when
> calling __lock_release_recursive() and __lock_close_recursive().
> This was creating problems in my target.
>
> Moreover, the previous code would not deallocate the struct if
> dirp->dd_fd is -1.
>
> Attached is a simple patch to fix the issue.
Thanks! I think you found something very suspicious here. The test for
fd != -1 is supposed to check... what?
Opendir fails if open on the directory fails, so a valid DIR* also has a
valid dd_fd value. The only time dd_fd can be -1 programatically is
when closedir has been called and in this case DIR* is invalid, too.
Or, if two threads call closedir for the same DIR* at about the same
time, one of them could find that dd_fd is -1 and skip the close/free
stuff. However, the code
fd = dirp->dd_fd;
if (fd != -1) {
dirp->dd_fd = -1;
is definitely not thread-safe, and closedir is not *supposed* to be
reentrant or thread-safe.
This test doesn't make sense. libc/sys/sparc64/closedir.c and
libc/sys/sysvi386/closedir.c both don't perform it either.
What I would suggest is to simplify the call to this code instead:
int
_DEFUN(closedir, (dirp),
register DIR *dirp)
{
int fd, rc;
#ifdef HAVE_DD_LOCK
__lock_acquire_recursive(dirp->dd_lock);
#endif
fd = dirp->dd_fd;
rc = close(fd);
_cleanupdir(dirp);
(void)free((void *)dirp->dd_buf);
#ifdef HAVE_DD_LOCK
__lock_release_recursive(dirp->dd_lock);
__lock_close_recursive(dirp->dd_lock);
#endif
(void)free((void *)dirp);
return rc;
}
Does that make sense? Did I miss something?
Thanks,
Corinna
--
Corinna Vinschen
Cygwin Maintainer
Red Hat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/newlib/attachments/20131113/a6117c70/attachment.sig>
More information about the Newlib
mailing list