Re: [RFC PATCH v2 13/27] libselinux/utils: introduce selabel_compare

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Aug 14, 2023 at 9:42 AM Christian Göttsche
<cgzones@xxxxxxxxxxxxxx> wrote:
>
> Add a utility around selabel_cmp(3).
>
> Can be used by users to compare a pre-compiled fcontext file to an
> original text-based file context definition file.
>
> Can be used for development to verify compilation and parsing of the
> pre-compiled fcontext format works correctly.
>
> Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx>
> ---
>  libselinux/utils/.gitignore        |   1 +
>  libselinux/utils/selabel_compare.c | 119 +++++++++++++++++++++++++++++
>  2 files changed, 120 insertions(+)
>  create mode 100644 libselinux/utils/selabel_compare.c
>
> diff --git a/libselinux/utils/.gitignore b/libselinux/utils/.gitignore
> index a92e1e94..4e2dfba8 100644
> --- a/libselinux/utils/.gitignore
> +++ b/libselinux/utils/.gitignore
> @@ -16,6 +16,7 @@ getseuser
>  matchpathcon
>  policyvers
>  sefcontext_compile
> +selabel_compare
>  selabel_digest
>  selabel_get_digests_all_partial_matches
>  selabel_lookup
> diff --git a/libselinux/utils/selabel_compare.c b/libselinux/utils/selabel_compare.c
> new file mode 100644
> index 00000000..f4325f7e
> --- /dev/null
> +++ b/libselinux/utils/selabel_compare.c
> @@ -0,0 +1,119 @@
> +#include <getopt.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include <selinux/label.h>
> +
> +
> +static void usage(const char *progname)
> +{
> +       fprintf(stderr,
> +               "usage: %s [-b backend] [-v] file1 file2\n\n"
> +               "Where:\n\t"
> +               "-b           The backend - \"file\", \"media\", \"x\", \"db\" or \"prop\" (defaults to \"file\")\n\t"
> +               "-v           Validate entries against loaded policy.\n\t"
> +               "file1/file2  Files containing the specs.\n",
> +               progname);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +       unsigned int backend = SELABEL_CTX_FILE;
> +       int opt;
> +       const char *validate = NULL, *file1 = NULL, *file2 = NULL;
> +
> +       if (argc < 3) {
> +               usage(argv[0]);
> +               return EXIT_FAILURE;
> +       }
> +
> +       while ((opt = getopt(argc, argv, "b:v")) > 0) {
> +               switch (opt) {
> +               case 'b':
> +                       if (!strcasecmp(optarg, "file")) {
> +                               backend = SELABEL_CTX_FILE;
> +                       } else if (!strcmp(optarg, "media")) {
> +                               backend = SELABEL_CTX_MEDIA;
> +                       } else if (!strcmp(optarg, "x")) {
> +                               backend = SELABEL_CTX_X;
> +                       } else if (!strcmp(optarg, "db")) {
> +                               backend = SELABEL_CTX_DB;
> +                       } else if (!strcmp(optarg, "prop")) {
> +                               backend = SELABEL_CTX_ANDROID_PROP;
> +                       } else if (!strcmp(optarg, "service")) {
> +                               backend = SELABEL_CTX_ANDROID_SERVICE;
> +                       } else {
> +                               fprintf(stderr, "Unknown backend: %s\n", optarg);
> +                               usage(argv[0]);
> +                               return EXIT_FAILURE;
> +                       }
> +                       break;
> +               case 'v':
> +                       validate = (char *)1;
> +                       break;
> +               default:
> +                       usage(argv[0]);
> +                       return EXIT_FAILURE;
> +               }
> +       }
> +
> +       if (argc != optind + 2) {
> +               usage(argv[0]);
> +               return EXIT_FAILURE;
> +       }
> +
> +       file1 = argv[optind++];
> +       file2 = argv[optind];
> +
> +       {

To me, having a block like this means that the stuff below should be
in a helper function.

Everything else looks good.
Jim


> +               struct selabel_handle *hnd1, *hnd2;
> +               const struct selinux_opt selabel_option1[] = {
> +                       { SELABEL_OPT_PATH, file1 },
> +                       { SELABEL_OPT_VALIDATE, validate }
> +               };
> +               const struct selinux_opt selabel_option2[] = {
> +                       { SELABEL_OPT_PATH, file2 },
> +                       { SELABEL_OPT_VALIDATE, validate }
> +               };
> +               enum selabel_cmp_result result;
> +
> +               hnd1 = selabel_open(backend, selabel_option1, 2);
> +               if (!hnd1) {
> +                       fprintf(stderr, "ERROR: selabel_open - Could not obtain handle for %s:  %m\n", file1);
> +                       return EXIT_FAILURE;
> +               }
> +
> +               hnd2 = selabel_open(backend, selabel_option2, 2);
> +               if (!hnd2) {
> +                       fprintf(stderr, "ERROR: selabel_open - Could not obtain handle for %s:  %m\n", file2);
> +                       selabel_close(hnd1);
> +                       return EXIT_FAILURE;
> +               }
> +
> +               result = selabel_cmp(hnd1, hnd2);
> +
> +               selabel_close(hnd2);
> +               selabel_close(hnd1);
> +
> +               switch (result) {
> +               case SELABEL_SUBSET:
> +                       printf("spec %s is a subset of spec %s\n", file1, file2);
> +                       break;
> +               case SELABEL_EQUAL:
> +                       printf("spec %s is equal to spec %s\n", file1, file2);
> +                       break;
> +               case SELABEL_SUPERSET:
> +                       printf("spec %s is a superset of spec %s\n", file1, file2);
> +                       break;
> +               case SELABEL_INCOMPARABLE:
> +                       printf("spec %s is uncompareable to spec %s\n", file1, file2);
> +                       break;
> +               default:
> +                       fprintf(stderr, "ERROR: selabel_cmp - Unexpected result %d\n", result);
> +                       return EXIT_FAILURE;
> +               }
> +
> +               return EXIT_SUCCESS;
> +       }
> +}
> --
> 2.40.1
>




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux