Fixes the following warning from gcc 7:
In function ‘name_list_to_string’,
inlined from ‘constraint_expr_to_string’ at module_to_cil.c:1790:8:
module_to_cil.c:1135:6: warning: argument 1 range [18446744071562067968, 18446744073709551615] exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=]
str = malloc(len);
~~~~^~~~~~~~~~~~~
In file included from module_to_cil.c:36:0:
module_to_cil.c: In function ‘constraint_expr_to_string’:
/usr/include/stdlib.h:443:14: note: in a call to allocation function ‘malloc’ declared here
extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur;
^~~~~~
While we are here, fix a few other issues too.
The usage of snprintf was wrong and unnecessary; we just allocated
the string to be the right size, so we should just fill it.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Fixes the following warning from gcc7 by increasing the
buffer size to PATH_MAX.
semanage_store.c: In function ‘semanage_remove_directory’:
semanage_store.c:819:30: warning: ‘%s’ directive output may be truncated writing up to 255 bytes into a region of size 254 [-Wformat-truncation=]
snprintf(s, sizeof(s), "%s/%s", path, namelist[i]->d_name);
^~
semanage_store.c:819:3: note: ‘snprintf’ output 2 or more bytes (assuming 257) into a destination of size 255
snprintf(s, sizeof(s), "%s/%s", path, namelist[i]->d_name);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
https://developers.redhat.com/blog/2017/03/10/wimplicit-fallthrough-in-gcc-7/
Fixes the following warnings by annotating with a /* FALLTHRU */ comment.
Unfortunately, the __attribute__ ((fallthrough)); approach does not appear
to work with older compilers.
../cil/src/cil_parser.c: In function ‘cil_parser’:
../cil/src/cil_parser.c:253:14: warning: this statement may fall through [-Wimplicit-fallthrough=]
tok.value = tok.value+1;
~~~~~~~~~~^~~~~~~~~~~~~
../cil/src/cil_parser.c:254:3: note: here
case SYMBOL:
^~~~
../cil/src/cil_parser.c:275:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
if (tok.type != END_OF_FILE) {
^
../cil/src/cil_parser.c:279:3: note: here
case END_OF_FILE:
^~~~
../cil/src/cil_post.c: In function ‘cil_post_fc_fill_data’:
../cil/src/cil_post.c:104:5: warning: this statement may fall through [-Wimplicit-fallthrough=]
c++;
~^~
../cil/src/cil_post.c:105:3: note: here
default:
^~~~~~~
regex.c: In function ‘regex_format_error’:
regex.c:541:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
*ptr++ = '.';
~~~~~~~^~~~~
regex.c:542:2: note: here
case 3:
^~~~
regex.c:543:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
*ptr++ = '.';
~~~~~~~^~~~~
regex.c:544:2: note: here
case 2:
^~~~
regex.c:545:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
*ptr++ = '.';
~~~~~~~^~~~~
regex.c:546:2: note: here
case 1:
^~~~
regex.c: In function ‘regex_format_error’:
regex.c:541:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
*ptr++ = '.';
~~~~~~~^~~~~
regex.c:542:2: note: here
case 3:
^~~~
regex.c:543:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
*ptr++ = '.';
~~~~~~~^~~~~
regex.c:544:2: note: here
case 2:
^~~~
regex.c:545:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
*ptr++ = '.';
~~~~~~~^~~~~
regex.c:546:2: note: here
case 1:
^~~~
modules.c: In function ‘semanage_module_get_path’:
modules.c:602:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
if (file == NULL) file = "hll";
^
modules.c:603:3: note: here
case SEMANAGE_MODULE_PATH_CIL:
^~~~
modules.c:604:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
if (file == NULL) file = "cil";
^
modules.c:605:3: note: here
case SEMANAGE_MODULE_PATH_LANG_EXT:
^~~~
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Type aliases present a problem for module_to_cil because they are not
in the sym_val_to_name table that it uses to write declarations. Type
aliases are gathered by going through the decl_ids list and then
the alias declaration is written out when the block with that scope
id is handled. This doesn't work if a type alias appears in a require
block, since the require cannot be distinguished from the declaration.
The result is two declarations of the alias and an error when secilc
compiles the policy.
Because of the work cleaning up scope handling, the alias declaration
will always be at the end of the decl_ids list, so now only gather
the last scope id.
Also, when an alias is used in a module it is required as a type and
it will appear in the sym_val_to_name table. When that occurs, just
skip the alias when writing out types.
Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Currently, when checking if an identifier is enabled, each scope in
the decl_ids list is checked. This means that if any block that
requires the identifier is enabled, then the identifier will be treated
as being declared.
Now, declarations will be kept at the end of the decl_ids list and
when checking if an identifier is enabled, only the last scope will
be checked (Except for roles and users which allow multiple declarations,
they will have to keep the old behavior.)
Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Assigning NULL to handle does not perform anything useful and clang
complains about this:
ibendports.c:122:2: error: 'handle' was marked unused but was used
[-Werror,-Wused-but-marked-unused]
handle = NULL;
^
ibpkeys.c:115:2: error: 'handle' was marked unused but was used
[-Werror,-Wused-but-marked-unused]
handle = NULL;
^
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
- If two typealiasactual statements exist for the same typealias, we get
a confusing error message mentioning that the actual arguement is not
an alias, which is clearly allowed. This poor error occurs because the
first typealiasactual statement resolves correctly, but when we
resolve the alias in the second typealiasactual statement,
cil_resolve_name tries to return what the alias points to, which is a
type and not the required typealias. This patch creates a new function
that does not perform the alias to actual conversion, used when we
want an alias and not what the alias points to. This allows the
cil_resolve_aliasactual to continue and reach the check for duplicate
typealiasactual statements, resulting in a more meaningful error
message.
- Add back support for aliases to aliases (broken in 5c9fcb02e),
while still ensuring that aliases point to either the correct actual
flavor or alias flavor, and not something else like a typeattribute.
Signed-off-by: Steve Lawrence <slawrence@tresys.com>
- Set rc to SEPOL_ERR if the alias part of an aliasactual statement
does not resolve to the correct alias flavor (e.g. typealias, senalias, catalias)
- Add an error check if the actual part of an aliasactual statement
does not resolve to the correct actual flavor (type, sens, cat)
Signed-off-by: Steve Lawrence <slawrence@tresys.com>
Commits a3d2c7a 6a7a5aa introduced inconsistent use of tabs and spaces
in indentation what makes python3.6 unhappy.
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
When a function called by sepol_module_policydb_to_cil() fails before
role_list_create() has been called, role_list is still NULL but is
dereferenced in role_list_destroy(). Here is a gdb session on hll/pp:
Unknown value for handle-unknown: 6
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a68a37 in role_list_destroy () at module_to_cil.c:215
215 struct list_node *curr = role_list->head;
(gdb) bt
#0 0x00007ffff7a68a37 in role_list_destroy () at
module_to_cil.c:215
#1 sepol_module_policydb_to_cil (fp=fp@entry=0x7ffff79925e0
<_IO_2_1_stdout_>, pdb=<optimized out>, linked=linked@entry=0) at
module_to_cil.c:4060
#2 0x00007ffff7a6ac75 in sepol_module_package_to_cil
(fp=fp@entry=0x7ffff79925e0 <_IO_2_1_stdout_>, mod_pkg=0x604280) at
module_to_cil.c:4080
#3 0x0000000000401a58 in main (argc=<optimized out>,
argv=<optimized out>) at pp.c:150
This issue has been found while fuzzing hll/pp with the American Fuzzy
Lop.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Update libsepol and libsemanage to work with ibendport records. Add local
storage for new and modified ibendport records in ibendports.local.
Update semanage to parse the ibendport command options to add, modify,
and delete them.
Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Update libsepol and libsemanage to work with pkey records. Add local
storage for new and modified pkey records in pkeys.local. Update semanage
to parse the pkey command options to add, modify, and delete pkeys.
Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Add support for reading, writing, and copying IB end port ocontext data.
Also add support for querying a IB end port sid to checkpolicy.
Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Add checkpolicy support for scanning and parsing ibendportcon labels.
Also create a new ocontext for IB end ports.
Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Add support for reading, writing, and copying Infiniband Pkey ocontext
data. Also add support for querying a Pkey sid to checkpolicy.
Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Add checkpolicy support for scanning and parsing ibpkeycon labels. Also
create a new ocontext for Infiniband Pkeys and define a new policydb
version for infiniband support.
Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
When allocating an array with calloc(), the first argument usually is
the number of items and the second one the size of an item. Doing so
silences a warning reported by clang's static analyzer:
kernel_to_cil.c:2050:14: warning: Call to 'calloc' has an allocation
size of 0 bytes.
cond_data = calloc(sizeof(struct cond_data), num);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
When common_to_cil() or class_to_cil() fail to allocate an array to map
a permissions hashtable (for example when permissions.nprim is too big),
class_perm_to_array() gets called on a NULL pointer. Fix this.
This issue has been found while fuzzing hll/pp with the American Fuzzy
Lop.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Since commit 58962eb3d8 ("libsepol,checkpolicy: add binary module
support for xperms") function avrule_read() has been using its "p"
argument even though it was previously marked unused. This makes clang
report:
policydb.c:3276:7: error: 'p' was marked unused but was used
[-Werror,-Wused-but-marked-unused].
if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) {
^
Remove the attribute to make the code consistent again.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Memory allocation failures in selabel_subs_init() should be fatal,
contrary to failures which come from the non-existence of the
substitution files (subs or subs_dist).
Modify selabel_subs_init()'s prototype in order to return the error
state. This forces the pointer to the created substitution list to be
moved to an output function argument.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
In selabel_subs_init(), when digest_add_specfile() fails, the returned
value is a pointer to data which has been freed (because label "err"
frees variable "sub" which is equals to the returned variable, "list").
Moreover since since commit fd56c5230c ("Separate out the calling of
local subs and dist subs in selabel_sub"), argument "list" of
selabel_subs_init() has always been NULL (rec->subs and rec->dist_subs
are both initialized to NULL in selabel_open() before
selabel_file_init() is called).
Drop selabel_file_init()'s "list" argument and free all the list items
which have been allocated in this function, when the code encounters an
error.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Presently we support xperms rules in source policy and in CIL modules.
The binary policy module format however was never extended for xperms.
This limitation inhibits use of xperms in refpolicy-based policy modules
(including the selinux-testsuite policy). Update libsepol to support
linking, reading, and writing a new binary policy module version that
supports xperms rules. Update dismod to display xperms rules in binary
policy modules.
Also, to support use of a non-base binary policy module with a newer
version on a system using a base policy module with an older version,
automatically upgrade the version during module linking. This facilitates
usage of newer features in non-base modules without requiring rebuilding
the base module.
Tests:
1. Add an allowxperms rule to the selinux-testsuite policy and
confirm that it is properly written to the binary policy module
(displayed by dismod), converted to CIL (the latter was already supported),
and included in the kernel policy (via dispol and kernel test).
2. Use semodule_link and semodule_expand to manually link and expand
all of the .pp files via libsepol, and confirm that the allowxperms rule
is correctly propagated to the kernel policy. This test is required to
exercise the legacy link/expand code path for binary modules that predated
CIL.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
In __cil_fqn_qualify_blocks(), when newlen >= CIL_MAX_NAME_LENGTH,
cil_tree_log() is called with child_args.node as argument but this value
has not been initialized yet. Use local variable node instead, which is
initialized early enough in the function.
This issue has been found using clang's static analyzer.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
This check is not specific to Android devices. If libselinux were used
with Bionic on a normal Linux system this check would still be needed.
Signed-off-by: Tom Cherry <tomcherry@google.com>
s6_addr32 is not portable; use s6_addr instead.
This obviates the need for #ifdef __APPLE__ conditionals in these cases.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
* `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>
This commit adds attribute expansion statements to the policy
language allowing compiler defaults to be overridden.
Always expands an attribute example:
expandattribute { foo } true;
CIL example:
(expandtypeattribute (foo) true)
Never expand an attribute example:
expandattribute { bar } false;
CIL example:
(expandtypeattribute (bar) false)
Adding the annotations directly to policy was chosen over other
methods as it is consistent with how targeted runtime optimizations
are specified in other languages. For example, in C the "inline"
command.
Motivation
expandattribute true:
Android has been moving away from a monolithic policy binary to
a two part split policy representing the Android platform and the
underlying vendor-provided hardware interface. The goal is a stable
API allowing these two parts to be updated independently of each
other. Attributes provide an important mechanism for compatibility.
For example, when the vendor provides a HAL for the platform,
permissions needed by clients of the HAL can be granted to an
attribute. Clients need only be assigned the attribute and do not
need to be aware of the underlying types and permissions being
granted.
Inheriting permissions via attribute creates a convenient mechanism
for independence between vendor and platform policy, but results
in the creation of many attributes, and the potential for performance
issues when processes are clients of many HALs. [1] Annotating these
attributes for expansion at compile time allows us to retain the
compatibility benefits of using attributes without the performance
costs. [2]
expandattribute false:
Commit 0be23c3f15fd added the capability to aggresively remove unused
attributes. This is generally useful as too many attributes assigned
to a type results in lengthy policy look up times when there is a
cache miss. However, removing attributes can also result in loss of
information used in external tests. On Android, we're considering
stripping neverallow rules from on-device policy. This is consistent
with the kernel policy binary which also did not contain neverallows.
Removing neverallow rules results in a 5-10% decrease in on-device
policy build and load and a policy size decrease of ~250k. Neverallow
rules are still asserted at build time and during device
certification (CTS). If neverallow rules are absent when secilc is
run, some attributes are being stripped from policy and neverallow
tests in CTS may be violated. [3] This change retains the aggressive
attribute stripping behavior but adds an override mechanism to
preserve attributes marked as necessary.
[1] https://github.com/SELinuxProject/cil/issues/9
[2] Annotating all HAL client attributes for expansion resulted in
system_server's dropping from 19 attributes to 8. Because these
attributes were not widely applied to other types, the final
policy size change was negligible.
[3] data_file_type and service_manager_type are stripped from AOSP
policy when using secilc's -G option. This impacts 11 neverallow
tests in CTS.
Test: Build and boot Marlin with all hal_*_client attributes marked
for expansion. Verify (using seinfo and sesearch) that permissions
are correctly expanded from attributes to types.
Test: Mark types being stripped by secilc with "preserve" and verify
that they are retained in policy and applied to the same types.
Signed-off-by: Jeff Vander Stoep <jeffv@google.com>
commit 16c123f4b1f3c8d20b3f597df161d7e635620923 ("libselinux:
support ANDROID_HOST=1 on Mac") split up warning flags in
CFLAGS based on compiler support in a manner that could lead to
including a subset that is invalid, e.g. upon
make DESTDIR=/path/to/dest install. Fix it.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
fcb5d5c removed ../include from CFLAGS from libsepol/utils/Makefile so
that a build tool can't find sepol/sepol.h when only libsepol is built
and a system is without sepol.h in standard paths. It should use its own
sepol.h file during build. `oveeride` needs to be used in order not to
be overridden by values provided on a command line. Same problem applies
to LDFLAGS.
Fixes:
$ make CFLAGS="" LDFLAGS=""
make[1]: Entering directory '/root/selinux/libsepol/utils'
cc chkcon.c -lsepol -o chkcon
chkcon.c:1:25: fatal error: sepol/sepol.h: No such file or directory
#include <sepol/sepol.h>
$ make CFLAGS="" LDFLAGS=""
...
make -C utils
make[1]: Entering directory '/root/selinux/libsepol/utils'
cc -I../include chkcon.c -lsepol -o chkcon
/usr/bin/ld: cannot find -lsepol
collect2: error: ld returned 1 exit status
Signed-off-by: Petr Lautrbach <plautrba@redhat.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.