Re: linux-next 20180327 - "SELinux: (dev dm-3, type ext4) getxattr errno 34"

2018-03-29 Thread valdis . kletnieks
On Thu, 29 Mar 2018 21:32:21 -0400, "Theodore Y. Ts'o" said:

> Yes, the breakage is my fault; my apologies.  The new version of the
> patch is already posted in bugzilla (and on linux-ext4).  I'll be
> pushing out a refreshed ext4.git branch shortly.

Confirming that reverting de57a63ea4389e39b1cdd1cef15e1ec9b58a964c
and applying the new version from the bugzilla results in a clean boot.



pgpce16BeQ_5Z.pgp
Description: PGP signature


Re: [PATCH 1/1] libsepol/cil: Improve processing of context rules

2018-03-29 Thread Tri Vo
In Android we have a problem when .cil files from different partitions with
duplicate genfscon statements are built together. I've checked that this commit
fixes the problem.

Thank you!

On Thu, Mar 29, 2018 at 1:14 PM, jwcart2  wrote:
> Pierre-Hugues Husson, I've tested and everything seems to work as I expect
> it, but does this meet your needs?
>
> Jim
>
>
> On 03/29/2018 04:06 PM, James Carter wrote:
>>
>> Improve the processing of netifcon, genfscon, ibpkeycon, ibendportcon,
>> portcon, nodecon, fsuse, filecon, iomemcon, ioportcon, pcidevicecon,
>> and devicetreecon rules.
>>
>> If the multiple-decls option is not used then report errors if duplicate
>> context rules are found. If it is used then remove duplicate context rules
>> and report errors when two rules are identical except for the context.
>>
>> This also changes the ordering of portcon and filecon rules. The protocol
>> of portcon rules will be compared if the port numbers are the same and the
>> path strings of filecon rules will be compared if the number of meta
>> characters, the stem length, string length and file types are the same.
>>
>> Based on an initial patch by Pierre-Hugues Husson (p...@phh.me)
>>
>> Signed-off-by: James Carter 
>> ---
>>   libsepol/cil/src/cil_post.c | 331
>> ++--
>>   1 file changed, 318 insertions(+), 13 deletions(-)
>>
>> diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
>> index a2122454..0b09cecc 100644
>> --- a/libsepol/cil/src/cil_post.c
>> +++ b/libsepol/cil/src/cil_post.c
>> @@ -53,6 +53,83 @@
>>   static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out,
>> int max, struct cil_db *db);
>>   static int __cil_expr_list_to_bitmap(struct cil_list *expr_list,
>> ebitmap_t *out, int max, struct cil_db *db);
>>   +static int cats_compare(struct cil_cats *a, struct cil_cats *b)
>> +{
>> +   struct cil_list_item *i, *j;
>> +   int rc;
>> +
>> +   if (a == b) return 0;
>> +   if (!a) return -1;
>> +   if (!b) return 1;
>> +
>> +   /* Expects cat expression to have been evaluated */
>> +   cil_list_for_each(i, a->datum_expr) {
>> +   cil_list_for_each(j, b->datum_expr) {
>> +   rc = strcmp(DATUM(i->data)->fqn,
>> DATUM(j->data)->fqn);
>> +   if (!rc) return rc;
>> +   }
>> +   }
>> +   return 0;
>> +}
>> +
>> +static int level_compare(struct cil_level *a, struct cil_level *b)
>> +{
>> +   int rc;
>> +
>> +   if (a == b) return 0;
>> +   if (!a) return -1;
>> +   if (!b) return 1;
>> +
>> +   if (a->sens != b->sens) {
>> +   rc = strcmp(DATUM(a->sens)->fqn, DATUM(b->sens)->fqn);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->cats != b->cats) {
>> +   return cats_compare(a->cats, b->cats);
>> +   }
>> +   return 0;
>> +}
>> +
>> +static int range_compare(struct cil_levelrange *a, struct cil_levelrange
>> *b)
>> +{
>> +   int rc;
>> +
>> +   if (a == b) return 0;
>> +   if (!a) return -1;
>> +   if (!b) return 1;
>> +
>> +   if (a->low != b->low) {
>> +   rc = level_compare(a->low, b->low);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->high != b->high) {
>> +   return level_compare(a->high, b->high);
>> +   }
>> +   return 0;
>> +}
>> +
>> +static int context_compare(struct cil_context *a, struct cil_context *b)
>> +{
>> +   int rc;
>> +
>> +   if (a->user != b->user) {
>> +   rc = strcmp(DATUM(a->user)->fqn, DATUM(b->user)->fqn);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->role != b->role) {
>> +   rc = strcmp(DATUM(a->role)->fqn, DATUM(b->role)->fqn);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->type != b->type) {
>> +   rc = strcmp(DATUM(a->type)->fqn, DATUM(b->type)->fqn);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->range != b->range) {
>> +   return range_compare(a->range, b->range);
>> +   }
>> +   return 0;
>> +}
>> +
>>   static int cil_verify_is_list(struct cil_list *list, enum cil_flavor
>> flavor)
>>   {
>> struct cil_list_item *curr;
>> @@ -145,6 +222,8 @@ int cil_post_filecon_compare(const void *a, const void
>> *b)
>> rc = -1;
>> } else if (b_filecon->type < a_filecon->type) {
>> rc = 1;
>> +   } else {
>> +   rc = strcmp(a_filecon->path_str, b_filecon->path_str);
>> }
>> free(a_path);
>> @@ -190,6 +269,10 @@ int cil_post_portcon_compare(const void *a, const
>> void *b)
>> rc = -1;
>> } else if (bportcon->port_low < aportcon->port_low) {
>> rc = 1;
>> +   } else if (aportcon->proto < bportcon->proto) {
>> +   

[PATCH v3 0/2] restorecon context validation improvement

2018-03-29 Thread Yuli Khodorkovskiy
In permissive, if a bad label is written to a file_context file,
restorecon will not verify the label before succesfully applying the
context. These patches fix validation of labels during restorecon
while not breaking current behavior of lazy validation.

Changes since V1:
- Continue using lazy validation for restorecon that was broken in V1 of
the patch.
- Add line number tracking for error messages in restorecon.

Changes since V2:
- Fix compiler error caused by unused variable in selabel_validate()

Yuli Khodorkovskiy (2):
  libselinux: verify file_contexts when using restorecon
  libselinux: echo line number of bad label in selabel_fini()

 libselinux/src/label.c  | 7 +++
 libselinux/src/label_backends_android.c | 2 +-
 libselinux/src/label_file.c | 2 +-
 libselinux/src/label_file.h | 3 ++-
 libselinux/src/label_internal.h | 7 +++
 libselinux/src/matchpathcon.c   | 5 ++---
 6 files changed, 12 insertions(+), 14 deletions(-)

-- 
2.14.3




[PATCH v3 1/2] libselinux: verify file_contexts when using restorecon

2018-03-29 Thread Yuli Khodorkovskiy
In permissive mode, calling restorecon with a bad label in file_contexts
does not verify the label's existence in the loaded policy. This
results in any label successfully applying to a file, as long as the
file exists.

This issue has two assumptions:

1) file_contexts must be manually updated with the invalid label.
Running `semanage fcontext` will error when attempting to add
an invalid label to file_contexts.
2) the system must be in permissive. Although applying an invalid label
in enforcing gives an error and fails, successfully labeling a file with a
bad label could cause issues during policy development in permissive.

Instead, as each context is used, verify it is valid before blindly
applying the label. If an error with validation occurs in restorecon,
application of remaining valid labels will be uninterrupted as before.

Signed-off-by: Yuli Khodorkovskiy 
---
 libselinux/src/label.c  | 7 +++
 libselinux/src/label_backends_android.c | 2 +-
 libselinux/src/label_file.c | 2 +-
 libselinux/src/label_file.h | 2 +-
 libselinux/src/label_internal.h | 6 ++
 libselinux/src/matchpathcon.c   | 5 ++---
 6 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/libselinux/src/label.c b/libselinux/src/label.c
index 48f4d2d6..c510edc1 100644
--- a/libselinux/src/label.c
+++ b/libselinux/src/label.c
@@ -121,12 +121,11 @@ static inline int selabel_is_validate_set(const struct 
selinux_opt *opts,
return 0;
 }
 
