selinux: libselinux: Enable multiple input files to selabel_open.
PATCH 1/1 selinux: libselinux: Enable multiple input files to selabel_open.
From: Dan Cashman <[email protected]>
The file_contexts labeling backend, specified in label_file.c, currently assumes that only one path will be specified as an option to selabel_open(). The split of platform and non-platform policy on device, however, will necessitate the loading of two disparate policy files. Rather than combining the files and then calling the existing API on a newly-formed file, just add the ability to specify multiple files to use. Order of opt specification to selabel_open matters.
This corresponds to AOSP commit 50400d38203e4db08314168e60c281cc61a717a8, which lead to a fork with upstream, which we'd like to correct.
--- libselinux/src/label.c | 21 +++++--- libselinux/src/label_file.c | 104 +++++++++++++++++++++++++++++----------- libselinux/src/label_internal.h | 5 +- 3 files changed, 94 insertions(+), 36 deletions(-)
libselinux/src/label.c +15 -6
@@ -143,7 +143,11 @@ static int selabel_fini(struct selabel_handle *rec,struct selabel_lookup_rec *lr, int translating) { - if (compat_validate(rec, lr, rec->spec_file, 0)) + char *path = NULL; + +if (rec->spec_files) + path = rec->spec_files[0 ]; +if (compat_validate (rec, lr, path,0 ))return -1 ; if (translating && !lr->ctx_trans &&
@@ -226,11 +230,9 @@ struct selabel_handle *selabel_open(unsigned int backend, rec->digest =selabel_is_digest_set (opts, nopts, rec->digest);if ((*initfuncs[backend])(rec, opts, nopts)) { -free (rec->spec_file); -free (rec); +selabel_close (rec); rec =NULL ; } - out:return rec; }
@@ -337,10 +339,17 @@ int selabel_digest(struct selabel_handle *rec,void selabel_close (struct selabel_handle *rec) { +size_t i; + +if (rec->spec_files) { +for (i =0 ; i < rec->spec_files_len; i++) +free (rec->spec_files[i]); +free (rec->spec_files); + }if (rec->digest)selabel_digest_fini (rec->digest); - rec->func_close (rec); -free (rec->spec_file); +if (rec->func_close) + rec->func_close (rec);free (rec); }
libselinux/src/label_file.c +76 -28
153 lines not on this page · raw message
libselinux/src/label_internal.h +3 -2
@@ -98,10 +98,11 @@ struct selabel_handle {void *data;/* -* The main spec file used. Note for file contexts the local and/or +* The main spec file(s) used. Note for file contexts the local and/or * homedirs could also have been used to resolve a context. */ -char *spec_file; +size_t spec_files_len; +char **spec_files;/* ptr to SHA1 hash information if SELABEL_OPT_DIGEST set */ struct selabel_digest *digest;
Signature · 1 line
2.14.1.581.gf28d330327-goog
Quoted 124 lines · Daniel Cashman
From: Dan Cashman <[email protected]>
The
file_contextslabeling backend, specified inlabel_file.c, currently assumes
that only one path will be specified as an option toselabel_open(). The split
of platform and non-platform policy on device, however, will necessitate the
loading of two disparate policy files. Rather than combining the files and then
calling the existing API on a newly-formed file, just add the ability to specify
multiple files to use. Order of opt specification toselabel_openmatters.This corresponds to AOSP commit
50400d38203e4db08314168e60c281cc61a717a8, which
lead to a fork with upstream, which we'd like to correct.Signed-off-by Dan Cashman <[email protected]>--- libselinux/src/label.c | 21 +++++--- libselinux/src/label_file.c | 104 +++++++++++++++++++++++++++++- ---------- libselinux/src/label_internal.h | 5 +- 3 files changed, 94 insertions(+), 36 deletions(-)libselinux/src/label.c +6
-4@@ -143,7 +143,11 @@ static int selabel_fini(struct selabel_handle *rec,struct selabel_lookup_rec *lr, int translating) { - if (compat_validate(rec, lr, rec->spec_file, 0)) + char *path = NULL; + +if (rec->spec_files) + path = rec->spec_files[0 ]; +if (compat_validate (rec, lr, path,0 ))return -1 ; if (translating && !lr->ctx_trans &&@@ -226,11 +230,9 @@ struct selabel_handle *selabel_open(unsigned int backend, rec->digest =selabel_is_digest_set (opts, nopts, rec->digest);if ((*initfuncs[backend])(rec, opts, nopts)) { -free (rec->spec_file); -free (rec); +selabel_close (rec); rec =NULL ; } - out:return rec;}
libselinux/src/label.c +9
-2@@ -337,10 +339,17 @@ int selabel_digest(struct selabel_handle *rec,void selabel_close (struct selabel_handle *rec) { +size_t i; + +if (rec->spec_files) { +for (i =0 ; i < rec->spec_files_len; i++) +free (rec->spec_files[i]); +free (rec->spec_files); + }if (rec->digest)selabel_digest_fini (rec->digest); - rec->func_close (rec); -free (rec->spec_file); +if (rec->func_close) + rec->func_close (rec);free (rec); }libselinux/src/label_file.c +20
-7@@ -709,28 +709,61 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, unsigned n) {struct saved_data *data = (struct saved_data *)rec->data; -const char *path =NULL ; +size_t num_paths =0 ; +char **path =NULL ;const char *prefix =NULL ; -int status =-1 , baseonly =0 ; +int status =-1 ; +size_t i; +bool baseonly = false; +bool path_provided;/* Process arguments */ -while (n--) -switch (opts[n].type) { + i = n; +while (i--) +switch (opts[i].type) {case SELABEL_OPT_PATH : - path = opts[n].value; + num_paths++;break ;case SELABEL_OPT_SUBSET : - prefix = opts[n].value; + prefix = opts[i].value;break ;case SELABEL_OPT_BASEONLY : - baseonly = !!opts[n].value; + baseonly = !!opts[i].value;break ; } +if (!num_paths) { + num_paths =1 ; + path_provided = false; + }else { + path_provided = true; + } + + path =calloc (num_paths,sizeof (*path));
libselinux/src/label_file.c static int init(struct selabel_handle *rec, const · line 753
Quoted 10 lines
libselinux/src/label_file.c +9
-0+if (path ==NULL ) { + goto finish; + } + rec->spec_files = path; + rec->spec_files_len = num_paths; + +if (path_provided) { +for (i =0 ; i < n; i++) { +switch (opts[i].type) {
Weird way to do an if/else?
Quoted 134 lines
libselinux/src/label_file.c +12
-1+case SELABEL_OPT_PATH : + *path =strdup (opts[i].value); +if (*path ==NULL ) + goto finish; + path++; +break ; +default : +break ; + } + } + }#if !defined(BUILD_HOST ) && !defined(ANDROID )char subs_file[PATH_MAX +1 ];/* Process local and distribution substitution files */ -if (!path) { +if (!path_provided) { status = selabel_subs_init(selinux_file_context_subs_dist_path(), rec->digest, &data->dist_subs);libselinux/src/label_file.c +28
-19@@ -740,43 +773,52 @@ static int init(struct selabel_handle *rec, conststruct selinux_opt *opts, rec->digest, &data->subs);if (status) goto finish; - path = selinux_file_context_path(); + rec->spec_files[0 ] =strdup (selinux_file_context_path ()); +if (rec->spec_files[0 ] ==NULL ) + goto finish; } else { -snprintf (subs_file,sizeof (subs_file),"%s.subs_dist" , path); - status =selabel_subs_init (subs_file, rec->digest, +for (i =0 ; i < num_paths; i++) { +snprintf (subs_file,sizeof (subs_file),"%s.subs_dist" , rec->spec_files[i]); + status =selabel_subs_init (subs_file, rec->digest, &data->dist_subs); -if (status) - goto finish; -snprintf (subs_file,sizeof (subs_file),"%s.subs" , path); - status =selabel_subs_init (subs_file, rec->digest, +if (status) + goto finish; +snprintf (subs_file,sizeof (subs_file),"%s.subs" , rec->spec_files[i]); + status =selabel_subs_init (subs_file, rec->digest, &data->subs); -if (status) - goto finish; +if (status) + goto finish; + } + } +#else +if (!path_provided) { +selinux_log (SELINUX_ERROR ,"No path given to file labeling backend\n"); + goto finish; } -#endif - rec->spec_file =strdup (path);/* -* The do detailed validation of the input and fill the spec array +* Do detailed validation of the input and fill the spec array */ - status =process_file (path,NULL , rec, prefix, rec->digest); -if (status) - goto finish; - -if (rec->validating) { - status =nodups_specs (data, path); +for (i =0 ; i < num_paths; i++) { + status =process_file (rec->spec_files[i],NULL , rec, prefix, rec->digest);if (status) goto finish; + +if (rec->validating) { + status =nodups_specs (data, rec->spec_files[i]); +if (status) + goto finish; + } }if (!baseonly) { - status =process_file (path,"homedirs" , rec, prefix, + status =process_file (rec->spec_files[0 ],"homedirs" , rec, prefix, rec->digest);if (status && errno != ENOENT) goto finish;libselinux/src/label_file.c +1
-1- status = process_file(path, "local", rec, prefix, + status = process_file(rec->spec_files[0], "local", rec,prefix,
rec->digest); if (status && errno != ENOENT) goto finish;libselinux/src/label_file.c +6
-0@@ -804,6 +846,12 @@ static void closef(struct selabel_handle *rec)struct stem *stem;unsigned int i; +if (!data) +return ; + +/* make sure successive ->func_close() calls are harmless */ + rec->data =NULL ; +selabel_subs_fini (data->subs);selabel_subs_fini (data->dist_subs);libselinux/src/label_ renamed from libselinux/src/label_internal.h +0
-0
internal.h
indexc55efb75..43b63513100644libselinux/src/label_internal.h +1
-1@@ -98,10 +98,11 @@ struct selabel_handle {void *data;/* -* The main spec file used. Note for file contexts the local and/or +* The main spec file(s) used. Note for file contexts the local and/or
* homedirs could also have been used to resolve a context. */libselinux/src/label_internal.h +2
-2-char *spec_file; +size_t spec_files_len; +char **spec_files;/* ptr to SHA1 hash information if SELABEL_OPT_DIGEST set */ struct selabel_digest *digest; --
Quoted 3 lines
2.14.1.581.gf28d330327-goog
all in all, I have no major gripes with this. Ack.
Quoted 15 lines · Daniel Cashman
From: Dan Cashman <[email protected]>
The
file_contextslabeling backend, specified inlabel_file.c, currently assumes
that only one path will be specified as an option to selabel_open(). The split
of platform and non-platform policy on device, however, will necessitate the
loading of two disparate policy files. Rather than combining the files and then
calling the existing API on a newly-formed file, just add the ability to specify
multiple files to use. Order of opt specification toselabel_openmatters.
Quoted 3 lines
This corresponds to AOSP commit
50400d38203e4db08314168e60c281cc61a717a8, which lead to a fork with upstream, which we'd like to correct.
We need to update the other label backends as well, at least sufficiently to still build, even if they only support a single path.
Quoted 262 lines
Signed-off-by Dan Cashman <[email protected]>---
libselinux/src/label.c | 21 +++++--- libselinux/src/label_file.c | 104 +++++++++++++++++++++++++++++-
----------
libselinux/src/label_internal.h | 5 +-3 files changed, 94 insertions(+), 36 deletions(-)libselinux/src/label.c +5
-1@@ -143,7 +143,11 @@ static int selabel_fini(struct selabel_handle *rec, struct selabel_lookup_rec *lr, int translating) { -if (compat_validate (rec, lr, rec->spec_file,0 )) +char *path =NULL ; + +if (rec->spec_files) + path = rec->spec_files[0 ]; +if (compat_validate (rec, lr, path,0 )) return -1;
if (translating && !lr->ctx_trans &&libselinux/src/label.c +0
-0@@ -226,11 +230,9 @@ struct selabel_handle *selabel_open(unsigned int backend,
rec->digest= selabel_is_digest_set(opts, nopts, rec-Quoted 1 line
digest);
if ((*initfuncs[backend])(rec, opts, nopts)) {libselinux/src/label.c +1
-2-free (rec->spec_file); -free (rec); +selabel_close (rec);rec = NULL;
}
-
out:
return rec;
}libselinux/src/label.c +0
-0@@ -337,10 +339,17 @@ int selabel_digest(struct selabel_handle *rec,
voidselabel_close(struct selabel_handle *rec)
{libselinux/src/label.c +7
-0+size_t i; + +if (rec->spec_files) { +for (i =0 ; i < rec->spec_files_len; i++) +free (rec->spec_files[i]); +free (rec->spec_files); + }if (
rec->digest)
selabel_digest_fini(rec->digest);libselinux/src/label.c +2
-2- rec->func_close (rec); -free (rec->spec_file); +if (rec->func_close) + rec->func_close (rec);free(rec);
}libselinux/src/label_file.c +6
-2@@ -709,28 +709,61 @@ static int init(struct selabel_handle *rec,const struct selinux_opt *opts, unsigned n) { struct saved_data *data = (struct saved_data *)rec->data; -const char *path =NULL ; +size_t num_paths =0 ; +char **path =NULL ; const char *prefix = NULL; -int status =-1 , baseonly =0 ; +int status =-1 ; +size_t i; +bool baseonly = false; +bool path_provided;
/* Process arguments */libselinux/src/label_file.c +3
-2-while (n--) -switch (opts[n].type) { + i = n; +while (i--) +switch (opts[i].type) {case
SELABEL_OPT_PATH:libselinux/src/label_file.c +1
-1- path = opts[n].value; + num_paths++;break;
caseSELABEL_OPT_SUBSET:libselinux/src/label_file.c +1
-1- prefix = opts[n].value; + prefix = opts[i].value;break;
caseSELABEL_OPT_BASEONLY:libselinux/src/label_file.c +1
-1- baseonly = !!opts[n].value; + baseonly = !!opts[i].value;break;
}libselinux/src/label_file.c +28
-0+if (!num_paths) { + num_paths =1 ; + path_provided = false; + }else { + path_provided = true; + } + + path =calloc (num_paths,sizeof (*path)); +if (path ==NULL ) { + goto finish; + } + rec->spec_files = path; + rec->spec_files_len = num_paths; + +if (path_provided) { +for (i =0 ; i < n; i++) { +switch (opts[i].type) { +case SELABEL_OPT_PATH : + *path =strdup (opts[i].value); +if (*path ==NULL ) + goto finish; + path++; +break ; +default : +break ; + } + } + }#if !defined(BUILD_HOST) && !defined(ANDROID)
char subs_file[PATH_MAX + 1];
/* Process local and distribution substitution files */libselinux/src/label_file.c +1
-1-if (!path) { +if (!path_provided) {status =
selabel_subs_init( selinux_file_context_subs_dist_path(), rec->digest, &data->dist_subs);libselinux/src/label_file.c +18
-11@@ -740,43 +773,52 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, rec->digest, &data->subs); if (status) goto finish; - path =selinux_file_context_path (); + rec->spec_files[0] = strdup(selinux_file_context_path()); + if (rec->spec_files[0] == NULL) + goto finish; } else { -snprintf (subs_file,sizeof (subs_file), "%s.subs_dist", path); - status =selabel_subs_init (subs_file, rec->digest, + for (i = 0; i < num_paths; i++) { + snprintf(subs_file, sizeof(subs_file), "%s.subs_dist", rec->spec_files[i]); + status = selabel_subs_init(subs_file, rec- >digest, &data->dist_subs); -if (status) - goto finish; -snprintf (subs_file,sizeof (subs_file),"%s.subs" , path); - status =selabel_subs_init (subs_file, rec->digest, + if (status) + goto finish; + snprintf(subs_file, sizeof(subs_file), "%s.subs", rec->spec_files[i]); + status = selabel_subs_init(subs_file, rec- >digest, &data->subs); -if (status) - goto finish; + if (status) + goto finish; + } + } +#else + if (!path_provided) { + selinux_log(SELINUX_ERROR, "No path given to file labeling backend\n"); + goto finish; } - #endif - rec->spec_file =strdup (path);
/*libselinux/src/label_file.c +0
-1- * The do detailed validation of the input and fill the specarray
libselinux/src/label_file.c +1
-0+ * Do detailed validation of the input and fill the specarray
*/libselinux/src/label_file.c +2
-6- status =process_file (path,NULL , rec, prefix, rec->digest); -if (status) - goto finish; - -if (rec->validating) { - status =nodups_specs (data, path); +for (i =0 ; i < num_paths; i++) { + status = process_file(rec->spec_files[i], NULL, rec,prefix,
rec->digest);
if (status)
goto finish;libselinux/src/label_file.c +3
-0+ +if (rec->validating) { + status = nodups_specs(data, rec-Quoted 1 line
spec_files[i]);
libselinux/src/label_file.c +3
-0+if (status) + goto finish; + }}
if (!baseonly) {libselinux/src/label_file.c +1
-1- status = process_file(path, "homedirs", rec, prefix, + status = process_file(rec->spec_files[0],"homedirs", rec, prefix,
rec-Quoted 1 line
digest);
if (status && errno != ENOENT)
goto finish;libselinux/src/label_file.c +1
-1- status = process_file(path, "local", rec, prefix, + status = process_file(rec->spec_files[0], "local",rec, prefix,
rec-Quoted 1 line
digest);
if (status && errno != ENOENT)
goto finish;libselinux/src/label_file.c +0
-0@@ -804,6 +846,12 @@ static void closef(struct selabel_handle *rec) struct stem *stem; unsigned int i;libselinux/src/label_file.c +6
-0+if (!data) +return ; + +/* make sure successive ->func_close() calls are harmless */ + rec->data =NULL ; +
selabel_subs_fini(data->subs);
selabel_subs_fini(data->dist_subs);libselinux/src/label_internal.h +0
-0@@ -98,10 +98,11 @@ struct selabel_handle { void *data;
/*libselinux/src/label_internal.h +0
-1- * The main spec file used. Note for file contexts the localand/or
libselinux/src/label_internal.h +1
-0+ * The main spec file(s) used. Note for file contexts thelocal and/or
* homedirs could also have been used to resolve a context. */libselinux/src/label_internal.h +2
-1-char *spec_file; +size_t spec_files_len; +char **spec_files;
/* ptr to SHA1 hash information ifSELABEL_OPT_DIGESTset */ structselabel_digest*digest;
PATCH 1/1 selinux: libselinux: Enable multiple input files to selabel_open.
From: Dan Cashman <[email protected]>
The file_contexts labeling backend, specified in label_file.c, currently assumes that only one path will be specified as an option to selabel_open(). The split of platform and non-platform policy on device, however, will necessitate the loading of two disparate policy files. Rather than combining the files and then calling the existing API on a newly-formed file, just add the ability to specify multiple files to use. Order of opt specification to selabel_open matters.
This corresponds to AOSP commit 50400d38203e4db08314168e60c281cc61a717a8, which lead to a fork with upstream, which we'd like to correct.
--- libselinux/src/label.c | 21 +++++--- libselinux/src/label_db.c | 4 +- libselinux/src/label_file.c | 104 +++++++++++++++++++++++++++++----------- libselinux/src/label_internal.h | 5 +- libselinux/src/label_media.c | 4 +- libselinux/src/label_x.c | 4 +- 6 files changed, 103 insertions(+), 39 deletions(-)
libselinux/src/label.c +15 -6
@@ -143,7 +143,11 @@ static int selabel_fini(struct selabel_handle *rec,struct selabel_lookup_rec *lr, int translating) { - if (compat_validate(rec, lr, rec->spec_file, 0)) + char *path = NULL; + +if (rec->spec_files) + path = rec->spec_files[0 ]; +if (compat_validate (rec, lr, path,0 ))return -1 ; if (translating && !lr->ctx_trans &&
@@ -226,11 +230,9 @@ struct selabel_handle *selabel_open(unsigned int backend, rec->digest =selabel_is_digest_set (opts, nopts, rec->digest);if ((*initfuncs[backend])(rec, opts, nopts)) { -free (rec->spec_file); -free (rec); +selabel_close (rec); rec =NULL ; } - out:return rec; }
@@ -337,10 +339,17 @@ int selabel_digest(struct selabel_handle *rec,void selabel_close (struct selabel_handle *rec) { +size_t i; + +if (rec->spec_files) { +for (i =0 ; i < rec->spec_files_len; i++) +free (rec->spec_files[i]); +free (rec->spec_files); + }if (rec->digest)selabel_digest_fini (rec->digest); - rec->func_close (rec); -free (rec->spec_file); +if (rec->func_close) + rec->func_close (rec);free (rec); }
libselinux/src/label_db.c +3 -1
@@ -290,7 +290,9 @@ db_init(const struct selinux_opt *opts, unsigned nopts, errno =EINVAL ;return NULL ; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);/* * Parse for each lines
libselinux/src/label_file.c +76 -28
153 lines not on this page · raw message
libselinux/src/label_internal.h +3 -2
@@ -98,10 +98,11 @@ struct selabel_handle {void *data;/* -* The main spec file used. Note for file contexts the local and/or +* The main spec file(s) used. Note for file contexts the local and/or * homedirs could also have been used to resolve a context. */ -char *spec_file; +size_t spec_files_len; +char **spec_files;/* ptr to SHA1 hash information if SELABEL_OPT_DIGEST set */ struct selabel_digest *digest;
libselinux/src/label_media.c +3 -1
@@ -100,7 +100,9 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, errno =EINVAL ;return -1 ; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);/* * Perform two passes over the specification file.
libselinux/src/label_x.c +3 -1
@@ -127,7 +127,9 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, errno =EINVAL ;return -1 ; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);/* * Perform two passes over the specification file.
Signature · 1 line
2.14.2.920.gcf0c67979c-goog
Quoted 286 lines · Daniel Cashman
From: Dan Cashman <[email protected]>
The
file_contextslabeling backend, specified inlabel_file.c, currently assumes that only one path will be specified as an option toselabel_open(). The split of platform and non-platform policy on device, however, will necessitate the loading of two disparate policy files. Rather than combining the files and then calling the existing API on a newly-formed file, just add the ability to specify multiple files to use. Order of opt specification toselabel_openmatters.This corresponds to AOSP commit
50400d38203e4db08314168e60c281cc61a717a8, which lead to a fork with upstream, which we'd like to correct.Signed-off-by Dan Cashman <[email protected]>--- libselinux/src/label.c | 21 +++++--- libselinux/src/label_db.c | 4 +- libselinux/src/label_file.c | 104 +++++++++++++++++++++++++++++----------- libselinux/src/label_internal.h | 5 +- libselinux/src/label_media.c | 4 +- libselinux/src/label_x.c | 4 +- 6 files changed, 103 insertions(+), 39 deletions(-)libselinux/src/label.c +15
-6@@ -143,7 +143,11 @@ static int selabel_fini(struct selabel_handle *rec,struct selabel_lookup_rec *lr, int translating) { - if (compat_validate(rec, lr, rec->spec_file, 0)) + char *path = NULL; + +if (rec->spec_files) + path = rec->spec_files[0 ]; +if (compat_validate (rec, lr, path,0 ))return -1 ; if (translating && !lr->ctx_trans &&@@ -226,11 +230,9 @@ struct selabel_handle *selabel_open(unsigned int backend, rec->digest =selabel_is_digest_set (opts, nopts, rec->digest);if ((*initfuncs[backend])(rec, opts, nopts)) { -free (rec->spec_file); -free (rec); +selabel_close (rec); rec =NULL ; } - out:return rec; }@@ -337,10 +339,17 @@ int selabel_digest(struct selabel_handle *rec,void selabel_close (struct selabel_handle *rec) { +size_t i; + +if (rec->spec_files) { +for (i =0 ; i < rec->spec_files_len; i++) +free (rec->spec_files[i]); +free (rec->spec_files); + }if (rec->digest)selabel_digest_fini (rec->digest); - rec->func_close (rec); -free (rec->spec_file); +if (rec->func_close) + rec->func_close (rec);free (rec); }libselinux/src/label_db.c +3
-1@@ -290,7 +290,9 @@ db_init(const struct selinux_opt *opts, unsigned nopts, errno =EINVAL ;return NULL ; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);/* * Parse for each lines libselinux/src/label_file.c +76
-28@@ -709,28 +709,61 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, unsigned n) {struct saved_data *data = (struct saved_data *)rec->data; -const char *path =NULL ; +size_t num_paths =0 ; +char **path =NULL ;const char *prefix =NULL ; -int status =-1 , baseonly =0 ; +int status =-1 ; +size_t i; +bool baseonly = false; +bool path_provided;/* Process arguments */ -while (n--) -switch (opts[n].type) { + i = n; +while (i--) +switch (opts[i].type) {case SELABEL_OPT_PATH : - path = opts[n].value; + num_paths++;break ;case SELABEL_OPT_SUBSET : - prefix = opts[n].value; + prefix = opts[i].value;break ;case SELABEL_OPT_BASEONLY : - baseonly = !!opts[n].value; + baseonly = !!opts[i].value;break ; } +if (!num_paths) { + num_paths =1 ; + path_provided = false; + }else { + path_provided = true; + } + + path =calloc (num_paths,sizeof (*path)); +if (path ==NULL ) { + goto finish; + } + rec->spec_files = path; + rec->spec_files_len = num_paths; + +if (path_provided) { +for (i =0 ; i < n; i++) { +switch (opts[i].type) { +case SELABEL_OPT_PATH : + *path =strdup (opts[i].value); +if (*path ==NULL ) + goto finish; + path++; +break ; +default : +break ; + } + } + }#if !defined(BUILD_HOST ) && !defined(ANDROID )char subs_file[PATH_MAX +1 ];/* Process local and distribution substitution files */ -if (!path) { +if (!path_provided) { status =selabel_subs_init (selinux_file_context_subs_dist_path (), rec->digest, &data->dist_subs);@@ -740,43 +773,52 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, rec->digest, &data->subs);if (status) goto finish; - path = selinux_file_context_path(); + rec->spec_files[0 ] =strdup (selinux_file_context_path ()); +if (rec->spec_files[0 ] ==NULL ) + goto finish; } else { -snprintf (subs_file,sizeof (subs_file),"%s.subs_dist" , path); - status =selabel_subs_init (subs_file, rec->digest, +for (i =0 ; i < num_paths; i++) { +snprintf (subs_file,sizeof (subs_file),"%s.subs_dist" , rec->spec_files[i]); + status =selabel_subs_init (subs_file, rec->digest, &data->dist_subs); -if (status) - goto finish; -snprintf (subs_file,sizeof (subs_file),"%s.subs" , path); - status =selabel_subs_init (subs_file, rec->digest, +if (status) + goto finish; +snprintf (subs_file,sizeof (subs_file),"%s.subs" , rec->spec_files[i]); + status =selabel_subs_init (subs_file, rec->digest, &data->subs); -if (status) - goto finish; +if (status) + goto finish; + } + } +#else +if (!path_provided) { +selinux_log (SELINUX_ERROR ,"No path given to file labeling backend\n" ); + goto finish; } -#endif - rec->spec_file =strdup (path);/* -* The do detailed validation of the input and fill the spec array +* Do detailed validation of the input and fill the spec array */ - status =process_file (path,NULL , rec, prefix, rec->digest); -if (status) - goto finish; - -if (rec->validating) { - status =nodups_specs (data, path); +for (i =0 ; i < num_paths; i++) { + status =process_file (rec->spec_files[i],NULL , rec, prefix, rec->digest);if (status) goto finish; + +if (rec->validating) { + status =nodups_specs (data, rec->spec_files[i]); +if (status) + goto finish; + } }if (!baseonly) { - status =process_file (path,"homedirs" , rec, prefix, + status =process_file (rec->spec_files[0 ],"homedirs" , rec, prefix, rec->digest);if (status && errno !=ENOENT ) goto finish; - status =process_file (path,"local" , rec, prefix, + status =process_file (rec->spec_files[0 ],"local" , rec, prefix, rec->digest);if (status && errno !=ENOENT ) goto finish;@@ -804,6 +846,12 @@ static void closef(struct selabel_handle *rec)struct stem *stem;unsigned int i; +if (!data) +return ; + +/* make sure successive ->func_close() calls are harmless */ + rec->data =NULL ; +selabel_subs_fini (data->subs);selabel_subs_fini (data->dist_subs);libselinux/src/label_internal.h +3
-2@@ -98,10 +98,11 @@ struct selabel_handle {void *data;/* -* The main spec file used. Note for file contexts the local and/or +* The main spec file(s) used. Note for file contexts the local and/or * homedirs could also have been used to resolve a context. */ -char *spec_file; +size_t spec_files_len; +char **spec_files;/* ptr to SHA1 hash information if SELABEL_OPT_DIGEST set */ struct selabel_digest *digest;libselinux/src/label_media.c +3
-1@@ -100,7 +100,9 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, errno =EINVAL ;return -1 ; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);/* * Perform two passes over the specification file. libselinux/src/label_x.c +0
-0
libselinux/src/label_x.c static int init(struct selabel_handle *rec, const struct selinux_opt *opts, · line 135
Quoted 10 lines
libselinux/src/label_x.c +3
-1@@ -127,7 +127,9 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, errno =EINVAL ;return -1 ; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);/* * Perform two passes over the specification file.
Sorry, I completely overlooked the non-compilation of the other backends. I actually would like to see us integrate the upstream
tests and build so that we're not just flying by the android build system, but for now I think this is all that is required. I'll be sending a follow-up patch for the android backends that is basically AOSP commit: c75d01302f68d7714235600bd5b237bae2e8b893.
Thanks,
Dan
Quoted 36 lines · Daniel Cashman
From: Dan Cashman <[email protected]>
The
file_contextslabeling backend, specified inlabel_file.c, currently assumes
that only one path will be specified as an option to selabel_open(). The split
of platform and non-platform policy on device, however, will necessitate the
loading of two disparate policy files. Rather than combining the files and then
calling the existing API on a newly-formed file, just add the ability to specify
multiple files to use. Order of opt specification toselabel_openmatters.This corresponds to AOSP commit
50400d38203e4db08314168e60c281cc61a717a8, which lead to a fork with upstream, which we'd like to correct.Signed-off-by Dan Cashman <[email protected]>---
libselinux/src/label.c | 21 +++++--- libselinux/src/label_db.c | 4 +- libselinux/src/label_file.c | 104 +++++++++++++++++++++++++++++-
----------
libselinux/src/label_internal.h | 5 +- libselinux/src/label_media.c | 4 +- libselinux/src/label_x.c | 4 +-6 files changed, 103 insertions(+), 39 deletions(-)libselinux/src/label_db.c +0
-0
libselinux/src/label_db.c db_init(const struct selinux_opt *opts, unsigned · line 295
Quoted 7 lines
libselinux/src/label_db.c +2
-1@@ -290,7 +290,9 @@ db_init(const struct selinux_opt *opts, unsigned nopts, errno = EINVAL; return NULL; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path))
Missing semicolon, and a check for NULL. Also should likely be sizeof(rec->spec_files[0]) or sizeof(char *); path isn't really relevant here.
libselinux/src/label_db.c db_init(const struct selinux_opt *opts, unsigned · line 296
Quoted 1 line
libselinux/src/label_db.c +1
-0+ rec->spec_files[0 ] =strdup (path);
Ditto, although I see you didn't introduce that per se; we ought to fix it anyway.
Quoted 6 lines
libselinux/src/label_media.c +0
-0
libselinux/src/label_media.c static int init(struct selabel_handle *rec, const · line 106
Quoted 8 lines
libselinux/src/label_media.c +3
-1@@ -100,7 +100,9 @@ static int init(struct selabel_handle *rec, conststruct selinux_opt *opts, errno = EINVAL; return -1; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);
Same as for label_db.c.
Quoted 8 lines
/*
* Perform two passes over the specification file.libselinux/src/label_x.c +0
-0
libselinux/src/label_x.c static int init(struct selabel_handle *rec, const · line 133
Quoted 8 lines
libselinux/src/label_x.c +3
-1@@ -127,7 +127,9 @@ static int init(struct selabel_handle *rec, conststruct selinux_opt *opts, errno = EINVAL; return -1; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);
And again.
Quoted 3 lines
/*
* Perform two passes over the specification file.
Quoted 81 lines · Stephen Smalley
Quoted 36 lines · Daniel Cashman
From: Dan Cashman <[email protected]>
The
file_contextslabeling backend, specified inlabel_file.c, currently assumes
that only one path will be specified as an option to selabel_open(). The split
of platform and non-platform policy on device, however, will necessitate the
loading of two disparate policy files. Rather than combining the files and then
calling the existing API on a newly-formed file, just add the ability to specify
multiple files to use. Order of opt specification toselabel_openmatters.This corresponds to AOSP commit
50400d38203e4db08314168e60c281cc61a717a8, which lead to a fork with upstream, which we'd like to correct.Signed-off-by Dan Cashman <[email protected]>--- libselinux/src/label.c | 21 +++++--- libselinux/src/label_db.c | 4 +- libselinux/src/label_file.c | 104 +++++++++++++++++++++++++++++- ---------- libselinux/src/label_internal.h | 5 +- libselinux/src/label_media.c | 4 +- libselinux/src/label_x.c | 4 +- 6 files changed, 103 insertions(+), 39 deletions(-)libselinux/src/label_db.c +0
-0libselinux/src/label_db.c db_init(const struct selinux_opt *opts, unsigned · line 295
Quoted 7 lines
libselinux/src/label_db.c +2
-1@@ -290,7 +290,9 @@ db_init(const struct selinux_opt *opts, unsigned nopts, errno = EINVAL; return NULL; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path))Missing semicolon, and a check for NULL. Also should likely be
sizeof(rec->spec_files[0])orsizeof(char *); path isn't really relevant here.libselinux/src/label_db.c db_init(const struct selinux_opt *opts, unsigned · line 296
Quoted 1 line
libselinux/src/label_db.c +1
-0+ rec->spec_files[0 ] =strdup (path);Ditto, although I see you didn't introduce that per se; we ought to fix it anyway.
Quoted 6 lines
libselinux/src/label_media.c +0
-0libselinux/src/label_media.c static int init(struct selabel_handle *rec, const · line 106
Quoted 8 lines
libselinux/src/label_media.c +3
-1@@ -100,7 +100,9 @@ static int init(struct selabel_handle *rec, conststruct selinux_opt *opts, errno = EINVAL; return -1; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);Same as for
label_db.c.Quoted 10 lines
libselinux/src/label_media.c +0
-0/** Perform two passes over the specification file. libselinux/src/label_x.c +0
-0@@ -127,7 +127,9 @@ static int init(struct selabel_handle *rec, conststruct selinux_opt *opts, errno = EINVAL;
Quoted 12 lines
libselinux/src/label_x.c static int init(struct selabel_handle *rec, const · line 133
Quoted 6 lines
libselinux/src/label_x.c +3
-1return -1; } - rec->spec_file =strdup (path); + rec->spec_files_len =1 ; + rec->spec_files =calloc (rec->spec_files_len,sizeof (path)) + rec->spec_files[0] = strdup(path);And again.
Quoted 3 lines
libselinux/src/label_x.c +0
-0/** Perform two passes over the specification file.
Well that was embarrassing. Twice bitten, thrice shy? I've now setup a fedora vm to at least test whether or not patches will build, so that's a good outcome of this. Submitted v3 to the list (rather than continuing this thread). Thanks for the review!
-Dan