1#!/bin/sh
2# Ensure we handle file systems returning no SELinux context,
3# which triggered a segmentation fault in coreutils-8.22.
4# This test is skipped on systems that lack LD_PRELOAD support; that's fine.
5# Similarly, on a system that lacks lgetfilecon altogether, skipping it is fine.
6
7# Copyright (C) 2014-2023 Free Software Foundation, Inc.
8
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18
19# You should have received a copy of the GNU General Public License
20# along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
22. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
23print_ver_ cp
24require_gcc_shared_
25require_selinux_
26
27# Replace each getfilecon and lgetfilecon call with a call to these stubs.
28cat > k.c <<'EOF' || framework_failure_
29#include <stdio.h>
30#include <selinux/selinux.h>
31#include <errno.h>
32
33int getfilecon (const char *path, char **con)
34{
35  /* Leave a marker so we can identify if the function was intercepted.  */
36  fclose(fopen("preloaded", "w"));
37
38  errno=ENODATA;
39  return -1;
40}
41
42int lgetfilecon (const char *path, char **con)
43{ return getfilecon (path, con); }
44EOF
45
46# Then compile/link it:
47gcc_shared_ k.c k.so \
48  || skip_ 'failed to build SELinux shared library'
49
50touch file_src
51
52# New file with SELinux context optionally included
53LD_PRELOAD=$LD_PRELOAD:./k.so cp -a file_src file_dst || fail=1
54
55# Existing file with SELinux context optionally included
56LD_PRELOAD=$LD_PRELOAD:./k.so cp -a file_src file_dst || fail=1
57
58# ENODATA should give an immediate error when required to preserve ctx
59# This is debatable, and maybe we should not fail when no context available?
60( export LD_PRELOAD=$LD_PRELOAD:./k.so
61  returns_ 1 cp --preserve=context file_src file_dst ) || fail=1
62
63test -e preloaded || skip_ 'LD_PRELOAD interception failed'
64
65Exit $fail
66