Re: [PATCH v2 2/2] libselinux: support multiple context files for the file backend
Stephen Smalley <[email protected]> Thu, 23 Jul 2026 10:03:38 -0400
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <CAEjxPJ6_ZBTP=wVnF3=cW1NNQAAsnDLFG7FiA0rv0r_-nLCZUA@mail.gmail.com> |
On Wed, Jul 22, 2026 at 11:11 PM Thiébaud Weksteen <[email protected]> wrote: > > Update the file labeling backend to support specifying multiple > SELABEL_OPT_PATH options in selabel_open(). > > All provided paths are stored in rec->spec_files and processed during > initialization. Derived files, such as substitutions (.subs, .subs_dist) > and auxiliary contexts (.homedirs, .local), continue to be based on the > first path (or default selinux_file_context_path()) when enabled. > > Duplicate checking is only performed within each context file. The current > behavior expects the ability for a later file to overwrite a previous > declaration (e.g., .local). > > Signed-off-by: Thiébaud Weksteen <[email protected]> > --- > Changes since v1: > - Restore nodups_spec_node, ignore duplicates across files. > - Change num_paths type to uint8_t and check for overflow. > - Check for NULL before strdup any path. > - Use num_paths and num_paths+1 for homedirs and local. > > libselinux/src/label_file.c | 139 ++++++++++++++++++++++++------------ > 1 file changed, 92 insertions(+), 47 deletions(-) > > diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c > index d91e1462..02bd6f5d 100644 > --- a/libselinux/src/label_file.c > +++ b/libselinux/src/label_file.c > @@ -126,13 +127,16 @@ static int nodups_spec_node(const struct spec_node *node, const char *path) > node1->file_kind != node2->file_kind) > continue; > > + if (node1->inputno != node2->inputno) > + continue; > + > rc = -1; > errno = EINVAL; > if (strcmp(node1->lr.ctx_raw, node2->lr.ctx_raw) != 0) { > COMPAT_LOG( > SELINUX_ERROR, > "%s: Multiple different specifications for %s %s (%s and %s).\n", > - path, > + rec->spec_files[node1->inputno], Here and below if we hit this error within .local or .homedirs we will have an OOB read on rec->spec_files. > @@ -1511,10 +1526,50 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, > } > } > > + /* If no paths were provided, we will use the default path or fail, > + * depending on the target. */ > + if (!path_provided) { > +#if !defined(BUILD_HOST) && !defined(ANDROID) > + num_paths = 1; > +#else > + selinux_log(SELINUX_ERROR, > + "No path given to file labeling backend\n"); > + errno = EINVAL; > + return -1; > +#endif > + } > + > + /* If !baseonly, we reserve the last 2 indexes for homedirs and local. > + * Let's make sure we don't wrap */ > + if (!baseonly && num_paths > UINT8_MAX - 1) { This is never true since you capped num_paths at 254 above (return on UINT8_MAX).