forked from rpms/glibc
0bc968985e
This is an automated DistroBaker update from upstream sources. If you do not know what this is about or would like to opt out, contact the OSCI team. Source: https://src.fedoraproject.org/rpms/glibc.git#df07cd507e60fb1effac0d28d1bb0137235725ee
242 lines
6.7 KiB
Diff
242 lines
6.7 KiB
Diff
commit 32b9280f1d9f78e8fa3874e22f4d9a76460ee02a
|
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
|
Date: Thu Mar 11 08:21:06 2021 -0300
|
|
|
|
io: Return EBAFD for negative file descriptor on fstat (BZ #27559)
|
|
|
|
Now that fstat is implemented on top fstatat we need to handle negative
|
|
inputs. The implementation now rejects AT_FDCWD, which would otherwise
|
|
be accepted by the kernel.
|
|
|
|
Checked on x86_64-linux-gnu and on i686-linux-gnu.
|
|
|
|
(cherry picked from commit 94caafa040e4b4289c968cd70d53041b1463ac4d)
|
|
|
|
diff --git a/io/Makefile b/io/Makefile
|
|
index b7bebe923f84e878..d145d88f4e3faabf 100644
|
|
--- a/io/Makefile
|
|
+++ b/io/Makefile
|
|
@@ -68,7 +68,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
|
|
tst-fts tst-fts-lfs tst-open-tmpfile \
|
|
tst-copy_file_range tst-getcwd-abspath tst-lockf \
|
|
tst-ftw-lnk tst-file_change_detection tst-lchmod \
|
|
- tst-ftw-bz26353
|
|
+ tst-ftw-bz26353 tst-stat tst-stat-lfs
|
|
|
|
# Likewise for statx, but we do not need static linking here.
|
|
tests-internal += tst-statx
|
|
diff --git a/io/fstat.c b/io/fstat.c
|
|
index dc117361ffe7064b..17f31bf3b3a65a12 100644
|
|
--- a/io/fstat.c
|
|
+++ b/io/fstat.c
|
|
@@ -16,10 +16,16 @@
|
|
<https://www.gnu.org/licenses/>. */
|
|
|
|
#include <sys/stat.h>
|
|
+#include <errno.h>
|
|
|
|
int
|
|
__fstat (int fd, struct stat *buf)
|
|
{
|
|
+ if (fd < 0)
|
|
+ {
|
|
+ __set_errno (EBADF);
|
|
+ return -1;
|
|
+ }
|
|
return __fstatat (fd, "", buf, AT_EMPTY_PATH);
|
|
}
|
|
|
|
diff --git a/io/fstat64.c b/io/fstat64.c
|
|
index addf3797754f16b3..618170695cd56eec 100644
|
|
--- a/io/fstat64.c
|
|
+++ b/io/fstat64.c
|
|
@@ -16,10 +16,16 @@
|
|
<https://www.gnu.org/licenses/>. */
|
|
|
|
#include <sys/stat.h>
|
|
+#include <errno.h>
|
|
|
|
int
|
|
__fstat64 (int fd, struct stat64 *buf)
|
|
{
|
|
+ if (fd < 0)
|
|
+ {
|
|
+ __set_errno (EBADF);
|
|
+ return -1;
|
|
+ }
|
|
return __fstatat64 (fd, "", buf, AT_EMPTY_PATH);
|
|
}
|
|
hidden_def (__fstat64)
|
|
diff --git a/io/tst-stat-lfs.c b/io/tst-stat-lfs.c
|
|
new file mode 100644
|
|
index 0000000000000000..b53f460ad589c383
|
|
--- /dev/null
|
|
+++ b/io/tst-stat-lfs.c
|
|
@@ -0,0 +1,2 @@
|
|
+#define _FILE_OFFSET_BITS 64
|
|
+#include "tst-stat.c"
|
|
diff --git a/io/tst-stat.c b/io/tst-stat.c
|
|
new file mode 100644
|
|
index 0000000000000000..445ac4176c1d0f94
|
|
--- /dev/null
|
|
+++ b/io/tst-stat.c
|
|
@@ -0,0 +1,102 @@
|
|
+/* Basic tests for stat, lstat, fstat, and fstatat.
|
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <array_length.h>
|
|
+#include <errno.h>
|
|
+#include <fcntl.h>
|
|
+#include <support/check.h>
|
|
+#include <support/support.h>
|
|
+#include <support/temp_file.h>
|
|
+#include <support/xunistd.h>
|
|
+#include <sys/stat.h>
|
|
+#include <sys/sysmacros.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+static void
|
|
+stat_check (int fd, const char *path, struct stat *st)
|
|
+{
|
|
+ TEST_COMPARE (stat (path, st), 0);
|
|
+}
|
|
+
|
|
+static void
|
|
+lstat_check (int fd, const char *path, struct stat *st)
|
|
+{
|
|
+ TEST_COMPARE (lstat (path, st), 0);
|
|
+}
|
|
+
|
|
+static void
|
|
+fstat_check (int fd, const char *path, struct stat *st)
|
|
+{
|
|
+ /* Test for invalid fstat input (BZ #27559). */
|
|
+ TEST_COMPARE (fstat (AT_FDCWD, st), -1);
|
|
+ TEST_COMPARE (errno, EBADF);
|
|
+
|
|
+ TEST_COMPARE (fstat (fd, st), 0);
|
|
+}
|
|
+
|
|
+static void
|
|
+fstatat_check (int fd, const char *path, struct stat *st)
|
|
+{
|
|
+ TEST_COMPARE (fstatat (fd, "", st, 0), -1);
|
|
+ TEST_COMPARE (errno, ENOENT);
|
|
+
|
|
+ TEST_COMPARE (fstatat (fd, path, st, 0), 0);
|
|
+}
|
|
+
|
|
+typedef void (*test_t)(int, const char *path, struct stat *);
|
|
+
|
|
+static int
|
|
+do_test (void)
|
|
+{
|
|
+ char *path;
|
|
+ int fd = create_temp_file ("tst-fstat.", &path);
|
|
+ TEST_VERIFY_EXIT (fd >= 0);
|
|
+ support_write_file_string (path, "abc");
|
|
+
|
|
+ struct statx stx;
|
|
+ TEST_COMPARE (statx (fd, path, 0, STATX_BASIC_STATS, &stx), 0);
|
|
+
|
|
+ test_t tests[] = { stat_check, lstat_check, fstat_check, fstatat_check };
|
|
+
|
|
+ for (int i = 0; i < array_length (tests); i++)
|
|
+ {
|
|
+ struct stat st;
|
|
+ tests[i](fd, path, &st);
|
|
+
|
|
+ TEST_COMPARE (stx.stx_dev_major, major (st.st_dev));
|
|
+ TEST_COMPARE (stx.stx_dev_minor, minor (st.st_dev));
|
|
+ TEST_COMPARE (stx.stx_ino, st.st_ino);
|
|
+ TEST_COMPARE (stx.stx_mode, st.st_mode);
|
|
+ TEST_COMPARE (stx.stx_nlink, st.st_nlink);
|
|
+ TEST_COMPARE (stx.stx_uid, st.st_uid);
|
|
+ TEST_COMPARE (stx.stx_gid, st.st_gid);
|
|
+ TEST_COMPARE (stx.stx_rdev_major, major (st.st_rdev));
|
|
+ TEST_COMPARE (stx.stx_rdev_minor, minor (st.st_rdev));
|
|
+ TEST_COMPARE (stx.stx_blksize, st.st_blksize);
|
|
+ TEST_COMPARE (stx.stx_blocks, st.st_blocks);
|
|
+
|
|
+ TEST_COMPARE (stx.stx_ctime.tv_sec, st.st_ctim.tv_sec);
|
|
+ TEST_COMPARE (stx.stx_ctime.tv_nsec, st.st_ctim.tv_nsec);
|
|
+ TEST_COMPARE (stx.stx_mtime.tv_sec, st.st_mtim.tv_sec);
|
|
+ TEST_COMPARE (stx.stx_mtime.tv_nsec, st.st_mtim.tv_nsec);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#include <support/test-driver.c>
|
|
diff --git a/sysdeps/unix/sysv/linux/fstat.c b/sysdeps/unix/sysv/linux/fstat.c
|
|
index fd643622054fea26..31a172dcc81163e7 100644
|
|
--- a/sysdeps/unix/sysv/linux/fstat.c
|
|
+++ b/sysdeps/unix/sysv/linux/fstat.c
|
|
@@ -19,11 +19,17 @@
|
|
#include <sys/stat.h>
|
|
#include <kernel_stat.h>
|
|
#include <fcntl.h>
|
|
+#include <errno.h>
|
|
|
|
#if !XSTAT_IS_XSTAT64
|
|
int
|
|
__fstat (int fd, struct stat *buf)
|
|
{
|
|
+ if (fd < 0)
|
|
+ {
|
|
+ __set_errno (EBADF);
|
|
+ return -1;
|
|
+ }
|
|
return __fstatat (fd, "", buf, AT_EMPTY_PATH);
|
|
}
|
|
|
|
diff --git a/sysdeps/unix/sysv/linux/fstat64.c b/sysdeps/unix/sysv/linux/fstat64.c
|
|
index 993abcb4458fa309..46de80b663b9c1c4 100644
|
|
--- a/sysdeps/unix/sysv/linux/fstat64.c
|
|
+++ b/sysdeps/unix/sysv/linux/fstat64.c
|
|
@@ -22,10 +22,16 @@
|
|
#include <fcntl.h>
|
|
#include <kernel_stat.h>
|
|
#include <stat_t64_cp.h>
|
|
+#include <errno.h>
|
|
|
|
int
|
|
__fstat64_time64 (int fd, struct __stat64_t64 *buf)
|
|
{
|
|
+ if (fd < 0)
|
|
+ {
|
|
+ __set_errno (EBADF);
|
|
+ return -1;
|
|
+ }
|
|
return __fstatat64_time64 (fd, "", buf, AT_EMPTY_PATH);
|
|
}
|
|
#if __TIMESIZE != 64
|
|
@@ -34,6 +40,12 @@ hidden_def (__fstat64_time64)
|
|
int
|
|
__fstat64 (int fd, struct stat64 *buf)
|
|
{
|
|
+ if (fd < 0)
|
|
+ {
|
|
+ __set_errno (EBADF);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
struct __stat64_t64 st_t64;
|
|
return __fstat64_time64 (fd, &st_t64)
|
|
?: __cp_stat64_t64_stat64 (&st_t64, buf);
|