From nobody Fri Apr 14 05:14:48 2023 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4PyPlD3BjYz45R2H; Fri, 14 Apr 2023 05:14:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4PyPlD2NYQz3CFw; Fri, 14 Apr 2023 05:14:48 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1681449288; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3TqbcOyfWlpRGhtoo14U2wn5ZxJZk8FaZsFrZ3vP/RM=; b=QcTUqvEZb4b68dpRwVwasgttnEYUN+1w7cwiwkR71MS9UvGyT87Q2o9UBHxcnjdaxFOjUH +Z7uix7NHaL28y83+X4XGvEHzAKw1WyEWVgG7j+kXicS5krdiy5cezPLvq3nFtVcVIWgmu qYcexaEvzCtIVetwmrJTeuZ8jDIRvYfyq/R7FsgdBJJ2D69fdmj0JDFPJjeWcWAA4tTySc 9pgBESjrzXxpELpQh5t1VrZjYVD1iezvURNu/gu7U1tPRhxcBZd+o62F2FvSGNt5ZbjCK6 XNVyF/26g9R2+pdfjMQcPvU4ihYaEJf1LZNzJGNDS0WztvXNlK4X3nVB5GIO1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1681449288; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3TqbcOyfWlpRGhtoo14U2wn5ZxJZk8FaZsFrZ3vP/RM=; b=wszC9jMqqJT8vsDFVKnO603YRQb38qFZmaAThtoObtp/dCfgDe+Eqs3ANOo2cOy3jLBOVv qCoxV60Ig4eLPdfUIBg4Hv7E+E4CxJMjBkBJdzsTeg+KlAJTD/iEPIsABY6SkgMPRsSXB9 X7NHYqvNixTO6hsnReWeLBcIf7T6hBiXcBEbc9b+5bSTNKMoBsecDtoBe451b4rhzz/lGK 9usjDFY8fsoaeLydXMFxELUGKoaqBFuu7eOTw9RibJQlOyiDeHHkFRBK1hSkBpH3DrAxse 8gDuoeH0w8/u25j+Ar2LHl228gRk+pgRS0+0obJrCgvRfZRUdeyoEvqFRoRzXg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1681449288; a=rsa-sha256; cv=none; b=Ik/Rm3Hb5H2y1t8F3JEX9piKIkPrZWsHFiD/RgFvf8WGhDTJgltu45LwGJo/M+UoVVvDVj ms+JHUgr6lKNcgxB/TIAQ242vHK3SLWsxUK+snRIU2uSPLTrdQRzQIVkFdq0R5Xf02o4Gk Mf8oqsmjVzHN3gNrN7R9LVnDQ/anbVAYIR743D6RJxcWIAGNytHzNWYcSceEznqWQRROIb l6fqF2y3RaipcnJdVEWWN2sepep9kvh7ZWVBfWQBjcecTl/s2sNOdNPard/cc5BPp1ukiw 3MldonxvjadvYabY5qRN7CLrZUF3ysMTXZayzdTPvQHt62v+TMR6RWiHKYsMhw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4PyPlD1LMqz1B9J; Fri, 14 Apr 2023 05:14:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 33E5EmFK019844; Fri, 14 Apr 2023 05:14:48 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 33E5Emre019843; Fri, 14 Apr 2023 05:14:48 GMT (envelope-from git) Date: Fri, 14 Apr 2023 05:14:48 GMT Message-Id: <202304140514.33E5Emre019843@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Gordon Bergling Subject: git: e2e6c643408f - stable/13 - Improve parameters handling in veriexec List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: gbe X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: e2e6c643408fd2a0a17980d9d2bc3a071faf6830 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by gbe: URL: https://cgit.FreeBSD.org/src/commit/?id=e2e6c643408fd2a0a17980d9d2bc3a071faf6830 commit e2e6c643408fd2a0a17980d9d2bc3a071faf6830 Author: Hubert Mazur AuthorDate: 2022-06-29 08:55:51 +0000 Commit: Gordon Bergling CommitDate: 2023-04-14 05:14:27 +0000 Improve parameters handling in veriexec Provide more robust parameter parsing in veriexec. Do a little cleanup as well. Differential revision: https://reviews.freebsd.org/D33246 Obtained from: Semihalf Reviewed by: sjg, sebastien.bini_stormshield.eu (cherry picked from commit b439f64ac1b953936a89167f0201d0d53cc90197) --- sbin/veriexec/veriexec.c | 210 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 151 insertions(+), 59 deletions(-) diff --git a/sbin/veriexec/veriexec.c b/sbin/veriexec/veriexec.c index 1eb7a9af7d6f..aff514b1cac5 100644 --- a/sbin/veriexec/veriexec.c +++ b/sbin/veriexec/veriexec.c @@ -33,16 +33,36 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "veriexec.h" +/* Globals that are shared with manifest_parser.c */ int dev_fd = -1; int ForceFlags = 0; int Verbose = 0; int VeriexecVersion = 0; - const char *Cdir = NULL; +/*! + * @brief Print help message describing program's usage + * @param void + * @return always returns code 0 + */ +static int +veriexec_usage() +{ + printf("%s", + "Usage:\tveriexec [-h] [-i state] [-C] [-xv state|verbosity] [path]\n"); + + return (0); +} + +/*! + * @brief Load a veriexec manifest + * @param manifest Pointer to the location of the manifest file + * @retval the error code returned from the parser + */ static int veriexec_load(const char *manifest) { @@ -52,7 +72,7 @@ veriexec_load(const char *manifest) content = verify_signed(manifest, VEF_VERBOSE); if (!content) errx(EX_USAGE, "cannot verify %s", manifest); - if (manifest_open(manifest, content)) { + if (manifest_open(manifest, (const char *)content)) { rc = yyparse(); } else { err(EX_NOINPUT, "cannot load %s", manifest); @@ -61,21 +81,87 @@ veriexec_load(const char *manifest) return (rc); } +/*! + * @brief Get the veriexec state for the supplied argument + * @param arg_text String containing the argument to be processed + * @retval The veriexec state number for the specified argument + */ +static uint32_t +veriexec_state_query(const char *arg_text) +{ + uint32_t state = 0; + unsigned long len; + + len = strlen(arg_text); + + if (strncmp(arg_text, "active", len) == 0) + state |= VERIEXEC_STATE_ACTIVE; + else if (strncmp(arg_text, "enforce", len) == 0) + state |= VERIEXEC_STATE_ENFORCE; + if (strncmp(arg_text, "loaded", len) == 0) + state |= VERIEXEC_STATE_LOADED; + if (strncmp(arg_text, "locked", len) == 0) + state |= VERIEXEC_STATE_LOCKED; + if (state == 0 || __bitcount(state) > 1) + errx(EX_USAGE, "Unknown state \'%s\'", arg_text); + + return (state); +} + +/*! + * @brief Get the veriexec command state for the supplied argument + * @param arg_text String containing the argument to be processed + * @retval The veriexec command state for the specified argument + */ +static uint32_t +veriexec_state_modify(const char *arg_text) +{ + uint32_t state = 0; + unsigned long len; + + len = strlen(arg_text); + + if (strncmp(arg_text, "active", len) == 0) + state = VERIEXEC_ACTIVE; + else if (strncmp(arg_text, "enforce", len) == 0) + state = VERIEXEC_ENFORCE; + else if (strncmp(arg_text, "getstate", len) == 0) + state = VERIEXEC_GETSTATE; + else if (strncmp(arg_text, "lock", len) == 0) + state = VERIEXEC_LOCK; + else + errx(EX_USAGE, "Unknown command \'%s\'", arg_text); + + return (state); +} + int main(int argc, char *argv[]) { - unsigned long ctl; - int c; + long long converted_int; + uint32_t state; + char c; int x; + if (argc < 2) + return (veriexec_usage()); + dev_fd = open(_PATH_DEV_VERIEXEC, O_WRONLY, 0); - while ((c = getopt(argc, argv, "C:i:xvz:")) != -1) { + while ((c = getopt(argc, argv, "hC:i:xvz:")) != -1) { switch (c) { + case 'h': + /* Print usage info */ + + return (veriexec_usage()); case 'C': + /* Get the provided directory argument */ + Cdir = optarg; break; case 'i': + /* Query the current state */ + if (dev_fd < 0) { err(EX_UNAVAILABLE, "cannot open veriexec"); } @@ -83,32 +169,23 @@ main(int argc, char *argv[]) err(EX_UNAVAILABLE, "Cannot get veriexec state"); } - switch (optarg[0]) { - case 'a': /* active */ - ctl = VERIEXEC_STATE_ACTIVE; - break; - case 'e': /* enforce */ - ctl = VERIEXEC_STATE_ENFORCE; - break; - case 'l': /* loaded/locked */ - ctl = (strncmp(optarg, "lock", 4) == 0) ? - VERIEXEC_STATE_LOCKED : - VERIEXEC_STATE_LOADED; - break; - default: - errx(EX_USAGE, "unknown state %s", optarg); - break; - } - exit((x & ctl) == 0); + + state = veriexec_state_query(optarg); + + exit((x & state) == 0); break; case 'v': + /* Increase the verbosity */ + Verbose++; break; case 'x': + /* Check veriexec paths */ + /* * -x says all other args are paths to check. */ - for (x = 0; optind < argc; optind++) { + for (x = EX_OK; optind < argc; optind++) { if (veriexec_check_path(argv[optind])) { warn("%s", argv[optind]); x = 2; @@ -117,48 +194,63 @@ main(int argc, char *argv[]) exit(x); break; case 'z': - switch (optarg[0]) { - case 'a': /* active */ - ctl = VERIEXEC_ACTIVE; - break; - case 'd': /* debug* */ - ctl = (strstr(optarg, "off")) ? - VERIEXEC_DEBUG_OFF : VERIEXEC_DEBUG_ON; - if (optind < argc && ctl == VERIEXEC_DEBUG_ON) { - x = atoi(argv[optind]); + /* Modify the state */ + + if (strncmp(optarg, "debug", strlen(optarg)) == 0) { + const char *error; + + if (optind >= argc) + errx(EX_USAGE, + "Missing mac_veriexec verbosity level \'N\', veriexec -z debug N, where N is \'off\' or the value 0 or greater"); + + if (strncmp(argv[optind], "off", strlen(argv[optind])) == 0) { + state = VERIEXEC_DEBUG_OFF; + x = 0; + } else { + state = VERIEXEC_DEBUG_ON; + + converted_int = strtonum(argv[optind], 0, INT_MAX, &error); + + if (error != NULL) + errx(EX_USAGE, "Conversion error for argument \'%s\' : %s", + argv[optind], error); + + x = (int) converted_int; + + if (x == 0) - ctl = VERIEXEC_DEBUG_OFF; + state = VERIEXEC_DEBUG_OFF; } - break; - case 'e': /* enforce */ - ctl = VERIEXEC_ENFORCE; - break; - case 'g': - ctl = VERIEXEC_GETSTATE; /* get state */ - break; - case 'l': /* lock */ - ctl = VERIEXEC_LOCK; - break; - default: - errx(EX_USAGE, "unknown command %s", optarg); - break; - } - if (dev_fd < 0) { - err(EX_UNAVAILABLE, "cannot open veriexec"); - } - if (ioctl(dev_fd, ctl, &x)) { - err(EX_UNAVAILABLE, "cannot %s veriexec", optarg); - } - if (ctl == VERIEXEC_DEBUG_ON || - ctl == VERIEXEC_DEBUG_OFF) { - printf("debug is: %d\n", x); - } else if (ctl == VERIEXEC_GETSTATE) { - printf("%#o\n", x); - } + } else + state = veriexec_state_modify(optarg); + + if (dev_fd < 0) + err(EX_UNAVAILABLE, "Cannot open veriexec"); + if (ioctl(dev_fd, state, &x)) + err(EX_UNAVAILABLE, "Cannot %s veriexec", optarg); + + if (state == VERIEXEC_DEBUG_ON || state == VERIEXEC_DEBUG_OFF) + printf("mac_veriexec debug verbosity level: %d\n", x); + else if (state == VERIEXEC_GETSTATE) + printf("Veriexec state (octal) : %#o\n", x); + exit(EX_OK); break; + default: + + /* Missing argument, print usage info.*/ + veriexec_usage(); + exit(EX_USAGE); + break; } } + + if (Verbose) + printf("Verbosity level : %d\n", Verbose); + + if (dev_fd < 0) + err(EX_UNAVAILABLE, "Cannot open veriexec"); + openlog(getprogname(), LOG_PID, LOG_AUTH); if (ve_trust_init() < 1) errx(EX_OSFILE, "cannot initialize trust store");