Skip to content

Commit

Permalink
tests: check for relabeling rather than overlay
Browse files Browse the repository at this point in the history
Instead of checking for overlayfs, let's explicitly check for our
ability to relabel files since we now have a `libtest` function to do
this. Also port that logic to `libostreetest`.

Note that overlayfs *does* allow manipulating user xattrs. So ideally,
we should break down `OSTREE_NO_XATTRS` further to distinguish between
tests that use bare repos from other modes.

We check the current directory instead of `/` so that developers can
just point `TEST_TMPDIR` to a non-overlayfs mount point when hacking
from a container.

Closes: #1170
Approved by: cgwalters
  • Loading branch information
jlebon authored and rh-atomic-bot committed Sep 30, 2017
1 parent 8fe4536 commit a06bd82
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 49 deletions.
91 changes: 75 additions & 16 deletions tests/libostreetest.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,29 +72,88 @@ ot_test_setup_repo (GCancellable *cancellable,
return g_steal_pointer (&ret_repo);
}

/* Determine whether we're able to relabel files. Needed for bare tests. */
gboolean
ot_check_relabeling (gboolean *can_relabel,
GError **error)
{
g_auto(GLnxTmpfile) tmpf = { 0, };
if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_RDWR | O_CLOEXEC, &tmpf, error))
return FALSE;

g_autoptr(GError) local_error = NULL;
g_autoptr(GBytes) bytes = glnx_fgetxattr_bytes (tmpf.fd, "security.selinux", &local_error);
if (!bytes)
{
/* libglnx preserves errno */
if (G_IN_SET (errno, ENOTSUP, ENODATA))
{
*can_relabel = FALSE;
return TRUE;
}
g_propagate_error (error, g_steal_pointer (&local_error));
return FALSE;
}

gsize data_len;
const guint8 *data = g_bytes_get_data (bytes, &data_len);
if (fsetxattr (tmpf.fd, "security.selinux", data, data_len, 0) < 0)
{
if (errno == ENOTSUP)
{
*can_relabel = FALSE;
return TRUE;
}
return glnx_throw_errno_prefix (error, "fsetxattr");
}

*can_relabel = TRUE;
return TRUE;
}

/* Determine whether the filesystem supports getting/setting user xattrs. */
gboolean
ot_check_user_xattrs (gboolean *has_user_xattrs,
GError **error)
{
g_auto(GLnxTmpfile) tmpf = { 0, };
if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_RDWR | O_CLOEXEC, &tmpf, error))
return FALSE;

if (fsetxattr (tmpf.fd, "user.test", "novalue", strlen ("novalue"), 0) < 0)
{
if (errno == ENOTSUP)
{
*has_user_xattrs = FALSE;
return TRUE;
}
return glnx_throw_errno_prefix (error, "fsetxattr");
}

*has_user_xattrs = TRUE;
return TRUE;
}

OstreeSysroot *
ot_test_setup_sysroot (GCancellable *cancellable,
GError **error)
{
if (!ot_test_run_libtest ("setup_os_repository \"archive\" \"syslinux\"", error))
return FALSE;

struct statfs stbuf;
{ g_autoptr(GString) buf = g_string_new ("mutable-deployments");
if (statfs ("/", &stbuf) < 0)
return glnx_null_throw_errno (error);
/* Keep this in sync with the overlayfs bits in libtest.sh */
#ifndef OVERLAYFS_SUPER_MAGIC
#define OVERLAYFS_SUPER_MAGIC 0x794c7630
#endif
if (stbuf.f_type == OVERLAYFS_SUPER_MAGIC)
{
g_print ("libostreetest: detected overlayfs\n");
g_string_append (buf, ",no-xattrs");
}
/* Make sure deployments are mutable */
g_setenv ("OSTREE_SYSROOT_DEBUG", buf->str, TRUE);
}
g_autoptr(GString) buf = g_string_new ("mutable-deployments");

gboolean can_relabel;
if (!ot_check_relabeling (&can_relabel, error))
return FALSE;
if (!can_relabel)
{
g_print ("libostreetest: can't relabel, turning off xattrs\n");
g_string_append (buf, ",no-xattrs");
}

/* Make sure deployments are mutable */
g_setenv ("OSTREE_SYSROOT_DEBUG", buf->str, TRUE);

g_autoptr(GFile) sysroot_path = g_file_new_for_path ("sysroot");
return ostree_sysroot_new (sysroot_path);
Expand Down
6 changes: 6 additions & 0 deletions tests/libostreetest.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ gboolean ot_test_run_libtest (const char *cmd, GError **error);
OstreeRepo *ot_test_setup_repo (GCancellable *cancellable,
GError **error);

gboolean ot_check_relabeling (gboolean *can_relabel,
GError **error);

gboolean ot_check_user_xattrs (gboolean *has_user_xattrs,
GError **error);

OstreeSysroot *ot_test_setup_sysroot (GCancellable *cancellable,
GError **error);

Expand Down
78 changes: 49 additions & 29 deletions tests/libtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,50 @@ chmod -R u+w "${test_tmpdir}"
export TEST_GPG_KEYHOME=${test_tmpdir}/gpghome
export OSTREE_GPG_HOME=${test_tmpdir}/gpghome/trusted

# See comment in ot-builtin-commit.c and https://github.com/ostreedev/ostree/issues/758
# Also keep this in sync with the bits in libostreetest.c
echo evaluating for overlayfs...
case $(stat -f --printf '%T' /) in
overlayfs)
echo "overlayfs found; enabling OSTREE_NO_XATTRS"
export OSTREE_SYSROOT_DEBUG="${OSTREE_SYSROOT_DEBUG},no-xattrs"
export OSTREE_NO_XATTRS=1 ;;
*) ;;
esac
assert_has_setfattr() {
if ! which setfattr 2>/dev/null; then
fatal "no setfattr available to determine xattr support"
fi
}

