diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2016-11-09 19:09:53 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2016-11-09 19:09:53 +0000 |
commit | 6e60b5f6a7a7ffa769224f56459797265dec6dc0 (patch) | |
tree | 6602abaf60db83bc2431b0edbf2f8d80d1bd06c6 /lib/libc/gen | |
parent | 3476aff871cc4fcfd5926ed556933800267acde9 (diff) |
Fix a use after free error introduced in rev 1.18 by only calling
closedir() outside the loop. OK deraadt@ guenther@ markus@
Diffstat (limited to 'lib/libc/gen')
-rw-r--r-- | lib/libc/gen/ttyname.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/lib/libc/gen/ttyname.c b/lib/libc/gen/ttyname.c index 5efbc0d220f..c6195de2d64 100644 --- a/lib/libc/gen/ttyname.c +++ b/lib/libc/gen/ttyname.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ttyname.c,v 1.18 2016/06/27 16:52:30 espie Exp $ */ +/* $OpenBSD: ttyname.c,v 1.19 2016/11/09 19:09:52 millert Exp $ */ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. @@ -115,6 +115,7 @@ oldttyname(struct stat *sb, char *buf, size_t len) struct dirent *dirp; DIR *dp; struct stat dsb; + int error = ENOTTY; if ((dp = opendir(_PATH_DEV)) == NULL) return (errno); @@ -125,13 +126,15 @@ oldttyname(struct stat *sb, char *buf, size_t len) if (fstatat(dirfd(dp), dirp->d_name, &dsb, AT_SYMLINK_NOFOLLOW) || !S_ISCHR(dsb.st_mode) || sb->st_rdev != dsb.st_rdev) continue; - (void)closedir(dp); - if (dirp->d_namlen > len - sizeof(_PATH_DEV)) - return (ERANGE); - memcpy(buf + sizeof(_PATH_DEV) - 1, dirp->d_name, - dirp->d_namlen + 1); - return (0); + if (dirp->d_namlen > len - sizeof(_PATH_DEV)) { + error = ERANGE; + } else { + memcpy(buf + sizeof(_PATH_DEV) - 1, dirp->d_name, + dirp->d_namlen + 1); + error = 0; + } + break; } (void)closedir(dp); - return (ENOTTY); + return (error); } |