Re: [RFC PATCH 3/4] semodule_package: update

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

 



On Fri, Jun 9, 2023 at 3:32 PM James Carter <jwcart2@xxxxxxxxx> wrote:
>
> On Fri, May 12, 2023 at 7:25 AM Christian Göttsche
> <cgzones@xxxxxxxxxxxxxx> wrote:
> >
> > Drop unnecessary declarations.
> > Add missing error messages.
> > More strict command line argument parsing.
> > Check closing file for incomplete write.
> > Rework resource cleanup, so that all files and allocated memory are
> > released in all branches, useful to minimize reports while debugging
> > libsepol under valgrind(8) or sanitizers.
> >
> > Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx>
> > ---
> >  .../semodule_package/semodule_package.c       | 203 +++++++++++-------
> >  1 file changed, 125 insertions(+), 78 deletions(-)
> >
> > diff --git a/semodule-utils/semodule_package/semodule_package.c b/semodule-utils/semodule_package/semodule_package.c
> > index bc8584b5..7485e254 100644
> > --- a/semodule-utils/semodule_package/semodule_package.c
> > +++ b/semodule-utils/semodule_package/semodule_package.c
> > @@ -19,8 +19,7 @@
> >  #include <fcntl.h>
> >  #include <errno.h>
> >
> > -char *progname = NULL;
> > -extern char *optarg;
> > +static const char *progname = NULL;

I forgot to ask if this global can be removed as well.

Thanks,
Jim

