[glib/wip/smcv/fileutils-test-as-root: 2/2] glib/tests/fileutils: Fix expectations when running as root
- From: Simon McVittie <smcv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/smcv/fileutils-test-as-root: 2/2] glib/tests/fileutils: Fix expectations when running as root
- Date: Wed, 28 Oct 2020 12:28:48 +0000 (UTC)
commit d9e7d227a1b03ccc1f4f6b30a0efacdeed3799b2
Author: Simon McVittie <smcv collabora com>
Date: Wed Oct 28 09:49:32 2020 +0000
glib/tests/fileutils: Fix expectations when running as root
This test asserts that g_file_set_contents_full() will fail when used
on a read-only file, but processes with CAP_DAC_OVERRIDE on Linux or
uid 0 on traditional Unix can and do ignore DAC permissions.
Historically, running build-time tests as uid 0 has been considered to
be a very bad idea, and running installed-tests as uid 0 unnecessarily
has also been discouraged; but with increasing availability of expendable
environments suitable for CI systems (virtual machines, containers, and
cheap bare-metal hardware like Raspberry Pi) it's increasingly common
that there is nothing that needs to be protected from mistakes, so
everything is run as uid 0 in the expendable environment.
Instead, probe the file with Standard C fopen() to see what happens, and
assert that g_file_set_contents_full() has the same behaviour
(whatever that happens to be).
Bug-Debian: https://bugs.debian.org/973271
Signed-off-by: Simon McVittie <smcv collabora com>
glib/tests/fileutils.c | 64 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 56 insertions(+), 8 deletions(-)
---
diff --git a/glib/tests/fileutils.c b/glib/tests/fileutils.c
index cfcf0e40d..717e7f80d 100644
--- a/glib/tests/fileutils.c
+++ b/glib/tests/fileutils.c
@@ -524,10 +524,10 @@ test_mkdir_with_parents (void)
g_assert_cmpint (errno, ==, EINVAL);
}
-#ifdef G_OS_UNIX
/*
* check_cap_dac_override:
- * @tmpdir: A temporary directory in which we can create and delete files
+ * @tmpdir: (nullable): A temporary directory in which we can create
+ * and delete files. If %NULL, use the g_get_tmp_dir(), safely.
*
* Check whether the current process can bypass DAC permissions.
*
@@ -550,10 +550,29 @@ test_mkdir_with_parents (void)
static gboolean
check_cap_dac_override (const char *tmpdir)
{
+#ifdef G_OS_UNIX
+ gchar *safe_tmpdir = NULL;
gchar *dac_denies_write;
gchar *inside;
gboolean have_cap;
+ if (tmpdir == NULL)
+ {
+ /* It's unsafe to write predictable filenames into g_get_tmp_dir(),
+ * because it's usually a shared directory that can be subject to
+ * symlink attacks, so use a subdirectory for this check. */
+ GError *error = NULL;
+
+ safe_tmpdir = g_dir_make_tmp (NULL, &error);
+ g_assert_no_error (error);
+ g_clear_error (&error);
+
+ if (safe_tmpdir == NULL)
+ return FALSE;
+
+ tmpdir = safe_tmpdir;
+ }
+
dac_denies_write = g_build_filename (tmpdir, "dac-denies-write", NULL);
inside = g_build_filename (dac_denies_write, "inside", NULL);
@@ -577,11 +596,18 @@ check_cap_dac_override (const char *tmpdir)
g_assert_no_errno (chmod (dac_denies_write, S_IRWXU));
g_assert_no_errno (rmdir (dac_denies_write));
+
+ if (safe_tmpdir != NULL)
+ g_assert_no_errno (rmdir (safe_tmpdir));
+
g_free (dac_denies_write);
g_free (inside);
+ g_free (safe_tmpdir);
return have_cap;
-}
+#else
+ return FALSE;
#endif
+}
/* Reproducer for https://gitlab.gnome.org/GNOME/glib/issues/1852 */
static void
@@ -1132,6 +1158,7 @@ test_set_contents_full_read_only_file (void)
GError *error = NULL;
gchar *file_name = NULL;
gboolean ret;
+ gboolean can_override_dac = check_cap_dac_override (NULL);
g_test_summary ("Test g_file_set_contents_full() on a read-only file");
@@ -1147,8 +1174,18 @@ test_set_contents_full_read_only_file (void)
/* Set the file contents */
ret = g_file_set_contents_full (file_name, "b", 1, G_FILE_SET_CONTENTS_NONE, 0644, &error);
- g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES);
- g_assert_false (ret);
+
+ if (can_override_dac)
+ {
+ g_assert_no_error (error);
+ g_assert_true (ret);
+ }
+ else
+ {
+ g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES);
+ g_assert_false (ret);
+ }
+
g_clear_error (&error);
g_remove (file_name);
@@ -1174,11 +1211,13 @@ test_set_contents_full_read_only_directory (void)
gchar *dir_name = NULL;
gchar *file_name = NULL;
gboolean ret;
+ gboolean can_override_dac;
g_test_message ("Flags %d", flags);
dir_name = g_dir_make_tmp ("glib-file-set-contents-full-rodir-XXXXXX", &error);
g_assert_no_error (error);
+ can_override_dac = check_cap_dac_override (dir_name);
file_name = g_build_filename (dir_name, "file", NULL);
fd = g_open (file_name, O_CREAT | O_RDWR, 0644);
@@ -1191,10 +1230,19 @@ test_set_contents_full_read_only_directory (void)
/* Set the file contents */
ret = g_file_set_contents_full (file_name, "b", 1, flags, 0644, &error);
- g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES);
- g_assert_false (ret);
- g_clear_error (&error);
+ if (can_override_dac)
+ {
+ g_assert_no_error (error);
+ g_assert_true (ret);
+ }
+ else
+ {
+ g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES);
+ g_assert_false (ret);
+ }
+
+ g_clear_error (&error);
g_remove (file_name);
g_unlink (dir_name);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]