-int selabel_validate(struct selabel_handle *rec,
-struct selabel_lookup_rec *contexts)
+int selabel_validate(struct selabel_lookup_rec *contexts)
 {
int rc = 0;
 
-   if (!rec->validating || contexts->validated)
+   if (contexts->validated)
goto out;
 
rc = selinux_validate(>ctx_raw);
@@ -143,7 +142,7 @@ static int selabel_fini(struct selabel_handle *rec,
struct selabel_lookup_rec *lr,
int translating)
 {
-   if (compat_validate(rec, lr, rec->spec_file, 0))
+   if (compat_validate(lr, rec->spec_file, 0))
return -1;
 
if (translating && !lr->ctx_trans &&
diff --git a/libselinux/src/label_backends_android.c 
b/libselinux/src/label_backends_android.c
index cb8aae26..49e39ec8 100644
--- a/libselinux/src/label_backends_android.c
+++ b/libselinux/src/label_backends_android.c
@@ -122,7 +122,7 @@ static int process_line(struct selabel_handle *rec,
spec_arr[nspec].lr.ctx_raw = context;
 
if (rec->validating) {
-   if (selabel_validate(rec, _arr[nspec].lr) < 0) {
+   if (selabel_validate(_arr[nspec].lr) < 0) {
selinux_log(SELINUX_ERROR,
"%s:  line %u has invalid context 
%s\n",
path, lineno, 
spec_arr[nspec].lr.ctx_raw);
diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
index 560d8c3d..169fed70 100644
--- a/libselinux/src/label_file.c
+++ b/libselinux/src/label_file.c
@@ -328,7 +328,7 @@ end_arch_check:
spec->lr.ctx_raw = str_buf;
 
if (strcmp(spec->lr.ctx_raw, "<>") && rec->validating) {
-   if (selabel_validate(rec, >lr) < 0) {
+   if (selabel_validate(>lr) < 0) {
selinux_log(SELINUX_ERROR,
"%s: context %s is invalid\n",
path, spec->lr.ctx_raw);
diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
index aa576d8e..9e52a3c4 100644
--- a/libselinux/src/label_file.h
+++ b/libselinux/src/label_file.h
@@ -506,7 +506,7 @@ static inline int process_line(struct selabel_handle *rec,
spec_hasMetaChars(_arr[nspec]);
 
if (strcmp(context, "<>") && rec->validating)
-   return compat_validate(rec, _arr[nspec].lr, path, lineno);
+   return compat_validate(_arr[nspec].lr, path, lineno);
 
return 0;
 }
diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h
index c55efb75..75451858 100644
--- a/libselinux/src/label_internal.h
+++ b/libselinux/src/label_internal.h
@@ -111,8 +111,7 @@ struct selabel_handle {
  * Validation function
  */
 extern int
-selabel_validate(struct selabel_handle *rec,
-struct selabel_lookup_rec *contexts) hidden;
+selabel_validate(struct selabel_lookup_rec *contexts) hidden;
 
 /*
  * Compatibility support
@@ -127,8 +126,7 @@ extern void __attribute__ ((format(printf, 1, 2)))
selinux_log(type, fmt);
 
 extern int
-compat_validate(struct selabel_handle *rec,
-   struct selabel_lookup_rec *contexts,
+compat_validate(struct selabel_lookup_rec *contexts,
const char *path, unsigned lineno) hidden;
 
 /*
diff --git 

[PATCH v3 2/2] libselinux: echo line number of bad label in selabel_fini()

2018-03-29 Thread Yuli Khodorkovskiy
Keep track of line numbers for each file context in
selabel_handle. If an error occurs in selabel_fini(), the
line number of an invalid file context is echoed to the user.

Signed-off-by: Yuli Khodorkovskiy 
---
 libselinux/src/label.c  | 2 +-
 libselinux/src/label_file.h | 1 +
 libselinux/src/label_internal.h | 1 +
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/libselinux/src/label.c b/libselinux/src/label.c
index c510edc1..591815a7 100644
--- a/libselinux/src/label.c
+++ b/libselinux/src/label.c
@@ -142,7 +142,7 @@ static int selabel_fini(struct selabel_handle *rec,
struct selabel_lookup_rec *lr,
int translating)
 {
-   if (compat_validate(lr, rec->spec_file, 0))
+   if (compat_validate(lr, rec->spec_file, lr->lineno))
return -1;
 
if (translating && !lr->ctx_trans &&
diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
index 9e52a3c4..3f9ce53b 100644
--- a/libselinux/src/label_file.h
+++ b/libselinux/src/label_file.h
@@ -472,6 +472,7 @@ static inline int process_line(struct selabel_handle *rec,
spec_arr[nspec].mode = 0;
 
spec_arr[nspec].lr.ctx_raw = context;
+   spec_arr[nspec].lr.lineno = lineno;
 
/*
 * bump data->nspecs to cause closef() to cover it in its free
diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h
index 75451858..b0d05882 100644
--- a/libselinux/src/label_internal.h
+++ b/libselinux/src/label_internal.h
@@ -73,6 +73,7 @@ struct selabel_lookup_rec {
char * ctx_raw;
char * ctx_trans;
int validated;
+   unsigned lineno;
 };
 
 struct selabel_handle {
-- 
2.14.3




Re: [PATCH 1/1] libsepol/cil: Improve processing of context rules

2018-03-29 Thread Pierre-Hugues Husson
The commit message and the code match my needs, and the few tests (not
unit tests at all though) I have are passing.
I'll test it on real devices, and I'll report back if anything seem wrong.

Just as a reminder, the only problems I hit for the moment are on
genfscon, so that's the only thing I've checked.

Thanks!

2018-03-29 22:14 GMT+02:00 jwcart2 :
> Pierre-Hugues Husson, I've tested and everything seems to work as I expect
> it, but does this meet your needs?
>
> Jim
>
>
> On 03/29/2018 04:06 PM, James Carter wrote:
>>
>> Improve the processing of netifcon, genfscon, ibpkeycon, ibendportcon,
>> portcon, nodecon, fsuse, filecon, iomemcon, ioportcon, pcidevicecon,
>> and devicetreecon rules.
>>
>> If the multiple-decls option is not used then report errors if duplicate
>> context rules are found. If it is used then remove duplicate context rules
>> and report errors when two rules are identical except for the context.
>>
>> This also changes the ordering of portcon and filecon rules. The protocol
>> of portcon rules will be compared if the port numbers are the same and the
>> path strings of filecon rules will be compared if the number of meta
>> characters, the stem length, string length and file types are the same.
>>
>> Based on an initial patch by Pierre-Hugues Husson (p...@phh.me)
>>
>> Signed-off-by: James Carter 
>> ---
>>   libsepol/cil/src/cil_post.c | 331
>> ++--
>>   1 file changed, 318 insertions(+), 13 deletions(-)
>>
>> diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
>> index a2122454..0b09cecc 100644
>> --- a/libsepol/cil/src/cil_post.c
>> +++ b/libsepol/cil/src/cil_post.c
>> @@ -53,6 +53,83 @@
>>   static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out,
>> int max, struct cil_db *db);
>>   static int __cil_expr_list_to_bitmap(struct cil_list *expr_list,
>> ebitmap_t *out, int max, struct cil_db *db);
>>   +static int cats_compare(struct cil_cats *a, struct cil_cats *b)
>> +{
>> +   struct cil_list_item *i, *j;
>> +   int rc;
>> +
>> +   if (a == b) return 0;
>> +   if (!a) return -1;
>> +   if (!b) return 1;
>> +
>> +   /* Expects cat expression to have been evaluated */
>> +   cil_list_for_each(i, a->datum_expr) {
>> +   cil_list_for_each(j, b->datum_expr) {
>> +   rc = strcmp(DATUM(i->data)->fqn,
>> DATUM(j->data)->fqn);
>> +   if (!rc) return rc;
>> +   }
>> +   }
>> +   return 0;
>> +}
>> +
>> +static int level_compare(struct cil_level *a, struct cil_level *b)
>> +{
>> +   int rc;
>> +
>> +   if (a == b) return 0;
>> +   if (!a) return -1;
>> +   if (!b) return 1;
>> +
>> +   if (a->sens != b->sens) {
>> +   rc = strcmp(DATUM(a->sens)->fqn, DATUM(b->sens)->fqn);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->cats != b->cats) {
>> +   return cats_compare(a->cats, b->cats);
>> +   }
>> +   return 0;
>> +}
>> +
>> +static int range_compare(struct cil_levelrange *a, struct cil_levelrange
>> *b)
>> +{
>> +   int rc;
>> +
>> +   if (a == b) return 0;
>> +   if (!a) return -1;
>> +   if (!b) return 1;
>> +
>> +   if (a->low != b->low) {
>> +   rc = level_compare(a->low, b->low);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->high != b->high) {
>> +   return level_compare(a->high, b->high);
>> +   }
>> +   return 0;
>> +}
>> +
>> +static int context_compare(struct cil_context *a, struct cil_context *b)
>> +{
>> +   int rc;
>> +
>> +   if (a->user != b->user) {
>> +   rc = strcmp(DATUM(a->user)->fqn, DATUM(b->user)->fqn);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->role != b->role) {
>> +   rc = strcmp(DATUM(a->role)->fqn, DATUM(b->role)->fqn);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->type != b->type) {
>> +   rc = strcmp(DATUM(a->type)->fqn, DATUM(b->type)->fqn);
>> +   if (rc != 0) return rc;
>> +   }
>> +   if (a->range != b->range) {
>> +   return range_compare(a->range, b->range);
>> +   }
>> +   return 0;
>> +}
>> +
>>   static int cil_verify_is_list(struct cil_list *list, enum cil_flavor
>> flavor)
>>   {
>> struct cil_list_item *curr;
>> @@ -145,6 +222,8 @@ int cil_post_filecon_compare(const void *a, const void
>> *b)
>> rc = -1;
>> } else if (b_filecon->type < a_filecon->type) {
>> rc = 1;
>> +   } else {
>> +   rc = strcmp(a_filecon->path_str, b_filecon->path_str);
>> }
>> free(a_path);
>> @@ -190,6 +269,10 @@ int cil_post_portcon_compare(const void *a, const
>> void *b)
>> rc = -1;
>> } else if (bportcon->port_low < aportcon->port_low) {
>> 

Re: [PATCH 1/1] libsepol/cil: Improve processing of context rules

2018-03-29 Thread jwcart2
Pierre-Hugues Husson, I've tested and everything seems to work as I expect it, 
but does this meet your needs?


Jim

On 03/29/2018 04:06 PM, James Carter wrote:

Improve the processing of netifcon, genfscon, ibpkeycon, ibendportcon,
portcon, nodecon, fsuse, filecon, iomemcon, ioportcon, pcidevicecon,
and devicetreecon rules.

If the multiple-decls option is not used then report errors if duplicate
context rules are found. If it is used then remove duplicate context rules
and report errors when two rules are identical except for the context.

This also changes the ordering of portcon and filecon rules. The protocol
of portcon rules will be compared if the port numbers are the same and the
path strings of filecon rules will be compared if the number of meta
characters, the stem length, string length and file types are the same.

Based on an initial patch by Pierre-Hugues Husson (p...@phh.me)

Signed-off-by: James Carter 
---
  libsepol/cil/src/cil_post.c | 331 ++--
  1 file changed, 318 insertions(+), 13 deletions(-)

diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index a2122454..0b09cecc 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -53,6 +53,83 @@
  static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int 
max, struct cil_db *db);
  static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t 
*out, int max, struct cil_db *db);
  
+static int cats_compare(struct cil_cats *a, struct cil_cats *b)

+{
+   struct cil_list_item *i, *j;
+   int rc;
+
+   if (a == b) return 0;
+   if (!a) return -1;
+   if (!b) return 1;
+
+   /* Expects cat expression to have been evaluated */
+   cil_list_for_each(i, a->datum_expr) {
+   cil_list_for_each(j, b->datum_expr) {
+   rc = strcmp(DATUM(i->data)->fqn, DATUM(j->data)->fqn);
+   if (!rc) return rc;
+   }
+   }
+   return 0;
+}
+
+static int level_compare(struct cil_level *a, struct cil_level *b)
+{
+   int rc;
+
+   if (a == b) return 0;
+   if (!a) return -1;
+   if (!b) return 1;
+
+   if (a->sens != b->sens) {
+   rc = strcmp(DATUM(a->sens)->fqn, DATUM(b->sens)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->cats != b->cats) {
+   return cats_compare(a->cats, b->cats);
+   }
+   return 0;
+}
+
+static int range_compare(struct cil_levelrange *a, struct cil_levelrange *b)
+{
+   int rc;
+
+   if (a == b) return 0;
+   if (!a) return -1;
+   if (!b) return 1;
+
+   if (a->low != b->low) {
+   rc = level_compare(a->low, b->low);
+   if (rc != 0) return rc;
+   }
+   if (a->high != b->high) {
+   return level_compare(a->high, b->high);
+   }
+   return 0;
+}
+
+static int context_compare(struct cil_context *a, struct cil_context *b)
+{
+   int rc;
+
+   if (a->user != b->user) {
+   rc = strcmp(DATUM(a->user)->fqn, DATUM(b->user)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->role != b->role) {
+   rc = strcmp(DATUM(a->role)->fqn, DATUM(b->role)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->type != b->type) {
+   rc = strcmp(DATUM(a->type)->fqn, DATUM(b->type)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->range != b->range) {
+   return range_compare(a->range, b->range);
+   }
+   return 0;
+}
+
  static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor)
  {
struct cil_list_item *curr;
@@ -145,6 +222,8 @@ int cil_post_filecon_compare(const void *a, const void *b)
rc = -1;
} else if (b_filecon->type < a_filecon->type) {
rc = 1;
+   } else {
+   rc = strcmp(a_filecon->path_str, b_filecon->path_str);
}
  
  	free(a_path);

@@ -190,6 +269,10 @@ int cil_post_portcon_compare(const void *a, const void *b)
rc = -1;
} else if (bportcon->port_low < aportcon->port_low) {
rc = 1;
+   } else if (aportcon->proto < bportcon->proto) {
+   rc = -1;
+   } else if (aportcon->proto > bportcon->proto) {
+   rc = 1;
}
}
  
@@ -369,6 +452,102 @@ int cil_post_fsuse_compare(const void *a, const void *b)

return rc;
  }
  
+int cil_post_filecon_context_compare(const void *a, const void *b)

+{
+   struct cil_filecon *a_filecon = *(struct cil_filecon**)a;
+   struct cil_filecon *b_filecon = *(struct cil_filecon**)b;
+   return context_compare(a_filecon->context, b_filecon->context);
+}
+
+int cil_post_ibpkeycon_context_compare(const void *a, const void *b)
+{
+   struct cil_ibpkeycon *a_ibpkeycon = 

[PATCH 1/1] libsepol/cil: Improve processing of context rules

2018-03-29 Thread James Carter
Improve the processing of netifcon, genfscon, ibpkeycon, ibendportcon,
portcon, nodecon, fsuse, filecon, iomemcon, ioportcon, pcidevicecon,
and devicetreecon rules.

If the multiple-decls option is not used then report errors if duplicate
context rules are found. If it is used then remove duplicate context rules
and report errors when two rules are identical except for the context.

This also changes the ordering of portcon and filecon rules. The protocol
of portcon rules will be compared if the port numbers are the same and the
path strings of filecon rules will be compared if the number of meta
characters, the stem length, string length and file types are the same.

Based on an initial patch by Pierre-Hugues Husson (p...@phh.me)

Signed-off-by: James Carter 
---
 libsepol/cil/src/cil_post.c | 331 ++--
 1 file changed, 318 insertions(+), 13 deletions(-)

diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index a2122454..0b09cecc 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -53,6 +53,83 @@
 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int 
max, struct cil_db *db);
 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t 
*out, int max, struct cil_db *db);
 
+static int cats_compare(struct cil_cats *a, struct cil_cats *b)
+{
+   struct cil_list_item *i, *j;
+   int rc;
+
+   if (a == b) return 0;
+   if (!a) return -1;
+   if (!b) return 1;
+
+   /* Expects cat expression to have been evaluated */
+   cil_list_for_each(i, a->datum_expr) {
+   cil_list_for_each(j, b->datum_expr) {
+   rc = strcmp(DATUM(i->data)->fqn, DATUM(j->data)->fqn);
+   if (!rc) return rc;
+   }
+   }
+   return 0;
+}
+
+static int level_compare(struct cil_level *a, struct cil_level *b)
+{
+   int rc;
+
+   if (a == b) return 0;
+   if (!a) return -1;
+   if (!b) return 1;
+
+   if (a->sens != b->sens) {
+   rc = strcmp(DATUM(a->sens)->fqn, DATUM(b->sens)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->cats != b->cats) {
+   return cats_compare(a->cats, b->cats);
+   }
+   return 0;
+}
+
+static int range_compare(struct cil_levelrange *a, struct cil_levelrange *b)
+{
+   int rc;
+
+   if (a == b) return 0;
+   if (!a) return -1;
+   if (!b) return 1;
+
+   if (a->low != b->low) {
+   rc = level_compare(a->low, b->low);
+   if (rc != 0) return rc;
+   }
+   if (a->high != b->high) {
+   return level_compare(a->high, b->high);
+   }
+   return 0;
+}
+
+static int context_compare(struct cil_context *a, struct cil_context *b)
+{
+   int rc;
+
+   if (a->user != b->user) {
+   rc = strcmp(DATUM(a->user)->fqn, DATUM(b->user)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->role != b->role) {
+   rc = strcmp(DATUM(a->role)->fqn, DATUM(b->role)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->type != b->type) {
+   rc = strcmp(DATUM(a->type)->fqn, DATUM(b->type)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->range != b->range) {
+   return range_compare(a->range, b->range);
+   }
+   return 0;
+}
+
 static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor)
 {
struct cil_list_item *curr;
@@ -145,6 +222,8 @@ int cil_post_filecon_compare(const void *a, const void *b)
rc = -1;
} else if (b_filecon->type < a_filecon->type) {
rc = 1;
+   } else {
+   rc = strcmp(a_filecon->path_str, b_filecon->path_str);
}
 
free(a_path);
@@ -190,6 +269,10 @@ int cil_post_portcon_compare(const void *a, const void *b)
rc = -1;
} else if (bportcon->port_low < aportcon->port_low) {
rc = 1;
+   } else if (aportcon->proto < bportcon->proto) {
+   rc = -1;
+   } else if (aportcon->proto > bportcon->proto) {
+   rc = 1;
}
}
 
@@ -369,6 +452,102 @@ int cil_post_fsuse_compare(const void *a, const void *b)
return rc;
 }
 
+int cil_post_filecon_context_compare(const void *a, const void *b)
+{
+   struct cil_filecon *a_filecon = *(struct cil_filecon**)a;
+   struct cil_filecon *b_filecon = *(struct cil_filecon**)b;
+   return context_compare(a_filecon->context, b_filecon->context);
+}
+
+int cil_post_ibpkeycon_context_compare(const void *a, const void *b)
+{
+   struct cil_ibpkeycon *a_ibpkeycon = *(struct cil_ibpkeycon **)a;
+   struct cil_ibpkeycon *b_ibpkeycon = *(struct cil_ibpkeycon **)b;
+   return context_compare(a_ibpkeycon->context, b_ibpkeycon->context);

Re: linux-next 20180327 - "SELinux: (dev dm-3, type ext4) getxattr errno 34"

2018-03-29 Thread Stephen Smalley
On 03/29/2018 02:29 PM, Stephen Smalley wrote:
> On 03/29/2018 01:57 PM, valdis.kletni...@vt.edu wrote:
>> Seeing this error trying to mount ext4 disks. next-20180320 was OK.
>>
>> SELinux: (dev dm-3, type ext4) getxattr errno 34
>>
>> and for /var, it refused to mount entirely (which brought the boot
>> process to a screeching halt).
>>
>> git log shows commits in the past few days against both selinux and ext4,
>> but nothing obvious.
>>
>> This ring any bells, or is it time to start bisecting?
> 
> commit de57a63ea4389e39b1cdd1cef15e1ec9b58a964c
> Author: Theodore Ts'o 
> Date:   Sun Mar 25 02:58:44 2018 -0400
> 
> ext4: add better range checking for e_value_size in xattrs
> 
> https://bugzilla.kernel.org/show_bug.cgi?id=199185
> 
> Reported-by: Wen Xu 
> Signed-off-by: Theodore Ts'o 
> Cc: sta...@vger.kernel.org
> 
> broke a longstanding assumption by SELinux that it could call getxattr with a 
> NULL buffer and 0 size to probe whether the filesystem supports the security 
> xattrs at mount time.
> 
> Options for fixing:
> - Revert or revise that patch to not return -ERANGE if buffer is NULL (prior 
> behavior),
> - Change SELinux sb_finish_set_opts() to treat -ERANGE as a non-error result.

Per https://bugzilla.kernel.org/show_bug.cgi?id=199185#c4, other callers 
besides SELinux are also broken by this change, so a revert or revision of the 
ext4 commit seems necessary regardless.
 
> 
>>
>> dmesg follows...
>>
>> [0.00] microcode: microcode updated early to revision 0x1f, date = 
>> 2018-02-07
>> [0.00] Linux version 4.16.0-rc7-next-20180327-dirty 
>> (sou...@turing-police.cc.vt.edu) (gcc version 8.0.1 20180317 (Red Hat 
>> 8.0.1-0.19) (GCC)) #565 SMP PREEMPT Wed Mar 28 01:01:48 EDT 2018
>> [0.00] Command line: 
>> BOOT_IMAGE=/vmlinuz-4.16.0-rc7-next-20180327-dirty 
>> root=/dev/mapper/turing--police-root ro rd.md=0 rd.dm=0 
>> rd.lvm.lv=turing-police/00 console.keymap= 
>> rd.luks.uuid=luks-665bb147-9e39-4003-b3ae-7be925f51a97 
>> rd.lvm.lv=turing-police/swap rd.lvm.lv=turing-police/root quiet 
>> LANG=en_US.UTF-8 nouveau.modeset=0 rd.driver.blacklist=nouveau 
>> video=vesa:off modprobe.blacklist=nouveau nvidia-drm.modeset=1 single
>> [0.00] KERNEL supported cpus:
>> [0.00]   Intel GenuineIntel
>> [0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point 
>> registers'
>> [0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
>> [0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
>> [0.00] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
>> [0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 
>> bytes, using 'standard' format.
>> [0.00] e820: BIOS-provided physical RAM map:
>> [0.00] BIOS-e820: [mem 0x-0x0009cfff] usable
>> [0.00] BIOS-e820: [mem 0x0009d000-0x0009efff] 
>> reserved
>> [0.00] BIOS-e820: [mem 0x0009f000-0x0009] usable
>> [0.00] BIOS-e820: [mem 0x0010-0xca709fff] usable
>> [0.00] BIOS-e820: [mem 0xca70a000-0xca7f] 
>> reserved
>> [0.00] BIOS-e820: [mem 0xca80-0xcaf52fff] usable
>> [0.00] BIOS-e820: [mem 0xcaf53000-0xcaff] 
>> reserved
>> [0.00] BIOS-e820: [mem 0xcb00-0xcb7b1fff] usable
>> [0.00] BIOS-e820: [mem 0xcb7b2000-0xcb7f] ACPI 
>> data
>> [0.00] BIOS-e820: [mem 0xcb80-0xccefdfff] usable
>> [0.00] BIOS-e820: [mem 0xccefe000-0xccff] ACPI 
>> NVS
>> [0.00] BIOS-e820: [mem 0xcd00-0xce5aefff] usable
>> [0.00] BIOS-e820: [mem 0xce5af000-0xcefa5fff] 
>> reserved
>> [0.00] BIOS-e820: [mem 0xcefa6000-0xcefe8fff] ACPI 
>> NVS
>> [0.00] BIOS-e820: [mem 0xcefe9000-0xcf2b1fff] usable
>> [0.00] BIOS-e820: [mem 0xcf2b2000-0xcf7e] 
>> reserved
>> [0.00] BIOS-e820: [mem 0xcf7f-0xcf7f] usable
>> [0.00] BIOS-e820: [mem 0xf800-0xfbff] 
>> reserved
>> [0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] 
>> reserved
>> [0.00] BIOS-e820: [mem 0xfed0-0xfed03fff] 
>> reserved
>> [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] 
>> reserved
>> [0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] 
>> reserved
>> [0.00] BIOS-e820: [mem 0xff00-0x] 
>> reserved
>> [0.00] BIOS-e820: [mem 0x0001-0x00040dfacfff] usable
>> [0.00] BIOS-e820: [mem 0x00040dfad000-0x00040dfadfff] 
>> unusable
>> [0.00] BIOS-e820: [mem 

Re: linux-next 20180327 - "SELinux: (dev dm-3, type ext4) getxattr errno 34"

2018-03-29 Thread Stephen Smalley
On 03/29/2018 01:57 PM, valdis.kletni...@vt.edu wrote:
> Seeing this error trying to mount ext4 disks. next-20180320 was OK.
> 
> SELinux: (dev dm-3, type ext4) getxattr errno 34
> 
> and for /var, it refused to mount entirely (which brought the boot
> process to a screeching halt).
> 
> git log shows commits in the past few days against both selinux and ext4,
> but nothing obvious.
> 
> This ring any bells, or is it time to start bisecting?

commit de57a63ea4389e39b1cdd1cef15e1ec9b58a964c
Author: Theodore Ts'o 
Date:   Sun Mar 25 02:58:44 2018 -0400

ext4: add better range checking for e_value_size in xattrs

https://bugzilla.kernel.org/show_bug.cgi?id=199185

Reported-by: Wen Xu 
Signed-off-by: Theodore Ts'o 
Cc: sta...@vger.kernel.org

broke a longstanding assumption by SELinux that it could call getxattr with a 
NULL buffer and 0 size to probe whether the filesystem supports the security 
xattrs at mount time.

Options for fixing:
- Revert or revise that patch to not return -ERANGE if buffer is NULL (prior 
behavior),
- Change SELinux sb_finish_set_opts() to treat -ERANGE as a non-error result.

> 
> dmesg follows...
> 
> [0.00] microcode: microcode updated early to revision 0x1f, date = 
> 2018-02-07
> [0.00] Linux version 4.16.0-rc7-next-20180327-dirty 
> (sou...@turing-police.cc.vt.edu) (gcc version 8.0.1 20180317 (Red Hat 
> 8.0.1-0.19) (GCC)) #565 SMP PREEMPT Wed Mar 28 01:01:48 EDT 2018
> [0.00] Command line: 
> BOOT_IMAGE=/vmlinuz-4.16.0-rc7-next-20180327-dirty 
> root=/dev/mapper/turing--police-root ro rd.md=0 rd.dm=0 
> rd.lvm.lv=turing-police/00 console.keymap= 
> rd.luks.uuid=luks-665bb147-9e39-4003-b3ae-7be925f51a97 
> rd.lvm.lv=turing-police/swap rd.lvm.lv=turing-police/root quiet 
> LANG=en_US.UTF-8 nouveau.modeset=0 rd.driver.blacklist=nouveau video=vesa:off 
> modprobe.blacklist=nouveau nvidia-drm.modeset=1 single
> [0.00] KERNEL supported cpus:
> [0.00]   Intel GenuineIntel
> [0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point 
> registers'
> [0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
> [0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
> [0.00] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
> [0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 
> bytes, using 'standard' format.
> [0.00] e820: BIOS-provided physical RAM map:
> [0.00] BIOS-e820: [mem 0x-0x0009cfff] usable
> [0.00] BIOS-e820: [mem 0x0009d000-0x0009efff] reserved
> [0.00] BIOS-e820: [mem 0x0009f000-0x0009] usable
> [0.00] BIOS-e820: [mem 0x0010-0xca709fff] usable
> [0.00] BIOS-e820: [mem 0xca70a000-0xca7f] reserved
> [0.00] BIOS-e820: [mem 0xca80-0xcaf52fff] usable
> [0.00] BIOS-e820: [mem 0xcaf53000-0xcaff] reserved
> [0.00] BIOS-e820: [mem 0xcb00-0xcb7b1fff] usable
> [0.00] BIOS-e820: [mem 0xcb7b2000-0xcb7f] ACPI 
> data
> [0.00] BIOS-e820: [mem 0xcb80-0xccefdfff] usable
> [0.00] BIOS-e820: [mem 0xccefe000-0xccff] ACPI NVS
> [0.00] BIOS-e820: [mem 0xcd00-0xce5aefff] usable
> [0.00] BIOS-e820: [mem 0xce5af000-0xcefa5fff] reserved
> [0.00] BIOS-e820: [mem 0xcefa6000-0xcefe8fff] ACPI NVS
> [0.00] BIOS-e820: [mem 0xcefe9000-0xcf2b1fff] usable
> [0.00] BIOS-e820: [mem 0xcf2b2000-0xcf7e] reserved
> [0.00] BIOS-e820: [mem 0xcf7f-0xcf7f] usable
> [0.00] BIOS-e820: [mem 0xf800-0xfbff] reserved
> [0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] reserved
> [0.00] BIOS-e820: [mem 0xfed0-0xfed03fff] reserved
> [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved
> [0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved
> [0.00] BIOS-e820: [mem 0xff00-0x] reserved
> [0.00] BIOS-e820: [mem 0x0001-0x00040dfacfff] usable
> [0.00] BIOS-e820: [mem 0x00040dfad000-0x00040dfadfff] unusable
> [0.00] BIOS-e820: [mem 0x00040dfae000-0x00040dfaefff] usable
> [0.00] BIOS-e820: [mem 0x00040dfaf000-0x00040dfa] unusable
> [0.00] BIOS-e820: [mem 0x00040dfb-0x00040dfeafff] usable
> [0.00] BIOS-e820: [mem 0x00040dfeb000-0x00040dfebfff] unusable
> [0.00] BIOS-e820: [mem 0x00040dfec000-0x00042dff] usable
> [0.00] NX (Execute Disable) protection: active
> [

Re: [PATCH v2 1/1] Detect identical genfscon

2018-03-29 Thread Pierre-Hugues Husson
2018-03-23 0:04 GMT+01:00 Pierre-Hugues Husson :
> From: Pierre-Hugues Husson 
>
> Currently secilc doesn't deal with duplicate genfscon rules
>
> This commit fixes this, and implements multiple_decls behaviour.
>
> To reduce the code changes, the compare function returns in its LSB
> whether the rules are only a matching rule match, or a full match.
> ---
>  libsepol/cil/src/cil_post.c | 34 --
>  1 file changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
> index a2122454..c054e9ce 100644
> --- a/libsepol/cil/src/cil_post.c
> +++ b/libsepol/cil/src/cil_post.c
> @@ -53,6 +53,26 @@
>  static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int 
> max, struct cil_db *db);
>  static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t 
> *out, int max, struct cil_db *db);
>
> +/* compare function returns whether a,b have the same context in the LSB */
> +static int compact(void* array, uint32_t *count, int len, int 
> (*compare)(const void *, const void *), int multiple_decls) {
> +   char *a = (char*)array;
> +   uint32_t i, j = 0;
> +   int c;
> +   for(i=1; i<*count; i++) {
> +   c = compare(a+i*len, a+j*len);
> +   /* If LSB is set, it means the rules match except for the 
> context
> +* We never want this */
> +   if(c&1) return SEPOL_ERR;
> +
> +   if(!multiple_decls && c == 0) return SEPOL_ERR;
> +
> +   if(c) j++;
> +   if(i != j) memcpy(a+j*len, a+i*len, len);
> +   }
> +   *count = j;
I've just realized this should actually be j+1



linux-next 20180327 - "SELinux: (dev dm-3, type ext4) getxattr errno 34"

2018-03-29 Thread valdis . kletnieks
Seeing this error trying to mount ext4 disks. next-20180320 was OK.

SELinux: (dev dm-3, type ext4) getxattr errno 34

and for /var, it refused to mount entirely (which brought the boot
process to a screeching halt).

git log shows commits in the past few days against both selinux and ext4,
but nothing obvious.

This ring any bells, or is it time to start bisecting?

dmesg follows...

[0.00] microcode: microcode updated early to revision 0x1f, date = 
2018-02-07
[0.00] Linux version 4.16.0-rc7-next-20180327-dirty 
(sou...@turing-police.cc.vt.edu) (gcc version 8.0.1 20180317 (Red Hat 
8.0.1-0.19) (GCC)) #565 SMP PREEMPT Wed Mar 28 01:01:48 EDT 2018
[0.00] Command line: BOOT_IMAGE=/vmlinuz-4.16.0-rc7-next-20180327-dirty 
root=/dev/mapper/turing--police-root ro rd.md=0 rd.dm=0 
rd.lvm.lv=turing-police/00 console.keymap= 
rd.luks.uuid=luks-665bb147-9e39-4003-b3ae-7be925f51a97 
rd.lvm.lv=turing-police/swap rd.lvm.lv=turing-police/root quiet 
LANG=en_US.UTF-8 nouveau.modeset=0 rd.driver.blacklist=nouveau video=vesa:off 
modprobe.blacklist=nouveau nvidia-drm.modeset=1 single
[0.00] KERNEL supported cpus:
[0.00]   Intel GenuineIntel
[0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point 
registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[0.00] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
[0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, 
using 'standard' format.
[0.00] e820: BIOS-provided physical RAM map:
[0.00] BIOS-e820: [mem 0x-0x0009cfff] usable
[0.00] BIOS-e820: [mem 0x0009d000-0x0009efff] reserved
[0.00] BIOS-e820: [mem 0x0009f000-0x0009] usable
[0.00] BIOS-e820: [mem 0x0010-0xca709fff] usable
[0.00] BIOS-e820: [mem 0xca70a000-0xca7f] reserved
[0.00] BIOS-e820: [mem 0xca80-0xcaf52fff] usable
[0.00] BIOS-e820: [mem 0xcaf53000-0xcaff] reserved
[0.00] BIOS-e820: [mem 0xcb00-0xcb7b1fff] usable
[0.00] BIOS-e820: [mem 0xcb7b2000-0xcb7f] ACPI data
[0.00] BIOS-e820: [mem 0xcb80-0xccefdfff] usable
[0.00] BIOS-e820: [mem 0xccefe000-0xccff] ACPI NVS
[0.00] BIOS-e820: [mem 0xcd00-0xce5aefff] usable
[0.00] BIOS-e820: [mem 0xce5af000-0xcefa5fff] reserved
[0.00] BIOS-e820: [mem 0xcefa6000-0xcefe8fff] ACPI NVS
[0.00] BIOS-e820: [mem 0xcefe9000-0xcf2b1fff] usable
[0.00] BIOS-e820: [mem 0xcf2b2000-0xcf7e] reserved
[0.00] BIOS-e820: [mem 0xcf7f-0xcf7f] usable
[0.00] BIOS-e820: [mem 0xf800-0xfbff] reserved
[0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] reserved
[0.00] BIOS-e820: [mem 0xfed0-0xfed03fff] reserved
[0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved
[0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved
[0.00] BIOS-e820: [mem 0xff00-0x] reserved
[0.00] BIOS-e820: [mem 0x0001-0x00040dfacfff] usable
[0.00] BIOS-e820: [mem 0x00040dfad000-0x00040dfadfff] unusable
[0.00] BIOS-e820: [mem 0x00040dfae000-0x00040dfaefff] usable
[0.00] BIOS-e820: [mem 0x00040dfaf000-0x00040dfa] unusable
[0.00] BIOS-e820: [mem 0x00040dfb-0x00040dfeafff] usable
[0.00] BIOS-e820: [mem 0x00040dfeb000-0x00040dfebfff] unusable
[0.00] BIOS-e820: [mem 0x00040dfec000-0x00042dff] usable
[0.00] NX (Execute Disable) protection: active
[0.00] e820: update [mem 0xc7b50018-0xc7b6ce57] usable ==> usable
[0.00] e820: update [mem 0xc7b50018-0xc7b6ce57] usable ==> usable
[0.00] extended physical RAM map:
[0.00] reserve setup_data: [mem 0x-0x0009cfff] 
usable
[0.00] reserve setup_data: [mem 0x0009d000-0x0009efff] 
reserved
[0.00] reserve setup_data: [mem 0x0009f000-0x0009] 
usable
[0.00] reserve setup_data: [mem 0x0010-0xc7b50017] 
usable
[0.00] reserve setup_data: [mem 0xc7b50018-0xc7b6ce57] 
usable
[0.00] reserve setup_data: [mem 0xc7b6ce58-0xca709fff] 
usable
[0.00] reserve setup_data: [mem 0xca70a000-0xca7f] 
reserved
[0.00] reserve setup_data: [mem 0xca80-0xcaf52fff] 
usable
[0.00] reserve setup_data: [mem 

Re: [PATCH net-next 0/5] Introduce net_rwsem to protect net_namespace_list

2018-03-29 Thread David Miller
From: Kirill Tkhai 
Date: Thu, 29 Mar 2018 19:20:23 +0300

> The series introduces fine grained rw_semaphore, which will be used
> instead of rtnl_lock() to protect net_namespace_list.
> 
> This improves scalability and allows to do non-exclusive sleepable
> iteration for_each_net(), which is enough for most cases.
> 
> scripts/get_maintainer.pl gives enormous list of people, and I add
> all to CC.
> 
> Note, that this patch is independent of "Close race between
> {un, }register_netdevice_notifier and pernet_operations":
> https://patchwork.ozlabs.org/project/netdev/list/?series=36495
> 
> Signed-off-by: Kirill Tkhai 

Great stuff!

Series applied, thanks!



Re: [PATCH v2 2/2] libselinux: echo line number of bad label in selabel_fini()

2018-03-29 Thread Yuli Khodorkovskiy
Alright, then I'll resubmit with a fix for the compiler warnings and
do the rest of the enhancements as a separate patch set.

On Thu, Mar 29, 2018 at 12:35 PM, Stephen Smalley  wrote:
> On 03/29/2018 11:48 AM, Yuli Khodorkovskiy wrote:
>>
>>
>> On Thu, Mar 29, 2018 at 9:49 AM, Stephen Smalley > > wrote:
>>
>> On 03/28/2018 11:40 PM, Yuli Khodorkovskiy wrote:
>> > Keep track of line numbers for each file context in
>> > selabel_handle. If an error occurs in selabel_fini(), the
>> > line number of an invalid file context is echoed to the user.
>> >
>> > Signed-off-by: Yuli Khodorkovskiy > >
>> > ---
>> >  libselinux/src/label.c  | 2 +-
>> >  libselinux/src/label_file.h | 1 +
>> >  libselinux/src/label_internal.h | 1 +
>> >  3 files changed, 3 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/libselinux/src/label.c b/libselinux/src/label.c
>> > index e642a97b..d9a58ce9 100644
>> > --- a/libselinux/src/label.c
>> > +++ b/libselinux/src/label.c
>> > @@ -143,7 +143,7 @@ static int selabel_fini(struct selabel_handle *rec,
>> >   struct selabel_lookup_rec *lr,
>> >   int translating)
>> >  {
>> > - if (compat_validate(rec, lr, rec->spec_file, 0))
>> > + if (compat_validate(rec, lr, rec->spec_file, lr->lineno))
>> >   return -1;
>> >
>> >   if (translating && !lr->ctx_trans &&
>> > diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
>> > index aa576d8e..4780ae48 100644
>> > --- a/libselinux/src/label_file.h
>> > +++ b/libselinux/src/label_file.h
>> > @@ -472,6 +472,7 @@ static inline int process_line(struct 
>> selabel_handle *rec,
>> >   spec_arr[nspec].mode = 0;
>> >
>> >   spec_arr[nspec].lr.ctx_raw = context;
>> > + spec_arr[nspec].lr.lineno = lineno;
>> >
>> >   /*
>> >* bump data->nspecs to cause closef() to cover it in its free
>> > diff --git a/libselinux/src/label_internal.h 
>> b/libselinux/src/label_internal.h
>> > index c55efb75..0e020557 100644
>> > --- a/libselinux/src/label_internal.h
>> > +++ b/libselinux/src/label_internal.h
>> > @@ -73,6 +73,7 @@ struct selabel_lookup_rec {
>> >   char * ctx_raw;
>> >   char * ctx_trans;
>> >   int validated;
>> > + unsigned lineno;
>> >  };
>> >
>> >  struct selabel_handle {
>> >
>>
>> I think this is ok, but wanted to double check: does this work correctly 
>> when file contexts are loaded from
>> file_contexts.bin instead?  It looks to me as if the lineno will be left 
>> as 0 in that case and the
>> code will handle that correctly.
>>
>>
>> Compiling a file_contexts.bin with sefcontext_compile will give you the line 
>> number:
>>
>> sefcontext_compile /etc/selinux/targeted/contexts/files/file_contexts -o 
>> file_contexts.bin -p /etc/selinux/targeted/policy/policy.31
>> libsepol.sepol_context_from_string: malformed context "test"
>> libsepol.sepol_context_from_string: could not construct context from string
>> libsepol.context_from_string: could not create context structure
>> libsepol.sepol_context_to_sid: could not convert test to sid
>> /etc/selinux/targeted/contexts/files/file_contexts: line 6132 has invalid 
>> context test
>> sefcontext_compile: process_file failed
>>
>> Using file_contexts.bin for relabeling that I generated with no validation 
>> will not report a line number:
>>
>> restorecon: /etc/selinux/targeted/contexts/files/file_contexts: has invalid 
>> context test
>>
>> I'll see if I can associate the line number with each regex in 
>> sefcontext_compile.
>
> That's fine if you want to do it but not necessary for these patches to be 
> merged; I just wanted to ensure that we don't have garbage output as a result 
> of these patches.  I'd do it as a separate patch regardless since it likely 
> requires a new binary format version for the file_contexts.bin files.
>
>> The other question is whether we correctly report the file name when the 
>> entry comes from a file other
>> than file_contexts itself, e.g. file_contexts.local, .homedirs, ...  Not 
>> your bug if we don't but wondered.
>>
>>
>> It is reporting the line number correctly, but the filename is incorrect. 
>> I'll update this.
>
> Again, not strictly necessary for these patches since you didn't introduce 
> the bug, and probably ought to be its own separate patch.
>




[PATCH net-next 4/5] ovs: Remove rtnl_lock() from ovs_exit_net()

2018-03-29 Thread Kirill Tkhai
Here we iterate for_each_net() and removes
vport from alive net to the exiting net.

ovs_net::dps are protected by ovs_mutex(),
and the others, who change it (ovs_dp_cmd_new(),
__dp_destroy()) also take it.
The same with datapath::ports list.

So, we remove rtnl_lock() here.

Signed-off-by: Kirill Tkhai 
---
 net/openvswitch/datapath.c |2 --
 1 file changed, 2 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 9746ee30a99b..015e24e08909 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -2363,12 +2363,10 @@ static void __net_exit ovs_exit_net(struct net *dnet)
list_for_each_entry_safe(dp, dp_next, _net->dps, list_node)
__dp_destroy(dp);
 
-   rtnl_lock();
down_read(_rwsem);
for_each_net(net)
list_vports_from_net(net, dnet, );
up_read(_rwsem);
-   rtnl_unlock();
 
/* Detach all vports from given namespace. */
list_for_each_entry_safe(vport, vport_next, , detach_list) {




[PATCH net-next 5/5] net: Remove rtnl_lock() in nf_ct_iterate_destroy()

2018-03-29 Thread Kirill Tkhai
rtnl_lock() doesn't protect net::ct::count,
and it's not needed for__nf_ct_unconfirmed_destroy()
and for nf_queue_nf_hook_drop().

Signed-off-by: Kirill Tkhai 
---
 net/netfilter/nf_conntrack_core.c |2 --
 1 file changed, 2 deletions(-)

diff --git a/net/netfilter/nf_conntrack_core.c 
b/net/netfilter/nf_conntrack_core.c
index 370f9b7f051b..41ff04ee2554 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1763,7 +1763,6 @@ nf_ct_iterate_destroy(int (*iter)(struct nf_conn *i, void 
*data), void *data)
 {
struct net *net;
 
-   rtnl_lock();
down_read(_rwsem);
for_each_net(net) {
if (atomic_read(>ct.count) == 0)
@@ -1772,7 +1771,6 @@ nf_ct_iterate_destroy(int (*iter)(struct nf_conn *i, void 
*data), void *data)
nf_queue_nf_hook_drop(net);
}
up_read(_rwsem);
-   rtnl_unlock();
 
/* Need to wait for netns cleanup worker to finish, if its
 * running -- it might have deleted a net namespace from




[PATCH net-next 3/5] security: Remove rtnl_lock() in selinux_xfrm_notify_policyload()

2018-03-29 Thread Kirill Tkhai
rt_genid_bump_all() consists of ipv4 and ipv6 part.
ipv4 part is incrementing of net::ipv4::rt_genid,
and I see many places, where it's read without rtnl_lock().

ipv6 part calls __fib6_clean_all(), and it's also
called without rtnl_lock() in other places.

So, rtnl_lock() here was used to iterate net_namespace_list only,
and we can remove it.

Signed-off-by: Kirill Tkhai 
---
 security/selinux/include/xfrm.h |2 --
 1 file changed, 2 deletions(-)

diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 31d66431be1e..a0b465316292 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -47,12 +47,10 @@ static inline void selinux_xfrm_notify_policyload(void)
 {
struct net *net;
 
-   rtnl_lock();
down_read(_rwsem);
for_each_net(net)
rt_genid_bump_all(net);
up_read(_rwsem);
-   rtnl_unlock();
 }
 #else
 static inline int selinux_xfrm_enabled(void)




[PATCH net-next 2/5] net: Don't take rtnl_lock() in wireless_nlevent_flush()

2018-03-29 Thread Kirill Tkhai
This function iterates over net_namespace_list and flushes
the queue for every of them. What does this rtnl_lock()
protects?! Since we may add skbs to net::wext_nlevents
without rtnl_lock(), it does not protects us about queuers.

It guarantees, two threads can't flush the queue in parallel,
that can change the order, but since skb can be queued
in any order, it doesn't matter, how many threads do this
in parallel. In case of several threads, this will be even
faster.

So, we can remove rtnl_lock() here, as it was used for
iteration over net_namespace_list only.

Signed-off-by: Kirill Tkhai 
---
 net/wireless/wext-core.c |4 
 1 file changed, 4 deletions(-)

diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 544d7b62d7ca..5e677dac2a0c 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -347,8 +347,6 @@ void wireless_nlevent_flush(void)
struct sk_buff *skb;
struct net *net;
 
-   ASSERT_RTNL();
-
down_read(_rwsem);
for_each_net(net) {
while ((skb = skb_dequeue(>wext_nlevents)))
@@ -412,9 +410,7 @@ subsys_initcall(wireless_nlevent_init);
 /* Process events generated by the wireless layer or the driver. */
 static void wireless_nlevent_process(struct work_struct *work)
 {
-   rtnl_lock();
wireless_nlevent_flush();
-   rtnl_unlock();
 }
 
 static DECLARE_WORK(wireless_nlevent_work, wireless_nlevent_process);




Re: [PATCH v2 2/2] libselinux: echo line number of bad label in selabel_fini()

2018-03-29 Thread Stephen Smalley
On 03/29/2018 11:48 AM, Yuli Khodorkovskiy wrote:
> 
> 
> On Thu, Mar 29, 2018 at 9:49 AM, Stephen Smalley  > wrote:
> 
> On 03/28/2018 11:40 PM, Yuli Khodorkovskiy wrote:
> > Keep track of line numbers for each file context in
> > selabel_handle. If an error occurs in selabel_fini(), the
> > line number of an invalid file context is echoed to the user.
> >
> > Signed-off-by: Yuli Khodorkovskiy  >
> > ---
> >  libselinux/src/label.c          | 2 +-
> >  libselinux/src/label_file.h     | 1 +
> >  libselinux/src/label_internal.h | 1 +
> >  3 files changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/libselinux/src/label.c b/libselinux/src/label.c
> > index e642a97b..d9a58ce9 100644
> > --- a/libselinux/src/label.c
> > +++ b/libselinux/src/label.c
> > @@ -143,7 +143,7 @@ static int selabel_fini(struct selabel_handle *rec,
> >                           struct selabel_lookup_rec *lr,
> >                           int translating)
> >  {
> > -     if (compat_validate(rec, lr, rec->spec_file, 0))
> > +     if (compat_validate(rec, lr, rec->spec_file, lr->lineno))
> >               return -1;
> >
> >       if (translating && !lr->ctx_trans &&
> > diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
> > index aa576d8e..4780ae48 100644
> > --- a/libselinux/src/label_file.h
> > +++ b/libselinux/src/label_file.h
> > @@ -472,6 +472,7 @@ static inline int process_line(struct 
> selabel_handle *rec,
> >       spec_arr[nspec].mode = 0;
> >
> >       spec_arr[nspec].lr.ctx_raw = context;
> > +     spec_arr[nspec].lr.lineno = lineno;
> >
> >       /*
> >        * bump data->nspecs to cause closef() to cover it in its free
> > diff --git a/libselinux/src/label_internal.h 
> b/libselinux/src/label_internal.h
> > index c55efb75..0e020557 100644
> > --- a/libselinux/src/label_internal.h
> > +++ b/libselinux/src/label_internal.h
> > @@ -73,6 +73,7 @@ struct selabel_lookup_rec {
> >       char * ctx_raw;
> >       char * ctx_trans;
> >       int validated;
> > +     unsigned lineno;
> >  };
> >
> >  struct selabel_handle {
> >
> 
> I think this is ok, but wanted to double check: does this work correctly 
> when file contexts are loaded from
> file_contexts.bin instead?  It looks to me as if the lineno will be left 
> as 0 in that case and the
> code will handle that correctly.
> 
> 
> Compiling a file_contexts.bin with sefcontext_compile will give you the line 
> number:
> 
> sefcontext_compile /etc/selinux/targeted/contexts/files/file_contexts -o 
> file_contexts.bin -p /etc/selinux/targeted/policy/policy.31
> libsepol.sepol_context_from_string: malformed context "test"
> libsepol.sepol_context_from_string: could not construct context from string
> libsepol.context_from_string: could not create context structure
> libsepol.sepol_context_to_sid: could not convert test to sid
> /etc/selinux/targeted/contexts/files/file_contexts: line 6132 has invalid 
> context test
> sefcontext_compile: process_file failed
> 
> Using file_contexts.bin for relabeling that I generated with no validation 
> will not report a line number:
> 
> restorecon: /etc/selinux/targeted/contexts/files/file_contexts: has invalid 
> context test
> 
> I'll see if I can associate the line number with each regex in 
> sefcontext_compile.

That's fine if you want to do it but not necessary for these patches to be 
merged; I just wanted to ensure that we don't have garbage output as a result 
of these patches.  I'd do it as a separate patch regardless since it likely 
requires a new binary format version for the file_contexts.bin files. 

> The other question is whether we correctly report the file name when the 
> entry comes from a file other
> than file_contexts itself, e.g. file_contexts.local, .homedirs, ...  Not 
> your bug if we don't but wondered.
> 
> 
> It is reporting the line number correctly, but the filename is incorrect. 
> I'll update this.

Again, not strictly necessary for these patches since you didn't introduce the 
bug, and probably ought to be its own separate patch.



Re: [PATCH v2 1/2] libselinux: verify file_contexts when using restorecon

2018-03-29 Thread William Roberts
On Thu, Mar 29, 2018 at 5:37 AM, Stephen Smalley  wrote:
> On 03/28/2018 11:40 PM, Yuli Khodorkovskiy wrote:
>> In permissive mode, calling restorecon with a bad label in file_contexts
>> does not verify the label's existence in the loaded policy. This
>> results in any label successfully applying to a file, as long as the
>> file exists.
>>
>> This issue has two assumptions:
>>
>> 1) file_contexts must be manually updated with the invalid label.
>> Running `semanage fcontext` will error when attempting to add
>> an invalid label to file_contexts.
>> 2) the system must be in permissive. Although applying an invalid label
>> in enforcing gives an error and fails, successfully labeling a file with a
>> bad label could cause issues during policy development in permissive.
>>
>> Instead, as each context is used, verify it is valid before blindly
>> applying the label. If an error with validation occurs in restorecon,
>> application of remaining valid labels will be uninterrupted as before.
>>
>> Signed-off-by: Yuli Khodorkovskiy 
>> ---
>>  libselinux/src/label.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/libselinux/src/label.c b/libselinux/src/label.c
>> index 48f4d2d6..e642a97b 100644
>> --- a/libselinux/src/label.c
>> +++ b/libselinux/src/label.c
>> @@ -126,7 +126,7 @@ int selabel_validate(struct selabel_handle *rec,
>>  {
>>   int rc = 0;
>>
>> - if (!rec->validating || contexts->validated)
>> + if (contexts->validated)
>>   goto out;
>>
>>   rc = selinux_validate(>ctx_raw);
>>
>
> label.c: In function ‘selabel_validate’:
> label.c:124:45: error: unused parameter ‘rec’ [-Werror=unused-parameter]
>  int selabel_validate(struct selabel_handle *rec,
>  ^~~
> Need to drop the rec argument to selabel_validate() since it is no longer 
> used.

I figured with -Wall -Werror we would be good. For some reason, I
can't reproduce with my
ancient version of gcc. gcc versions 5 and above properly reports this. Weird.




Re: [PATCH v2 2/2] libselinux: echo line number of bad label in selabel_fini()

2018-03-29 Thread Yuli Khodorkovskiy
On Thu, Mar 29, 2018 at 9:49 AM, Stephen Smalley  wrote:

> On 03/28/2018 11:40 PM, Yuli Khodorkovskiy wrote:
> > Keep track of line numbers for each file context in
> > selabel_handle. If an error occurs in selabel_fini(), the
> > line number of an invalid file context is echoed to the user.
> >
> > Signed-off-by: Yuli Khodorkovskiy 
> > ---
> >  libselinux/src/label.c  | 2 +-
> >  libselinux/src/label_file.h | 1 +
> >  libselinux/src/label_internal.h | 1 +
> >  3 files changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/libselinux/src/label.c b/libselinux/src/label.c
> > index e642a97b..d9a58ce9 100644
> > --- a/libselinux/src/label.c
> > +++ b/libselinux/src/label.c
> > @@ -143,7 +143,7 @@ static int selabel_fini(struct selabel_handle *rec,
> >   struct selabel_lookup_rec *lr,
> >   int translating)
> >  {
> > - if (compat_validate(rec, lr, rec->spec_file, 0))
> > + if (compat_validate(rec, lr, rec->spec_file, lr->lineno))
> >   return -1;
> >
> >   if (translating && !lr->ctx_trans &&
> > diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
> > index aa576d8e..4780ae48 100644
> > --- a/libselinux/src/label_file.h
> > +++ b/libselinux/src/label_file.h
> > @@ -472,6 +472,7 @@ static inline int process_line(struct selabel_handle
> *rec,
> >   spec_arr[nspec].mode = 0;
> >
> >   spec_arr[nspec].lr.ctx_raw = context;
> > + spec_arr[nspec].lr.lineno = lineno;
> >
> >   /*
> >* bump data->nspecs to cause closef() to cover it in its free
> > diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_
> internal.h
> > index c55efb75..0e020557 100644
> > --- a/libselinux/src/label_internal.h
> > +++ b/libselinux/src/label_internal.h
> > @@ -73,6 +73,7 @@ struct selabel_lookup_rec {
> >   char * ctx_raw;
> >   char * ctx_trans;
> >   int validated;
> > + unsigned lineno;
> >  };
> >
> >  struct selabel_handle {
> >
>
> I think this is ok, but wanted to double check: does this work correctly
> when file contexts are loaded from
> file_contexts.bin instead?  It looks to me as if the lineno will be left
> as 0 in that case and the
> code will handle that correctly.
>

Compiling a file_contexts.bin with sefcontext_compile will give you the
line number:

sefcontext_compile /etc/selinux/targeted/contexts/files/file_contexts -o
file_contexts.bin -p /etc/selinux/targeted/policy/policy.31
libsepol.sepol_context_from_string: malformed context "test"
libsepol.sepol_context_from_string: could not construct context from string
libsepol.context_from_string: could not create context structure
libsepol.sepol_context_to_sid: could not convert test to sid
/etc/selinux/targeted/contexts/files/file_contexts: line 6132 has invalid
context test
sefcontext_compile: process_file failed

Using file_contexts.bin for relabeling that I generated with no validation
will not report a line number:

restorecon: /etc/selinux/targeted/contexts/files/file_contexts: has invalid
context test

I'll see if I can associate the line number with each regex in
sefcontext_compile.



>
> The other question is whether we correctly report the file name when the
> entry comes from a file other
> than file_contexts itself, e.g. file_contexts.local, .homedirs, ...  Not
> your bug if we don't but wondered.
>

It is reporting the line number correctly, but the filename is incorrect.
I'll update this.


Re: [PATCH v2 2/2] libselinux: echo line number of bad label in selabel_fini()

2018-03-29 Thread Stephen Smalley
On 03/28/2018 11:40 PM, Yuli Khodorkovskiy wrote:
> Keep track of line numbers for each file context in
> selabel_handle. If an error occurs in selabel_fini(), the
> line number of an invalid file context is echoed to the user.
> 
> Signed-off-by: Yuli Khodorkovskiy 
> ---
>  libselinux/src/label.c  | 2 +-
>  libselinux/src/label_file.h | 1 +
>  libselinux/src/label_internal.h | 1 +
>  3 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/libselinux/src/label.c b/libselinux/src/label.c
> index e642a97b..d9a58ce9 100644
> --- a/libselinux/src/label.c
> +++ b/libselinux/src/label.c
> @@ -143,7 +143,7 @@ static int selabel_fini(struct selabel_handle *rec,
>   struct selabel_lookup_rec *lr,
>   int translating)
>  {
> - if (compat_validate(rec, lr, rec->spec_file, 0))
> + if (compat_validate(rec, lr, rec->spec_file, lr->lineno))
>   return -1;
>  
>   if (translating && !lr->ctx_trans &&
> diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
> index aa576d8e..4780ae48 100644
> --- a/libselinux/src/label_file.h
> +++ b/libselinux/src/label_file.h
> @@ -472,6 +472,7 @@ static inline int process_line(struct selabel_handle *rec,
>   spec_arr[nspec].mode = 0;
>  
>   spec_arr[nspec].lr.ctx_raw = context;
> + spec_arr[nspec].lr.lineno = lineno;
>  
>   /*
>* bump data->nspecs to cause closef() to cover it in its free
> diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h
> index c55efb75..0e020557 100644
> --- a/libselinux/src/label_internal.h
> +++ b/libselinux/src/label_internal.h
> @@ -73,6 +73,7 @@ struct selabel_lookup_rec {
>   char * ctx_raw;
>   char * ctx_trans;
>   int validated;
> + unsigned lineno;
>  };
>  
>  struct selabel_handle {
> 

I think this is ok, but wanted to double check: does this work correctly when 
file contexts are loaded from
file_contexts.bin instead?  It looks to me as if the lineno will be left as 0 
in that case and the
code will handle that correctly.

The other question is whether we correctly report the file name when the entry 
comes from a file other
than file_contexts itself, e.g. file_contexts.local, .homedirs, ...  Not your 
bug if we don't but wondered.



Re: [PATCH v2 1/2] libselinux: verify file_contexts when using restorecon

2018-03-29 Thread Stephen Smalley
On 03/28/2018 11:40 PM, Yuli Khodorkovskiy wrote:
> In permissive mode, calling restorecon with a bad label in file_contexts
> does not verify the label's existence in the loaded policy. This
> results in any label successfully applying to a file, as long as the
> file exists.
> 
> This issue has two assumptions:
> 
> 1) file_contexts must be manually updated with the invalid label.
> Running `semanage fcontext` will error when attempting to add
> an invalid label to file_contexts.
> 2) the system must be in permissive. Although applying an invalid label
> in enforcing gives an error and fails, successfully labeling a file with a
> bad label could cause issues during policy development in permissive.
> 
> Instead, as each context is used, verify it is valid before blindly
> applying the label. If an error with validation occurs in restorecon,
> application of remaining valid labels will be uninterrupted as before.
> 
> Signed-off-by: Yuli Khodorkovskiy 
> ---
>  libselinux/src/label.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/libselinux/src/label.c b/libselinux/src/label.c
> index 48f4d2d6..e642a97b 100644
> --- a/libselinux/src/label.c
> +++ b/libselinux/src/label.c
> @@ -126,7 +126,7 @@ int selabel_validate(struct selabel_handle *rec,
>  {
>   int rc = 0;
>  
> - if (!rec->validating || contexts->validated)
> + if (contexts->validated)
>   goto out;
>  
>   rc = selinux_validate(>ctx_raw);
> 

label.c: In function ‘selabel_validate’:
label.c:124:45: error: unused parameter ‘rec’ [-Werror=unused-parameter]
 int selabel_validate(struct selabel_handle *rec,
 ^~~
Need to drop the rec argument to selabel_validate() since it is no longer used.