> >
> >  static __attribute__((__noreturn__)) void usage(const char *prog)
> >  {
> > @@ -37,26 +36,6 @@ static __attribute__((__noreturn__)) void usage(const char *prog)
> >         exit(1);
>
> Same comment as patch 1 about "exit(1)".
>
> >  }
> >
> > -static int file_to_policy_file(const char *filename, struct sepol_policy_file **pf,
> > -                              const char *mode)
> > -{
> > -       FILE *f;
> > -
> > -       if (sepol_policy_file_create(pf)) {
> > -               fprintf(stderr, "%s:  Out of memory\n", progname);
> > -               return -1;
> > -       }
> > -
> > -       f = fopen(filename, mode);
> > -       if (!f) {
> > -               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
> > -                       strerror(errno), filename);
> > -               return -1;
> > -       }
> > -       sepol_policy_file_set_fp(*pf, f);
> > -       return 0;
> > -}
> > -
> >  static int file_to_data(const char *path, char **data, size_t * len)
> >  {
> >         int fd;
> > @@ -94,17 +73,18 @@ static int file_to_data(const char *path, char **data, size_t * len)
> >
> >  int main(int argc, char **argv)
> >  {
> > -       struct sepol_module_package *pkg;
> > -       struct sepol_policy_file *mod, *out;
> > +       struct sepol_module_package *pkg = NULL;
> > +       struct sepol_policy_file *mod = NULL, *out = NULL;
> > +       FILE *fp = NULL;
> >         char *module = NULL, *file_contexts = NULL, *seusers =
> >             NULL, *user_extra = NULL;
> >         char *fcdata = NULL, *outfile = NULL, *seusersdata =
> >             NULL, *user_extradata = NULL;
> >         char *netfilter_contexts = NULL, *ncdata = NULL;
> >         size_t fclen = 0, seuserslen = 0, user_extralen = 0, nclen = 0;
> > -       int i;
> > +       int i, ret;
> >
> > -       static struct option opts[] = {
> > +       const struct option opts[] = {
> >                 {"module", required_argument, NULL, 'm'},
> >                 {"fc", required_argument, NULL, 'f'},
> >                 {"seuser", required_argument, NULL, 's'},
> > @@ -115,11 +95,12 @@ int main(int argc, char **argv)
> >                 {NULL, 0, NULL, 0}
> >         };
> >
> > +       progname = argv[0];
> > +
> >         while ((i = getopt_long(argc, argv, "m:f:s:u:o:n:h", opts, NULL)) != -1) {
> >                 switch (i) {
> >                 case 'h':
> > -                       usage(argv[0]);
> > -                       exit(0);
> > +                       usage(progname);
> >                 case 'm':
> >                         if (module) {
> >                                 fprintf(stderr,
> > @@ -127,8 +108,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         module = strdup(optarg);
> > -                       if (!module)
> > +                       if (!module) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 'f':
> >                         if (file_contexts) {
> > @@ -137,8 +120,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         file_contexts = strdup(optarg);
> > -                       if (!file_contexts)
> > +                       if (!file_contexts) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 'o':
> >                         if (outfile) {
> > @@ -147,8 +132,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         outfile = strdup(optarg);
> > -                       if (!outfile)
> > +                       if (!outfile) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 's':
> >                         if (seusers) {
> > @@ -157,8 +144,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         seusers = strdup(optarg);
> > -                       if (!seusers)
> > +                       if (!seusers) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 'u':
> >                         if (user_extra) {
> > @@ -167,8 +156,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         user_extra = strdup(optarg);
> > -                       if (!user_extra)
> > +                       if (!user_extra) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 'n':
> >                         if (netfilter_contexts) {
> > @@ -177,88 +168,144 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         netfilter_contexts = strdup(optarg);
> > -                       if (!netfilter_contexts)
> > +                       if (!netfilter_contexts) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> > +               case '?':
> > +                       usage(progname);
>
> What is this option "?" for?
>
> > +               default:
> > +                       fprintf(stderr, "%s:  Unsupported getopt return code: %d\n", progname, i);
> > +                       usage(progname);
>
> Why not just default to calling usage() without the error message?
>
> >                 }
> >         }
> >
> > -       progname = argv[0];
> > -
> > -       if (!module || !outfile) {
> > -               usage(argv[0]);
> > -               exit(0);
> > +       if (optind < argc) {
> > +               fprintf(stderr, "%s:  Superfluous command line arguments: ", progname);
> > +                while (optind < argc)
> > +                        fprintf(stderr, "%s ", argv[optind++]);
> > +               fprintf(stderr, "\n");
> > +               usage(progname);
> >         }
> >
> > -       if (file_contexts) {
> > -               if (file_to_data(file_contexts, &fcdata, &fclen))
> > -                       exit(1);
> > -       }
> > +       if (!module || !outfile)
> > +               usage(progname);
> >
> > -       if (seusers) {
> > -               if (file_to_data(seusers, &seusersdata, &seuserslen))
> > -                       exit(1);
> > -       }
> > +       if (file_contexts && file_to_data(file_contexts, &fcdata, &fclen))
> > +               goto failure;
> >
> > -       if (user_extra) {
> > -               if (file_to_data(user_extra, &user_extradata, &user_extralen))
> > -                       exit(1);
> > -       }
> > +       if (seusers && file_to_data(seusers, &seusersdata, &seuserslen))
> > +               goto failure;
> > +
> > +       if (user_extra && file_to_data(user_extra, &user_extradata, &user_extralen))
> > +               goto failure;
> >
> > -       if (netfilter_contexts) {
> > -               if (file_to_data(netfilter_contexts, &ncdata, &nclen))
> > -                       exit(1);
> > +       if (netfilter_contexts && file_to_data(netfilter_contexts, &ncdata, &nclen))
> > +               goto failure;
> > +
> > +       if (sepol_policy_file_create(&mod)) {
> > +               fprintf(stderr, "%s:  Out of memory\n", progname);
> > +               goto failure;
> >         }
> >
> > -       if (file_to_policy_file(module, &mod, "r"))
> > -               exit(1);
> > +       fp = fopen(module, "r");
> > +       if (!fp) {
> > +               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
> > +                       module, strerror(errno));
> > +               goto failure;
> > +       }
> > +       sepol_policy_file_set_fp(mod, fp);
> >
> >         if (sepol_module_package_create(&pkg)) {
> >                 fprintf(stderr, "%s:  Out of memory\n", argv[0]);
> > -               exit(1);
> > +               goto failure;
> >         }
> >
> >         if (sepol_policydb_read(sepol_module_package_get_policy(pkg), mod)) {
> >                 fprintf(stderr,
> >                         "%s:  Error while reading policy module from %s\n",
> >                         argv[0], module);
> > -               exit(1);
> > +               goto failure;
> >         }
> >
> > -       if (fclen)
> > -               sepol_module_package_set_file_contexts(pkg, fcdata, fclen);
> > +       fclose(fp);
> > +       fp = NULL;
> >
> > -       if (seuserslen)
> > -               sepol_module_package_set_seusers(pkg, seusersdata, seuserslen);
> > +       if (fclen && sepol_module_package_set_file_contexts(pkg, fcdata, fclen)) {
> > +               fprintf(stderr, "%s:  Error while setting file contexts\n", progname);
> > +               goto failure;
> > +       }
> >
> > -       if (user_extra)
> > -               sepol_module_package_set_user_extra(pkg, user_extradata,
> > -                                                   user_extralen);
> > +       if (seuserslen && sepol_module_package_set_seusers(pkg, seusersdata, seuserslen)) {
> > +               fprintf(stderr, "%s:  Error while setting seusers\n", progname);
> > +               goto failure;
> > +       }
> >
> > -       if (nclen)
> > -               sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen);
> > +       if (user_extra && sepol_module_package_set_user_extra(pkg, user_extradata, user_extralen)) {
> > +               fprintf(stderr, "%s:  Error while setting extra users\n", progname);
> > +               goto failure;
> > +       }
> > +
> > +       if (nclen && sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen)) {
> > +               fprintf(stderr, "%s:  Error while setting netfilter contexts\n", progname);
> > +               goto failure;
> > +       }
> > +
> > +       if (sepol_policy_file_create(&out)) {
> > +               fprintf(stderr, "%s:  Out of memory\n", progname);
> > +               goto failure;
> > +       }
> >
> > -       if (file_to_policy_file(outfile, &out, "w"))
> > -               exit(1);
> > +       fp = fopen(outfile, "w");
> > +       if (!fp) {
> > +               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
> > +                       outfile, strerror(errno));
> > +               goto failure;
> > +       }
> > +       sepol_policy_file_set_fp(out, fp);
> >
> >         if (sepol_module_package_write(pkg, out)) {
> >                 fprintf(stderr,
> >                         "%s:  Error while writing module package to %s\n",
> >                         argv[0], argv[1]);
> > -               exit(1);
> > +               goto failure;
> >         }
> >
> > -       if (fclen)
> > -               munmap(fcdata, fclen);
> > +       ret = fclose(fp);
> > +       fp = NULL;
> > +       if (ret) {
> > +               fprintf(stderr, "%s:  Could not close file %s:  %s\n", progname,
> > +                       outfile, strerror(errno));
> > +               goto failure;
> > +       }
> > +
> > +       ret = EXIT_SUCCESS;
> > +
> > +cleanup:
> > +       if (fp)
> > +               fclose(fp);
> > +       sepol_policy_file_free(out);
> >         if (nclen)
> >                 munmap(ncdata, nclen);
> > -       sepol_policy_file_free(mod);
> > -       sepol_policy_file_free(out);
> > +       if (user_extradata)
> > +               munmap(user_extradata, user_extralen);
> > +       if (seuserslen)
> > +               munmap(seusersdata, seuserslen);
> > +       if (fclen)
> > +               munmap(fcdata, fclen);
> >         sepol_module_package_free(pkg);
> > -       free(file_contexts);
> > +       sepol_policy_file_free(mod);
> > +       free(netfilter_contexts);
> > +       free(user_extra);
> > +       free(seusers);
> >         free(outfile);
> > +       free(file_contexts);
> >         free(module);
> > -       free(seusers);
> > -       free(user_extra);
> > -       exit(0);
> > +
> > +       return ret;
> > +
> > +failure:
> > +       ret = EXIT_FAILURE;
> > +       goto cleanup;
>
> Same as the comment for patch 1 about preferring "return ret" to be at the end.
>
> Thanks,
> Jim
>
> >  }
> > --
> > 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