_have_selinux_relabel=''
have_selinux_relabel() {
assert_has_setfattr
if test "${_have_selinux_relabel}" = ''; then
pushd ${test_tmpdir}
echo testlabel > testlabel.txt
selinux_xattr=security.selinux
if getfattr --encoding=base64 -n ${selinux_xattr} testlabel.txt >label.txt 2>err.txt; then
label=$(grep -E -e "^${selinux_xattr}=" < label.txt |sed -e "s,${selinux_xattr}=,,")
if setfattr -n ${selinux_xattr} -v ${label} testlabel.txt 2>err.txt; then
echo "SELinux enabled in $(pwd), and have privileges to relabel"
_have_selinux_relabel=yes
else
sed -e 's/^/# /' < err.txt >&2
echo "Found SELinux label, but unable to set (Unprivileged Docker?)"
_have_selinux_relabel=no
fi
else
sed -e 's/^/# /' < err.txt >&2
echo "Unable to retrieve SELinux label, assuming disabled"
_have_selinux_relabel=no
fi
popd
fi
test ${_have_selinux_relabel} = yes
}

# just globally turn off xattrs if we can't manipulate security xattrs; this is
# the case for overlayfs -- really, we should only enforce this for tests that
# use bare repos; separate from other tests that should check for user xattrs
# support
# see https://github.com/ostreedev/ostree/issues/758
# and https://github.com/ostreedev/ostree/pull/1217
echo -n checking for xattrs...
if ! have_selinux_relabel; then
export OSTREE_SYSROOT_DEBUG="${OSTREE_SYSROOT_DEBUG},no-xattrs"
export OSTREE_NO_XATTRS=1
fi
echo done

if test -n "${OT_TESTS_DEBUG:-}"; then
Expand Down Expand Up @@ -516,12 +550,9 @@ os_repository_new_commit ()
cd ${test_tmpdir}
}

# Usage: if ! skip_one_without_user_xattrs; then ... more tests ...; fi
_have_user_xattrs=''
have_user_xattrs() {
if ! which setfattr 2>/dev/null; then
fatal "no setfattr available to determine xattr support"
fi
assert_has_setfattr
if test "${_have_user_xattrs}" = ''; then
touch test-xattrs
if setfattr -n user.testvalue -v somevalue test-xattrs 2>/dev/null; then
Expand All @@ -533,6 +564,8 @@ have_user_xattrs() {
fi
test ${_have_user_xattrs} = yes
}

# Usage: if ! skip_one_without_user_xattrs; then ... more tests ...; fi
skip_one_without_user_xattrs () {
if ! have_user_xattrs; then
echo "ok # SKIP - this test requires xattr support"
Expand All @@ -554,21 +587,8 @@ skip_without_user_xattrs () {
# https://github.com/ostreedev/ostree/pull/759
# https://github.com/ostreedev/ostree/pull/1217
skip_without_no_selinux_or_relabel () {
cd ${test_tmpdir}
echo testlabel > testlabel.txt
selinux_xattr=security.selinux
if getfattr --encoding=base64 -n ${selinux_xattr} testlabel.txt >label.txt 2>err.txt; then
label=$(grep -E -e "^${selinux_xattr}=" < label.txt |sed -e "s,${selinux_xattr}=,,")
if setfattr -n ${selinux_xattr} -v ${label} testlabel.txt 2>err.txt; then
echo "SELinux enabled in $(pwd), and have privileges to relabel"
return 0
else
sed -e 's/^/# /' < err.txt >&2
skip "Found SELinux label, but unable to set (Unprivileged Docker?)"
fi
else
sed -e 's/^/# /' < err.txt >&2
skip "Unable to retrieve SELinux label, assuming disabled"
if ! have_selinux_relabel; then
skip "this test requires xattr support"
fi
}

Expand Down
14 changes: 10 additions & 4 deletions tests/test-basic-c.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,20 @@ test_devino_cache_xattrs (void)
g_assert_no_error (error);
g_assert (ret);

gboolean on_overlay;
ret = ot_check_for_overlay (&on_overlay, &error);
gboolean can_relabel;
ret = ot_check_relabeling (&can_relabel, &error);
g_assert_no_error (error);
g_assert (ret);

if (on_overlay)
gboolean has_user_xattrs;
ret = ot_check_user_xattrs (&has_user_xattrs, &error);
g_assert_no_error (error);
g_assert (ret);

/* we need both because we're bare and our tests target user xattrs */
if (!can_relabel || !has_user_xattrs)
{
g_test_skip ("overlayfs detected");
g_test_skip ("this test requires full xattr support");
return;
}

Expand Down

0 comments on commit a06bd82

Please sign in to comment.