Re: [PATCH v4 2/2] man: Document directory cycle handling of selinux_restorecon
Stephen Smalley <[email protected]> Tue, 28 Jul 2026 10:50:55 -0400
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <CAEjxPJ529Be7_1Pw1LRFsUtABDa3yVo_-wD=mT0QxiuA0sKfsA@mail.gmail.com> |
On Tue, Jul 28, 2026 at 3:09 AM Johannes Segitz <[email protected]> wrote: > > Skipping directory cycles instead of aborting the file tree walk is a > user visible behavior change: restorecon -R over a tree containing e.g. > a bind mount of an ancestor directory now logs a warning, skips the > cycle and completes successfully, instead of failing with ELOOP. > > Document the new behavior for the flag SELINUX_RESTORECON_RECURSE, > including that a cycle is not an error and therefore is neither > affected by SELINUX_RESTORECON_ABORT_ON_ERROR nor counted by > SELINUX_RESTORECON_COUNT_ERRORS, and note the previous behavior in the > selinux_restorecon(3), restorecon(8) and setfiles(8) man pages. > > Signed-off-by: Johannes Segitz <[email protected]> Thank you for doing this! Acked-by: Stephen Smalley <[email protected]> > --- > libselinux/man/man3/selinux_restorecon.3 | 28 ++++++++++++++++++++++++ > policycoreutils/setfiles/restorecon.8 | 20 +++++++++++++++++ > policycoreutils/setfiles/setfiles.8 | 14 ++++++++++++ > 3 files changed, 62 insertions(+) > > diff --git a/libselinux/man/man3/selinux_restorecon.3 b/libselinux/man/man3/selinux_restorecon.3 > index 9bcd3d42..bafa86a2 100644 > --- a/libselinux/man/man3/selinux_restorecon.3 > +++ b/libselinux/man/man3/selinux_restorecon.3 > @@ -99,6 +99,21 @@ and if successful write an SHA1 digest of the specfile entries to an > extended attribute as described in the > .B NOTES > section. > +.RS > +Note that directory cycles encountered while descending, for example a bind > +mount of an ancestor directory or nested BTRFS subvolumes, are not followed. > +A warning is logged, the offending directory is not descended into and the > +file tree walk continues with the remaining entries. Such cycles are not > +treated as errors, therefore they neither abort the file tree walk when > +.B SELINUX_RESTORECON_ABORT_ON_ERROR > +is set, nor are they included in the count returned by > +.BR selinux_restorecon_get_skipped_errors (3) > +when > +.B SELINUX_RESTORECON_COUNT_ERRORS > +is set. See the > +.B NOTES > +section for details of the previous behavior. > +.RE > .sp > .B SELINUX_RESTORECON_VERBOSE > log file label changes. > @@ -302,6 +317,19 @@ with the > .B SELINUX_CB_LOG > .I type > option. > +.IP "6." 4 > +Up to and including libselinux 3.11 a directory cycle was fatal: > +.BR selinux_restorecon () > +logged an error, stopped the file tree walk and returned \-1 with > +.I errno > +set to > +.BR ELOOP , > +regardless of the > +.B SELINUX_RESTORECON_ABORT_ON_ERROR > +and > +.B SELINUX_RESTORECON_COUNT_ERRORS > +flags. Since then the cycle is skipped as described above, so a file tree > +walk over a directory tree containing a cycle can complete successfully. > . > .SH "SEE ALSO" > .BR selabel_get_digests_all_partial_matches (3), > diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8 > index 982701c2..443f29ab 100644 > --- a/policycoreutils/setfiles/restorecon.8 > +++ b/policycoreutils/setfiles/restorecon.8 > @@ -145,6 +145,9 @@ options are mutually exclusive. > .TP > .B \-R, \-r > change files and directories file labels recursively (descend directories). > +Directory cycles are skipped, see the > +.B NOTES > +section for details. > .br > .TP > .B \-v > @@ -240,6 +243,23 @@ and provided the > .B \-n > option is NOT set and recursive mode is set, files will be relabeled as > required with the digests then being updated provided there are no errors. > +.IP "4." 4 > +When descending directories (i.e. the > +.B \-R > +or > +.B \-r > +option is set) > +.B restorecon > +detects directory cycles, for example a bind mount of an ancestor directory or > +nested BTRFS subvolumes. A cycle is reported as a warning and the offending > +directory is not descended into, the remaining entries are still relabeled. > +A directory cycle is not counted as a relabeling error, so it does not affect > +the exit status and does not stop the file tree walk. Up to and including > +version 3.11 a directory cycle was instead treated as a fatal > +.B ELOOP > +error, terminating > +.B restorecon > +with a non-zero exit status. > > .SH EXAMPLE > .nf > diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8 > index d55b42db..17cabe37 100644 > --- a/policycoreutils/setfiles/setfiles.8 > +++ b/policycoreutils/setfiles/setfiles.8 > @@ -307,6 +307,20 @@ and provided the > .B \-n > option is NOT set, files will be relabeled as required with the digests then > being updated provided there are no errors. > +.IP "4." 4 > +.B setfiles > +detects directory cycles while descending directories, for example a bind > +mount of an ancestor directory or nested BTRFS subvolumes. A cycle is reported > +as a warning and the offending directory is not descended into, the remaining > +entries are still relabeled. A directory cycle is not counted as a relabeling > +error, so it does not affect the exit status and does not stop the file tree > +walk. Up to and including version 3.11 a directory cycle was instead treated > +as a fatal > +.B ELOOP > +error, terminating > +.B setfiles > +with exit status > +.BR 255 . > > .SH EXAMPLE > .nf > -- > 2.55.0 > >