Making stdin/stdout non-blocking causes open_init_pty to hang if
they are closed, ala
./open_init_pty bash -c 'echo hello; exec >&- 2>&- <&-; sleep 1; '
and per
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=474956#10
This reverts commit fb081eb64b.
Reported-by: Laurent Bigonville <bigon@debian.org>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
As reported by Nicolas Iooss, there are still some inconsistencies
in the definitions and usage of Makefile variables related to bin
and sbin directories. Since we need to still support non-usrmerge
systems, we cannot completely synchronize them, but we can eliminate
unnecessary differences, remove unused variables, and drop the
USRSBINDIR variables.
Before:
$ find . -name Makefile -exec cat {} + |grep '^[A-Z_]*BINDIR' |sort -u
BINDIR=$(PREFIX)/bin
BINDIR ?= $(PREFIX)/bin
BINDIR ?= $(PREFIX)/sbin
SBINDIR ?= $(DESTDIR)/sbin
SBINDIR ?= $(PREFIX)/sbin
USRSBINDIR ?= $(PREFIX)/sbin
After:
$ find . -name Makefile -exec cat {} + | grep '^[A-Z_]*BINDIR' | sort -u
BINDIR ?= $(PREFIX)/bin
SBINDIR ?= $(DESTDIR)/sbin
SBINDIR ?= $(PREFIX)/sbin
This does not change the actual install location of any file.
It does drop the legacy symlink from /usr/sbin/load_policy to
/sbin/load_policy; packagers can create that separately if
desired.
Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
There were several places in the makefiles where LDLIBS or CFLAGS were
supposed to include options to build. They were missing the override
keyword so would be skipped if these vars were set on the make cmdline.
Add the override directive to fix this.
Signed-off-by: Jason Zaman <jason@perfinion.com>
Files in /tmp, /var/tmp, /var/run and /var/lib/debug labeled as
unlabeled_t or undefined_t are relabeled to match corresponding
directory label. Stop dereferencing link files in these folders
in order not to accidentally change label of other files in the
system.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1458831
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
when building packages (e.g. for openSUSE Linux)
(random) filesystem order of input files
influences ordering of functions in the output,
thus without the patch, builds (in disposable VMs) would usually differ.
See https://reproducible-builds.org/ for why this matters.
* `fixfiles -B relabel` or `fixfiles -C previouscontext relabel` would
skip the code that handles e.g. `/var/tmp`, which would be run by
`fixfiles relabel`. It would still remove all files in /tmp (subject to
user confirmation). This is confusing, undocumented, and unlikely to
be intentional.
* `fixfiles relabel path1 path2` is the same, except it would only relabel
the first path.
* `fixfiles -R ... relabel` was equivalent to `fixfiles -R ... restore`,
again contradicting the man page.
Also `fixfiles onboot` would ignore paths, -C, or -R.
fixfiles is mostly for users, where it should be acceptable to remove these
non-sensical combinations.
`fixfiles -C` is used in selinux-policy rpm install scripts. However I
believe the rpms used `fixfiles -C previouscontext restore`, and did not
either require user interaction or blow away /tmp without prompting. So
they should still work fine.
With these combinations removed, we can remove the `exit` calls which were
seen in some of the (non-error) code paths in `restore()`.
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
`fixfiles -R -a` is much less useful than it was made to sound, because -R
now works recursively. Therefore `fixfiles -R -a` relabels every file on
the system, multiple times. On my system it took over 5 times as long as
plain `fixfiles` (which takes about a minute).
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
This commit allows the use of `set -u` to detect reads of unset variables.
But what I really liked was making the code more explicit about these
modes. I hope that this is easier for a new reader to reason about.
`fixfiles restore` has accumulated five different modes it can run in.
Now use a single variable to indicate the mode, out-of-band of the
variables used for the individual modes.
Apparently `set -u` / `set -o nounset` doesn't work correctly with arrays.
If we ever need bash arrays, we can simply remove `set -u`. The `set -u`
dialect is a strict subset. See http://mywiki.wooledge.org/BashFAQ/112
Extra notes:
RESTORE_MODE was created because I couldn't bring myself to use an empty
FILEPATH, as a special case to indicate the default mode. Arguments
to the script (paths) could be empty already, so it would mean I had to
work out how we behaved in that case and decide whether it was reasonable.
It turns out the `-B | -N time` mode is distinct and does not respect
paths. So we can tell the user we're not going to do anything with the
paths they passed. Make sure this distinction is shown in the usage error
message.
We already rejected the combination of `-R rpmpackage,... dir/file...`.
Being aware of the different modes just causes more bogus combinations
to be rejected.
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
New users may try something like `fixfiles restore -v /dir/file` -
not realizing they are required to use `fixfiles -v restore /dir/file`.
Detect that `restorecon` aborts due to being run on the non-existent file
`-v`, and stop immediately. This will show the error much more clearly,
instead of continuing to restore `/dir/file` *without* verbose messages.
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
The idea is to print a usage error, then terminate with EXIT_FAILURE.
Don't print the usage error twice when run with no command.
Don't try to check for bogus extra arguments _after_
performing a long-running operation... particularly
if that operation terminates the script with EXIT_SUCCESS first.
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
$ shellcheck fixfiles
...
In fixfiles line 94:
[[ "${i}" =~ "^[[:blank:]]*#" ]] && continue
^-- SC2076: Don't quote rhs of =~, it'll match
literally rather than as a regex.
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
DIRS was suspicious because you can't store file names in a normal variable,
and it's not that common to use arrays in bash. It's not actually used.
While we're here, there's another variable which is never used
and should just be removed. (Pointed out by `shellcheck`.
It makes a couple of other points too, but I have more specific
patches I want to put those in).
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Make sure usage() in fixfiles shows all the current options.
It's printed when there's a user error, so it needs to be
helpful! (Excluding the deprecated option - see below).
manpage:
Remove the deprecated option `-l logfile`.
Add missing space in `restore|[-f] relabel`.
It's not clear why `-R rpmpackagename` was considered optional in the
second invocation. (If the user omits it, they are just performing the
first invocation). It desn't match usage() in fixfiles either.
Clean up bolding for `fixfiles onboot`.
Disable justification (troff "adjustment") in the synopsis. We want the
common options in the different invocations to line up consistently.
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
...and write log messages to standard output.
Some versions of fixfiles in 2004 created a logfile by default.
Apparently they also used `tee` to log to standard output at the same time.
We're also told that the logfile was implemented because there was too
much output generated for use on a tty, and it scrolled out of reach.
https://bugzilla.redhat.com/show_bug.cgi?id=131707
In the current version, none of these original reasons for `-l` remain.
The logfile is not created by default. If no log file is specified,
messages are written to stdin [sic]... if and only stdin is a tty. If
stdin is not a tty, the log defaults to /dev/null.
When a user runs fixfiles on a tty and finds there is too much output, she
is likely to try redirecting standard output and/or standard error using
the shell. She will find this doesn't help, because fixfiles is writing
the verbose log messages to standard input.
I tried to fix the problem non-intrusively, by changing the default log
file to `/dev/stdout`. Sadly, this breaks down where you have
`echo >>$LOGFILE "Log message"` inside a specific function, which is run
with output redirected in order to "return" a string value (captured
into a variable). exclude_dirs_from_relabelling() was such a function.
I was trying to abstract over writing to both normal files and stdout, but
my abstraction "leaks" in a non-obvious way.
There is a simple solution. We can write the log messages to standard
output. When we are passed `-l` by a legacy script, we can redirect
standard output to the logfile.
This removes any distinctions between the logfile and "non-log" messages.
Some calls to restorecon were missing redirections to the log file.
"Cleaning out /tmp" was written to the log file, but "Cleaning out labels
on /tmp" was not. There were no comments to explain these distinctions.
Move call to logit() outside a function which has its output redirected.
See next commit for explanation.
The logit calls are moved into a new function LogExcluded(), similar to
LogReadOnly(). I don't see a pretty way to resolve this, so I just went
for the most explicit approach I could think of.
Behaviour change: diff_filecontext will now log *all* excluded paths.
I think that approach is an improvement, because e.g. the fact that `-C`
mode excludes `/home` was not previouslly documented anywhere.
The LogReadOnly() call which warns the user about R/O filesystems, applies
to the `-B` mode (newer() function), and the `fixfiles check` mode
(no paths).
Make sure to print it for these modes, and these modes only.
The usage of exclude_dirs() is non-obvious.
It turns out it is only used by the `-C` mode of fixfiles. The other four
modes use the narrower list generated by exclude_dirs_from_relabelling().
Let's make this distinction more obvious.
(The purpose of the extra exclusions is not clear. E.g. there's an
exclusion for /dev. Whereas the `fixfiles check` mode explicitly tells you
that it's going to relabel /dev, without causing any problem. Maybe that
part is out of date? But without some explanation of the list, I don't
want to change anything!)
setfiles is now run with $exclude_dirs.
We shouldn't need to patch the file contexts as well.
This is fortunate, since the file context patching code was broken
(by the same commit which introduced the redundancy). It takes the
list of directories to exclude from $tempdirs, but $tempdirs is
never set.
Also messages about skipping directories were printed twice. Firstly when
exclude_dirs is generated, and secondly in the file context patching code.
Also TEMPFCFILE was only removed in one path out of several.
This reverts commit ac7899fc3a,
which is not yet part of an officially tagged release
(or release candidate).
`LOGFILE=/proc/self/fd/1` was wrong.
`LOGFILE=$(tty)` was being relied on in one case (exclude_dirs),
to log messages from a function run specifically with stdout redirected
(captured into a variable).
Having `logit "message"` break inside redirected functions
is a nasty leaky abstraction.
This caused e.g. `fixfiles restore` to terminate early with the error
skipping: No such file or directory
if the user had configured any excluded paths in
/etc/selinux/fixfiles_exclude_dirs
The toolchain automatically handles them and they break cross compiling.
LDFLAGS should also come before object files, some flags (eg,
-Wl,as-needed) can break things if they are in the wrong place)
Gentoo-Bug: https://bugs.gentoo.org/500674
Signed-off-by: Jason Zaman <jason@perfinion.com>
If the user has the $LINGUAS environment variable set, only translations
for those languages should be installed to the system.
The gettext manual [1] says:
"Internationalized packages have usually many ll.po files. Unless
translations are disabled, all those available are installed together
with the package. However, the environment variable LINGUAS may be set,
prior to configuration, to limit the installed set. LINGUAS should then
contain a space separated list of two-letter codes, stating which
languages are allowed."
[1]: https://www.gnu.org/software/gettext/manual/html_node/Installers.html#Installers
Signed-off-by: Jason Zaman <jason@perfinion.com>
In extract_pw_data(), if "getpwuid(uid)" fails, the function returns an
error value without initializing main's pw.pw_name. This leads main() to
call "free(pw.pw_name)" on an uninitialized value.
Use memset() to initialize structure pw in main().
This issue has been found using clang's static analyzer.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
In main(), if "extract_pw_data(&pw)" returns a failed value, it has
already freed pw.pw_name, pw.pw_dir and pw.pw_shell. These fields are
freed a second time in main's err_free label, which is incorrect. Work
around this by setting them to NULL after they are freed.
This issue has been found using clang's static analyzer.
While at it, make extract_pw_data() static.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
This check is a remnant of the libselinux <2.5 era, back when
is_selinux_enabled() checked whether a policy had been loaded. Nowadays
it only checks whether selinuxfs is mounted, and "load_policy -i"
therefore incorrectly refuses operation when selinuxfs is mounted, but
no policy has been loaded yet.
While it doesn't make much sense to call selinux_init_load_policy()
twice, there's no harm in doing so either, so let's just drop this
safeguard instead of fixing it.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Don't force output through a pipe - let them access the TTY.
When run interactively, this acts as a workaround for
"Output of fixfiles gets garbled?"
https://bugzilla.redhat.com/show_bug.cgi?id=1435894
E.g. it would also be useful if restorecon ever decides it doesn't want to
output backspace characters on non-TTY outputs.
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
I suggested that if you run a command for its informational output (by
passing `-v`), you don't expect it to be prefixed with the program name.
Prefixing is used for error messages, so you can tell where your shell
script blew up :). If a script is running a command for its informational
output, it's usually the script's responsibility to make sure it's in
context, e.g. providing headers if there are multiple sections of output.
Removing the program name from setfiles/restorecon output is particularly
useful because it generates very long lines. But also, it actually helps
highlight where there are error messages - the prefix will make them
stand out visually.
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
I accidently ran `fixfiles "a b"` during testing. Let's fix this too.
Before:
/sbin/fixfiles: line 394: [: a: binary operator expected
Usage: ...
After:
Usage: ...
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
E.g. `fixfiles restore -v /usr` - before:
Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
Progress and Verbose mutually exclusive
usage: /sbin/restorecon [-iFnprRv0] [-e excludedir] pathname...
usage: /sbin/restorecon [-iFnprRv0] [-e excludedir] -f filename
Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
229k
after:
Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
/sbin/restorecon: lstat(-v) failed: No such file or directory
Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
229k
This matches the usage shown in the manual page. While we're in there,
we should handle spaces as well e.g `fixfiles restore "a b"`. Before:
Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
/sbin/restorecon: lstat(b) failed: No such file or directory
After:
Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
/sbin/restorecon: lstat(a b) failed: No such file or directory
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Nicolass Iooss reports that when building with "clang -Wwrite-strings",
the compiler complains about initializing the char* array
genhomedirconargv with literal strings.
Make genhomedirconargv an array of pointers to const char and cast it
as non-const when assigning it to argv.
Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
This fixes the following bug:
UX regression: setfiles progress indicator is now misleading and
confusing in fixfiles.
The outputting of * is replaced by the number of files in 1k increments
as the previous versions. If "/" is specified on the pathname, then this
will indicate a mass relabel, an example output will be:
restorecon -nRp /etc /tmp /boot /
/etc 100.0%
/tmp 100.0%
/boot 100.0%
3.2%
Also setfiles(8) and restorecon(8) versions that are implemented using
the selinux_restorecon(3) function do not support the [-o filename]
option as this was deprecated. This has now been made clear by displaying
a message to stderr.
The documentation has also been updated to reflect these changes.
Reported-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
Define a logging callback for libselinux so that any informational
or error messages generated by libselinux functions are properly
prefixed with the program name and routed to the proper output stream.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
fixfiles was redirecting log output to `tty`. This overrides user intent
e.g. when shell redirection is used.
Redirect it to stdout, using /proc. `tty` equally depended on /proc.
We do not depend on /dev/stdout: it might not be present, if a rescue
system is booted with devtmpfs (no udev daemon).
By default, log messages were redirected into the void when not run from a
tty. We consider this a bug, which is now fixed.
1. If calling scripts happen to require the old behaviour, they can easily
write the same code themselves.
2. When fixfiles is run from Fedora's selinux-autorelabel.service,
the calling script is specifically run from a tty.
Also Fedora's calling script chooses to redirect stdout and stderr to
/dev/null. This redirection will now suceed, improving the transparency
of the code. The previous behaviour may be obtained by choosing not
to redirect the progress messages of this long-running process to
/dev/null. A patch has been submitted to Fedora to suggest this novel
approach: https://bugzilla.redhat.com/show_bug.cgi?id=1415674
Complete disclosure:
* Remove unused variable LOGGER.
* Fix logfiles containing spaces.
Disclaimer:
1. "Log" output may contain escape sequences (backspace?) e.g. in
`fixfiles -l log.txt restore`. This is not the usual understanding
of a log file.
2. For some reason, not all informative messages are sent to `-l` e.g.
the list of filesystems, and "cleaning up labels on /tmp".
3. `function logit` is retained, but the logfile is also written to
outside this function. Implementing support for the system log
would require another function which accepts piped input.
Also see point 1.
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Policy module structure created by libsepol out of base module
contains NULL in module name, which results in segfault in "pp"
compiler. Add NULL check.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1350806
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Even though "hashtab_key_t" is an alias for "char *", "const
hashtab_key_t" is not an alias for "(const char) *" but means "(char *)
const".
Introduce const_hashtab_key_t to map "(const char) *" and use it in
hashtab_search() and hashtab key comparison functions.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>