summaryrefslogtreecommitdiff
path: root/libc/misc/dirent
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2019-06-21 12:09:36 +0200
committerWaldemar Brodkorb <wbx@openadk.org>2019-06-21 12:09:36 +0200
commit4f506bb95ad4bc55e6174cef98803802a35b050e (patch)
treeb6e7adaf2b8c6b2d7cdb3dba03d87062e7e39e27 /libc/misc/dirent
parentf93b43e4d1a02b72e8e7659f6be4cc28a0c6e194 (diff)
fix opendir, fpathconf and ttyname_r to use fstat64(), not fstat()
There is no opendir64(), thus even programs built for 64-bit off_t use opendir(). Before this change, internally opendir() uses fstat(), with the following breakage if some of struct stat fields are too narrow: $ strace ls -l execve("/busybox/ls", ["ls", "-l"], 0x7ffcdc43ede8 /* 16 vars */) = 0 ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0 getuid32() = 0 time([1551486393 /* 2019-03-02T00:26:33+0000 */]) = 1551486393 (2019-03-02T00:26:33+0000) ioctl(0, TIOCGWINSZ, {ws_row=38, ws_col=120, ws_xpixel=0, ws_ypixel=0}) = 0 ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0 brk(NULL) = 0x9768000 brk(0x9769000) = 0x9769000 lstat64(".", 0xffa6e374) = 0 open(".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3 fstat(3, 0xffa6e378) = -1 EOVERFLOW (Value too large for defined data type) See https://bugs.busybox.net/show_bug.cgi?id=11651 Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'libc/misc/dirent')
-rw-r--r--libc/misc/dirent/opendir.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/libc/misc/dirent/opendir.c b/libc/misc/dirent/opendir.c
index 8af00f88c..0ef8364f6 100644
--- a/libc/misc/dirent/opendir.c
+++ b/libc/misc/dirent/opendir.c
@@ -16,6 +16,9 @@
#include <dirent.h>
#include "dirstream.h"
+#define STAT stat64
+#define FSTAT fstat64
+
static DIR *fd_to_DIR(int fd, __blksize_t size)
{
DIR *ptr;
@@ -43,9 +46,9 @@ static DIR *fd_to_DIR(int fd, __blksize_t size)
DIR *fdopendir(int fd)
{
int flags;
- struct stat st;
+ struct STAT st;
- if (fstat(fd, &st))
+ if (FSTAT(fd, &st))
return NULL;
if (!S_ISDIR(st.st_mode)) {
__set_errno(ENOTDIR);
@@ -69,12 +72,12 @@ DIR *fdopendir(int fd)
DIR *opendir(const char *name)
{
int fd;
- struct stat statbuf;
+ struct STAT statbuf;
DIR *ptr;
#ifndef O_DIRECTORY
/* O_DIRECTORY is linux specific and has been around since like 2.1.x */
- if (stat(name, &statbuf))
+ if (STAT(name, &statbuf))
return NULL;
if (!S_ISDIR(statbuf.st_mode)) {
__set_errno(ENOTDIR);
@@ -90,7 +93,7 @@ DIR *opendir(const char *name)
* defined and since Linux has supported it for like ever, i'm not going
* to worry about it right now (if ever). */
- if (fstat(fd, &statbuf) < 0) {
+ if (FSTAT(fd, &statbuf) < 0) {
/* this close() never fails
*int saved_errno;
*saved_errno = errno; */