parser: Add option --Werror to enable turning warnings into errors

Add basic ability to treat a warning as an error and abort the compile
by specifying the new option --Werror.

  --Werror

will turn all warnings into errors. Where if an warning type is
specified only that type of warning will be turned into an error.

  --Werror=deprecated.

The full list of supported warning types can be found by using

     apparmor_parser --help=warn
   or
     apparmor_parser --help=Werror

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/600
Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2020-08-28 11:38:12 -07:00
parent f5c4927c85
commit 343024b4a3
4 changed files with 49 additions and 7 deletions

View file

@ -295,7 +295,7 @@ Report on the profiles as they are loaded, and show warnings.
=item --warn=n
Enable various warnings during policy compilation. A single dump flag
Enable various warnings during policy compilation. A single warn flag
can be specified per --warn option, but the --warn flag can be passed
multiple times.
@ -303,6 +303,19 @@ multiple times.
Use --help=warn to see a full list of which warn flags are supported.
=item --Werror[=n]
Convert warnings into errors during policy compilation. If the
optional flag is not specified all warnings become errors. If the
optional flag is specified only the class of warnings specified will
become errors. A single flag can be specified per --Werror option, but
the --Werror flag can be passed multiple times.
apparmor_parser --Werror=deprecated ...
Use --help=warn or --help=Werror to see a full list of which warn flags
are supported.
=item -d, --debug
Given once, only checks the profiles to ensure syntactic correctness.

View file

@ -79,6 +79,7 @@ extern int parser_token;
WARN_UNEXPECTED | WARN_FORMAT | WARN_MISSING | WARN_OVERRIDE)
extern dfaflags_t warnflags;
extern dfaflags_t werrflags;
typedef enum pattern_t pattern_t;
@ -351,10 +352,10 @@ extern char *profile_ns;
extern char *current_filename;
extern FILE *ofile;
extern int read_implies_exec;
extern void pwarnf(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
extern void pwarnf(bool werr, const char *fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
extern void common_warn_once(const char *name, const char *msg, const char **warned_name);
#define pwarn(F, args...) do { if (warnflags & (F)) pwarnf(args); } while (0)
#define pwarn(F, args...) do { if (warnflags & (F)) pwarnf((werrflags & (F)), ## args); } while (0)
/* from parser_main (cannot be used in tst builds) */
extern int force_complain;

View file

@ -85,6 +85,7 @@ int option = OPTION_ADD;
dfaflags_t dfaflags = (dfaflags_t)(DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | DFA_CONTROL_MINIMIZE | DFA_CONTROL_DIFF_ENCODE);
dfaflags_t warnflags = DEFAULT_WARNINGS;
dfaflags_t werrflags = 0;
const char *progname = __FILE__;
char *profile_ns = NULL;
@ -99,7 +100,7 @@ int read_implies_exec = 1;
int read_implies_exec = 0;
#endif
void pwarnf(const char *fmt, ...)
void pwarnf(bool werr, const char *fmt, ...)
{
va_list arg;
char *newfmt;
@ -107,7 +108,8 @@ void pwarnf(const char *fmt, ...)
if (conf_quiet || names_only || option == OPTION_REMOVE)
return;
if (asprintf(&newfmt, _("Warning from %s (%s%sline %d): %s"),
if (asprintf(&newfmt, _("%s from %s (%s%sline %d): %s"),
werr ? _("Warning converted to Error") : _("Warning"),
profilename ? profilename : "stdin",
current_filename ? current_filename : "",
current_filename ? " " : "",
@ -120,13 +122,22 @@ void pwarnf(const char *fmt, ...)
va_end(arg);
free(newfmt);
if (werr) {
fflush(stderr);
exit(1);
}
}
/* do we want to warn once/profile or just once per compile?? */
void common_warn_once(const char *name, const char *msg, const char **warned_name)
{
if ((warnflags & WARN_RULE_NOT_ENFORCED) && *warned_name != name) {
cerr << "Warning from profile " << name << " (";
if (werrflags & WARN_RULE_NOT_ENFORCED)
cerr << "Warning converted to Error";
else
cerr << "Warning";
cerr << " from profile " << name << " (";
if (current_filename)
cerr << current_filename;
else
@ -134,4 +145,7 @@ void common_warn_once(const char *name, const char *msg, const char **warned_nam
cerr << "): " << msg << "\n";
*warned_name = name;
}
if (werrflags & WARN_RULE_NOT_ENFORCED)
exit(1);
}

View file

@ -128,6 +128,7 @@ static const char *config_file = "/etc/apparmor/parser.conf";
#define ARG_PRINT_CONFIG_FILE 140
#define ARG_OVERRIDE_POLICY_ABI 141
#define EARLY_ARG_CONFIG_FILE 142
#define ARG_WERROR 143
/* Make sure to update BOTH the short and long_options */
static const char *short_options = "ad::f:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:j:";
@ -172,6 +173,7 @@ struct option long_options[] = {
{"abort-on-error", 0, 0, ARG_ABORT_ON_ERROR}, /* no short option */
{"skip-bad-cache-rebuild", 0, 0, ARG_SKIP_BAD_CACHE_REBUILD},/* no short option */
{"warn", 1, 0, ARG_WARN}, /* no short option */
{"Werror", 2, 0, ARG_WERROR},
{"debug-cache", 0, 0, ARG_DEBUG_CACHE}, /* no short option */
{"max-jobs", 1, 0, ARG_MAX_JOBS}, /* no short option */
{"print-cache-dir", 0, 0, ARG_PRINT_CACHE_DIR}, /* no short option */
@ -242,6 +244,7 @@ static void display_usage(const char *command)
"--config-file n Specify the parser config file location, processed early before other options.\n"
"--print-config Print config file location\n"
"--warn n Enable warnings (see --help=warn)\n"
"--Werror [n] Convert warnings to errors. If n is specified turn warn n into an error\n"
,command);
}
@ -471,7 +474,8 @@ static int process_arg(int c, char *optarg)
strcmp(optarg, "optimize") == 0 ||
strcmp(optarg, "O") == 0) {
display_optimize(progname);
} else if (strcmp(optarg, "warn") == 0) {
} else if (strcmp(optarg, "warn") == 0 ||
strcmp(optarg, "Werror") == 0) {
display_warn(progname);
} else {
PERROR("%s: Invalid --help option %s\n",
@ -696,6 +700,16 @@ static int process_arg(int c, char *optarg)
exit(1);
}
break;
case ARG_WERROR:
if (!optarg) {
werrflags = -1;
} else if (optarg && !handle_flag_table(warnflag_table, optarg,
&werrflags)) {
PERROR("%s: Invalid --Werror option %s\n",
progname, optarg);
exit(1);
}
break;
case ARG_DEBUG_CACHE:
warnflags |= WARN_DEBUG_CACHE;
break;