From patchwork Thu Apr 28 06:53:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laszlo Ersek X-Patchwork-Id: 12830056 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90DCEC433F5 for ; Thu, 28 Apr 2022 06:54:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244659AbiD1G53 (ORCPT ); Thu, 28 Apr 2022 02:57:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244618AbiD1G5Y (ORCPT ); Thu, 28 Apr 2022 02:57:24 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id A8FFF985B2 for ; Wed, 27 Apr 2022 23:54:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1651128849; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kIz0Cu4Ol620es4MTJLbyzZp+QPTEI2gwSpjPd+S0kY=; b=DYN8pyTlvPgkXgeegUBpoVUZ/1qtOdcRgrl723c5HdOMbuQXhAIzsUeLgL+cvCNmNuOX6v VagW6ahbGsDdiA4zZOKJRVKLnAGqtXU3wawLZHnO46F22sP/x1JRwY6X3Lb6v7S0lqhZkZ bP/4A56MLWS2bkgsLdbphRQwAfJ1cJY= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-507-L8bo9p8MOeeOt7fud5ECWA-1; Thu, 28 Apr 2022 02:54:08 -0400 X-MC-Unique: L8bo9p8MOeeOt7fud5ECWA-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 37DF31C08543 for ; Thu, 28 Apr 2022 06:54:08 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (unknown [10.39.192.29]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4B158416385; Thu, 28 Apr 2022 06:54:07 +0000 (UTC) From: Laszlo Ersek To: SELinux List , Laszlo Ersek Cc: "Richard W.M. Jones" , Petr Lautrbach Subject: [PATCH for-3.5 5/5] setfiles: introduce the -C option for distinguishing file tree walk errors Date: Thu, 28 Apr 2022 08:53:54 +0200 Message-Id: <20220428065354.27605-6-lersek@redhat.com> In-Reply-To: <20220428065354.27605-1-lersek@redhat.com> References: <20220428065354.27605-1-lersek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org setfiles(8) exits with status 255 if it encounters any error. Introduce the "-C" option: if the only errors that setfiles(8) encounters are labeling errors seen during the file tree walk(s), then let setfiles(8) exit with status 1. Cc: "Richard W.M. Jones" Cc: Petr Lautrbach Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518 Signed-off-by: Laszlo Ersek --- policycoreutils/setfiles/restore.h | 4 +++- policycoreutils/setfiles/restore.c | 8 +++++-- policycoreutils/setfiles/setfiles.c | 19 +++++++++++------ policycoreutils/setfiles/setfiles.8 | 22 ++++++++++++++++++++ 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/policycoreutils/setfiles/restore.h b/policycoreutils/setfiles/restore.h index bb35a1db9e34..a5af81fe3bb4 100644 --- a/policycoreutils/setfiles/restore.h +++ b/policycoreutils/setfiles/restore.h @@ -35,6 +35,7 @@ struct restore_opts { unsigned int ignore_noent; unsigned int ignore_mounts; unsigned int conflict_error; + unsigned int count_errors; /* restorecon_flags holds | of above for restore_init() */ unsigned int restorecon_flags; char *rootpath; @@ -49,7 +50,8 @@ struct restore_opts { void restore_init(struct restore_opts *opts); void restore_finish(void); void add_exclude(const char *directory); -int process_glob(char *name, struct restore_opts *opts, size_t nthreads); +int process_glob(char *name, struct restore_opts *opts, size_t nthreads, + long unsigned *skipped_errors); extern char **exclude_list; #endif diff --git a/policycoreutils/setfiles/restore.c b/policycoreutils/setfiles/restore.c index e9ae33ad039a..6131f46a7523 100644 --- a/policycoreutils/setfiles/restore.c +++ b/policycoreutils/setfiles/restore.c @@ -41,7 +41,8 @@ void restore_init(struct restore_opts *opts) opts->xdev | opts->abort_on_error | opts->syslog_changes | opts->log_matches | opts->ignore_noent | opts->ignore_mounts | - opts->mass_relabel | opts->conflict_error; + opts->mass_relabel | opts->conflict_error | + opts->count_errors; /* Use setfiles, restorecon and restorecond own handles */ selinux_restorecon_set_sehandle(opts->hnd); @@ -72,7 +73,8 @@ void restore_finish(void) } } -int process_glob(char *name, struct restore_opts *opts, size_t nthreads) +int process_glob(char *name, struct restore_opts *opts, size_t nthreads, + long unsigned *skipped_errors) { glob_t globbuf; size_t i = 0; @@ -96,6 +98,8 @@ int process_glob(char *name, struct restore_opts *opts, size_t nthreads) nthreads); if (rc < 0) errors = rc; + else if (opts->restorecon_flags & SELINUX_RESTORECON_COUNT_ERRORS) + *skipped_errors += selinux_restorecon_get_skipped_errors(); } globfree(&globbuf); diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c index aeec1fdcc2ab..4dd0d0dc3835 100644 --- a/policycoreutils/setfiles/setfiles.c +++ b/policycoreutils/setfiles/setfiles.c @@ -40,8 +40,8 @@ static __attribute__((__noreturn__)) void usage(const char *const name) name, name); } else { fprintf(stderr, - "usage: %s [-diIDlmnpqvEFWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file pathname...\n" - "usage: %s [-diIDlmnpqvEFWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file -f filename\n" + "usage: %s [-diIDlmnpqvCEFWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file pathname...\n" + "usage: %s [-diIDlmnpqvCEFWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file -f filename\n" "usage: %s -s [-diIDlmnpqvFWT] spec_file\n", name, name, name); } @@ -150,9 +150,10 @@ int main(int argc, char **argv) const char *base; int errors = 0; const char *ropts = "e:f:hiIDlmno:pqrsvFRW0xT:"; - const char *sopts = "c:de:f:hiIDlmno:pqr:svEFR:W0T:"; + const char *sopts = "c:de:f:hiIDlmno:pqr:svCEFR:W0T:"; const char *opts; union selinux_callback cb; + long unsigned skipped_errors; /* Initialize variables */ memset(&r_opts, 0, sizeof(r_opts)); @@ -161,6 +162,7 @@ int main(int argc, char **argv) warn_no_match = 0; request_digest = 0; policyfile = NULL; + skipped_errors = 0; if (!argv[0]) { fprintf(stderr, "Called without required program name!\n"); @@ -288,6 +290,9 @@ int main(int argc, char **argv) r_opts.syslog_changes = SELINUX_RESTORECON_SYSLOG_CHANGES; break; + case 'C': + r_opts.count_errors = SELINUX_RESTORECON_COUNT_ERRORS; + break; case 'E': r_opts.conflict_error = SELINUX_RESTORECON_CONFLICT_ERROR; @@ -447,13 +452,15 @@ int main(int argc, char **argv) buf[len - 1] = 0; if (!strcmp(buf, "/")) r_opts.mass_relabel = SELINUX_RESTORECON_MASS_RELABEL; - errors |= process_glob(buf, &r_opts, nthreads) < 0; + errors |= process_glob(buf, &r_opts, nthreads, + &skipped_errors) < 0; } if (strcmp(input_filename, "-") != 0) fclose(f); } else { for (i = optind; i < argc; i++) - errors |= process_glob(argv[i], &r_opts, nthreads) < 0; + errors |= process_glob(argv[i], &r_opts, nthreads, + &skipped_errors) < 0; } maybe_audit_mass_relabel(r_opts.mass_relabel, errors); @@ -467,5 +474,5 @@ int main(int argc, char **argv) if (r_opts.progress) fprintf(stdout, "\n"); - exit(errors ? -1 : 0); + exit(errors ? -1 : skipped_errors ? 1 : 0); } diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8 index 19b59a2cc90d..bf26e161a71d 100644 --- a/policycoreutils/setfiles/setfiles.8 +++ b/policycoreutils/setfiles/setfiles.8 @@ -6,6 +6,7 @@ setfiles \- set SELinux file security contexts. .B setfiles .RB [ \-c .IR policy ] +.RB [ \-C ] .RB [ \-d ] .RB [ \-l ] .RB [ \-m ] @@ -58,6 +59,13 @@ option will force a replacement of the entire context. .B \-c check the validity of the contexts against the specified binary policy. .TP +.B \-C +If only relabeling errors are encountered during the file tree walks, +exit with status +.B 1 +rather than +.BR 255 . +.TP .B \-d show what specification matched each file. .TP @@ -219,6 +227,20 @@ or the .B \-s option is used. +.SH "EXIT STATUS" +.B setfiles +exits with status +.B 0 +if it encounters no errors. Fatal errors result in status +.BR 255 . +Labeling errors encountered during file tree walk(s) result in status +.B 1 +if the +.B -C +option is specified and no other kind of error is encountered, and in status +.B 255 +otherwise. + .SH "NOTES" .IP "1." 4 .B setfiles