From patchwork Mon Sep 26 15:30:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Haines X-Patchwork-Id: 9350875 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4B0836077B for ; Mon, 26 Sep 2016 15:32:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3B07028821 for ; Mon, 26 Sep 2016 15:32:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2F69528D51; Mon, 26 Sep 2016 15:32:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from emsm-gh1-uea11.nsa.gov (smtp.nsa.gov [8.44.101.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 765D028821 for ; Mon, 26 Sep 2016 15:32:20 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.30,400,1470700800"; d="scan'208";a="19550424" IronPort-PHdr: =?us-ascii?q?9a23=3Anl4FCh/uPZDBbv9uRHKM819IXTAuvvDOBiVQ1KB9?= =?us-ascii?q?1egcTK2v8tzYMVDF4r011RmSDN+dsqkP27OempujcFRI2YyGvnEGfc4EfD4+ou?= =?us-ascii?q?JSoTYdBtWYA1bwNv/gYn9yNs1DUFh44yPzahANS47AblHf6ke/8SQVUk2mc1Ek?= =?us-ascii?q?fKKsQcWC1oye7KObw9XreQJGhT6wM/tZDS6dikHvjPQQmpZoMa0ryxHE8TNicu?= =?us-ascii?q?VSwn50dxrIx06vrvqq+NZf1wgY+7d4r48TGZn9Kr81Sb1eESQOL3E+5MqtswLK?= =?us-ascii?q?CwSI+CgySGITxyBJCAjM9h2yfp7wtCbh/r5n2SKaNNf6ersDWT2j6apwYBX0iS?= =?us-ascii?q?EbOiQ//X2Rgct12vEI6Cm9rgByltaHKLqeM+BzK+aEJd4=3D?= X-IPAS-Result: =?us-ascii?q?A2EXAwDLPulX/wHyM5BdHQEFAQsBGAEFAQsBgxIBAQEBAR6?= =?us-ascii?q?BU7pFPR2HZUwBAQEBAQEBAQIBAlsngjIEAxMFBTkKMgEBAQEBAQEBAQEBAQEBA?= =?us-ascii?q?RoCCEgBASECJBMGAQ0gDAIDCQIFEikICAMBLRUfCwUYBIgPAQMXBLZFBYEChFq?= =?us-ascii?q?CVwMIhCeJK4FPEQGCaAuCah0FjjSLQo9qgWyIDwyFYkiMI4N8VIJVNg4cGIE5c?= =?us-ascii?q?YVHeIEnAQEB?= Received: from unknown (HELO tarius.tycho.ncsc.mil) ([144.51.242.1]) by emsm-gh1-uea11.nsa.gov with ESMTP; 26 Sep 2016 15:32:03 +0000 Received: from prometheus.infosec.tycho.ncsc.mil (prometheus [192.168.25.40]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id u8QFW3Tg000847; Mon, 26 Sep 2016 11:32:03 -0400 Received: from tarius.tycho.ncsc.mil (tarius.infosec.tycho.ncsc.mil [144.51.242.1]) by prometheus.infosec.tycho.ncsc.mil (8.15.2/8.15.2) with ESMTP id u8QFUgUM253087 for ; Mon, 26 Sep 2016 11:30:42 -0400 Received: from goalie.tycho.ncsc.mil (goalie [144.51.242.250]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id u8QFUetw000706 for ; Mon, 26 Sep 2016 11:30:42 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A1CdAAAiPulXh4IAFEFdHAEBBAEBCgEBgz0BAQEBAYFxpTAEkT+EE4YegiwBAgEBAQEBAhMBAQEIDQkJGYUUKhkBOAEVgTuIMAEDFwS2RQWBAoRaglcDCIQniSuESQuCah0FjjSLQo9qgWyIG4ViSIwjg3yDHUIOEQsYgTlxh2YBAQE X-IPAS-Result: A1CdAAAiPulXh4IAFEFdHAEBBAEBCgEBgz0BAQEBAYFxpTAEkT+EE4YegiwBAgEBAQEBAhMBAQEIDQkJGYUUKhkBOAEVgTuIMAEDFwS2RQWBAoRaglcDCIQniSuESQuCah0FjjSLQo9qgWyIG4ViSIwjg3yDHUIOEQsYgTlxh2YBAQE X-IronPort-AV: E=Sophos;i="5.30,400,1470715200"; d="scan'208";a="5728973" Received: from emsm-gh1-uea10.corp.nsa.gov (HELO emsm-gh1-uea10.nsa.gov) ([10.208.41.36]) by goalie.tycho.ncsc.mil with ESMTP; 26 Sep 2016 11:30:42 -0400 IronPort-PHdr: =?us-ascii?q?9a23=3Af0NN4R2f9sEnQTEcsmDT+DRfVm0co7zxezQtwd8Z?= =?us-ascii?q?segSLfad9pjvdHbS+e9qxAeQG96KsbQd0KGG6ujJYi8p2d65qncMcZhBBVcuqP?= =?us-ascii?q?49uEgeOvODElDxN/XwbiY3T4xoXV5h+GynYwAOQJ6tL2PbrnD61zMOABK3bVMz?= =?us-ascii?q?fbWvXNeJxJTun8mJuLTrKz1SgzS8Zb4gZD6Xli728vcsvI15N6wqwQHIqHYbM8?= =?us-ascii?q?5fxGdvOE7B102kvpT4r9Zf9HFLtvYg8dNQebnrdKQ/C7pDBXIpNH5mytfssEz5?= =?us-ascii?q?TACP72EQGkUfkxxFGECR9hDxXp7rvhzxgep02S+XJuX8UbEyRTm46ap3DhTvjX?= =?us-ascii?q?FUZHYC7GjLh5ko3+pgqxW7qkknzg=3D=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0EEAQCLPulXh4IAFEFdHAEBBAEBCgEBG?= =?us-ascii?q?AEFAQsBgxIBAQEBAYFxpTAEkT+DUkGGHoIsAQEBAQEBAQECAQIQAQEBCA0JCRk?= =?us-ascii?q?vgjIYDDkKMgEBAQEBAQEBAQEBAQEBARoCCEgBAR0qGQE4ARWBO4gwAQMXBLZHB?= =?us-ascii?q?YEChFqCVwMIhCeJK4RJC4JqHQWONItCj2qBbIgbhWJIjCODfIMdQg4RCxiBOXG?= =?us-ascii?q?HZgEBAQ?= X-IPAS-Result: =?us-ascii?q?A0EEAQCLPulXh4IAFEFdHAEBBAEBCgEBGAEFAQsBgxIBAQE?= =?us-ascii?q?BAYFxpTAEkT+DUkGGHoIsAQEBAQEBAQECAQIQAQEBCA0JCRkvgjIYDDkKMgEBA?= =?us-ascii?q?QEBAQEBAQEBAQEBARoCCEgBAR0qGQE4ARWBO4gwAQMXBLZHBYEChFqCVwMIhCe?= =?us-ascii?q?JK4RJC4JqHQWONItCj2qBbIgbhWJIjCODfIMdQg4RCxiBOXGHZgEBAQ?= X-IronPort-AV: E=Sophos;i="5.30,400,1470700800"; d="scan'208";a="17967163" Received: from rgout0603.bt.lon5.cpcloud.co.uk (HELO rgout06.bt.lon5.cpcloud.co.uk) ([65.20.0.130]) by emsm-gh1-uea10.nsa.gov with ESMTP; 26 Sep 2016 15:30:38 +0000 X-OWM-Source-IP: 81.132.47.164 (GB) X-OWM-Env-Sender: richard_c_haines@btinternet.com X-Junkmail-Premium-Raw: score=8/50, refid=2.7.2:2016.9.19.125116:17:8.707, ip=, rules=NO_URI_FOUND, NO_CTA_URI_FOUND, NO_MESSAGE_ID, TO_MALFORMED, NO_URI_HTTPS Received: from localhost.localdomain (81.132.47.164) by rgout06.bt.lon5.cpcloud.co.uk (9.0.019.06-1) (authenticated as richard_c_haines@btinternet.com) id 57DAE58D01A2A35F; Mon, 26 Sep 2016 16:30:37 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=btinternet.com; s=btcpcloud; t=1474903838; bh=1BoV9tmI1y0bGcKm27BG9bzMdVw716Av1DBlYgRnob0=; h=From:To:Cc:Subject:Date:Message-Id:X-Mailer; b=CRdW45PMefieizvHniXjiG1IvyLRFMfHIpit5WdgH9hdxL4DzfX/l+eld3XSDePxmHEMt3wXojrrQWH63hKnRtV5s90/Z02eFE1NKvMYqKwVS7Vjld/Ps9DfYJ1Ws8dwFD6k6qyRNO3ydq/RsSHxaTxcgMA/Di5w8AE8+f7oic4= From: Richard Haines To: selinux@tycho.nsa.gov Subject: [PATCH 2/2] policycoreutils: setfiles - Utility to find security.restorecon_last entries Date: Mon, 26 Sep 2016 16:30:30 +0100 Message-Id: <1474903830-5042-1-git-send-email-richard_c_haines@btinternet.com> X-Mailer: git-send-email 2.7.4 X-BeenThere: selinux@tycho.nsa.gov X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Security-Enhanced Linux \(SELinux\) mailing list" List-Post: List-Help: MIME-Version: 1.0 Errors-To: selinux-bounces@tycho.nsa.gov Sender: "Selinux" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds restorecon_xattr(8) to find and/or remove security.restorecon_last entries added by setfiles(8) or restorecon(8). Uses the services of selinux_restorecon_xattr(3). Signed-off-by: Richard Haines --- policycoreutils/setfiles/Makefile | 10 +- policycoreutils/setfiles/restore.h | 1 + policycoreutils/setfiles/restorecon_xattr.8 | 119 +++++++++++++++ policycoreutils/setfiles/restorecon_xattr.c | 221 ++++++++++++++++++++++++++++ 4 files changed, 348 insertions(+), 3 deletions(-) create mode 100644 policycoreutils/setfiles/restorecon_xattr.8 create mode 100644 policycoreutils/setfiles/restorecon_xattr.c diff --git a/policycoreutils/setfiles/Makefile b/policycoreutils/setfiles/Makefile index 98f4f7d..43364f9 100644 --- a/policycoreutils/setfiles/Makefile +++ b/policycoreutils/setfiles/Makefile @@ -17,13 +17,15 @@ ifeq ($(AUDITH), /usr/include/libaudit.h) LDLIBS += -laudit endif -all: setfiles restorecon man +all: setfiles restorecon restorecon_xattr man setfiles: setfiles.o restore.o restorecon: setfiles ln -sf setfiles restorecon +restorecon_xattr: restorecon_xattr.o restore.o + man: @cp -af setfiles.8 setfiles.8.man @cp -af restorecon.8 restorecon.8.man @@ -35,14 +37,16 @@ install: all -mkdir -p $(SBINDIR) install -m 755 setfiles $(SBINDIR) (cd $(SBINDIR) && ln -sf setfiles restorecon) + install -m 755 restorecon_xattr $(SBINDIR) install -m 644 setfiles.8.man $(MANDIR)/man8/setfiles.8 install -m 644 restorecon.8.man $(MANDIR)/man8/restorecon.8 + install -m 644 restorecon_xattr.8 $(MANDIR)/man8/restorecon_xattr.8 clean: - rm -f setfiles restorecon *.o setfiles.8.man restorecon.8.man + rm -f setfiles restorecon restorecon_xattr *.o setfiles.8.man restorecon.8.man indent: ../../scripts/Lindent $(wildcard *.[ch]) relabel: install - $(SBINDIR)/restorecon $(SBINDIR)/setfiles + $(SBINDIR)/restorecon $(SBINDIR)/setfiles $(SBINDIR)/restorecon_xattr diff --git a/policycoreutils/setfiles/restore.h b/policycoreutils/setfiles/restore.h index bafb662..97fbdf4 100644 --- a/policycoreutils/setfiles/restore.h +++ b/policycoreutils/setfiles/restore.h @@ -56,5 +56,6 @@ 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); +extern char **exclude_list; #endif diff --git a/policycoreutils/setfiles/restorecon_xattr.8 b/policycoreutils/setfiles/restorecon_xattr.8 new file mode 100644 index 0000000..65b28ea --- /dev/null +++ b/policycoreutils/setfiles/restorecon_xattr.8 @@ -0,0 +1,119 @@ +.TH "restorecon_xattr" "8" "24 Sept 2016" "" "SELinux User Command" +.SH "NAME" +restorecon_xattr \- manage +.I security.restorecon_last +extended attribute entries added by +.BR setfiles (8) +or +.BR restorecon (8). + +.SH "SYNOPSIS" +.B restorecon_xattr +.RB [ \-d ] +.RB [ \-D ] +.RB [ \-m ] +.RB [ \-n ] +.RB [ \-r ] +.RB [ \-v ] +.RB [ \-e +.IR directory ] +.RB [ \-f +.IR specfile ] +.I pathname + +.SH "DESCRIPTION" +.B restorecon_xattr +will display the SHA1 digests added to extended attributes +.I security.restorecon_last +or delete the attribute completely. These attributes are set by +.BR restorecon (8) +or +.BR setfiles (8) +to specified directories when relabeling recursively. +.sp +.B restorecon_xattr +is useful for managing the extended attribute entries particularly when +users forget what directories they ran +.BR restorecon (8) +or +.BR setfiles (8) +from. +.sp +.B RAMFS +and +.B TMPFS +filesystems do not support the +.I security.restorecon_last +extended attribute and are automatically excluded from searches. +.sp +By default +.B restorecon_xattr +will display the SHA1 digests with "Match" appended if they match the default +specfile set or the +.I specfile +set used with the +.B \-f +option. Non-matching SHA1 digests will be displayed with "No Match" appended. +This feature can be disabled by the +.B \-n +option. + +.SH "OPTIONS" +.TP +.B \-d +delete all non-matching +.I security.restorecon_last +directory digest entries. +.TP +.B \-D +delete all +.I security.restorecon_last +directory digest entries. +.TP +.B \-m +do not read +.B /proc/mounts +to obtain a list of non-seclabel mounts to be excluded from relabeling checks. +.br +Setting +.B \-m +is useful where there is a non-seclabel fs mounted with a seclabel fs mounted +on a directory below this. +.TP +.B \-n +Do not append "Match" or "No Match" to displayed digests. +.TP +.B \-r +recursively descend directories. +.TP +.B \-v +display SHA1 digest generated by specfile set. +.TP +.B \-e +.I directory +.br +directory to exclude (repeat option for more than one directory). +.TP +.B \-f +.I specfile +.br +an optional +.I specfile +containing file context entries as described in +.BR file_contexts (5). +This will be used by +.BR selabel_open (3) +to retrieve the set of labeling entries, with the SHA1 digest being +retrieved by +.BR selabel_digest (3). +If the option is not specified, then the default file_contexts will be used. + +.SH "ARGUMENTS" +.TP +.I pathname +.br +the pathname of the directory tree to be searched. + +.SH "SEE ALSO" +.BR restorecon (8), +.BR setfiles (8) diff --git a/policycoreutils/setfiles/restorecon_xattr.c b/policycoreutils/setfiles/restorecon_xattr.c new file mode 100644 index 0000000..1c39efe --- /dev/null +++ b/policycoreutils/setfiles/restorecon_xattr.c @@ -0,0 +1,221 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "restore.h" + +static void usage(const char *progname) +{ + fprintf(stderr, + "\nusage: %s [-vnrmdD] [-e directory] [-f specfile] pathname\n" + "\nWhere:\n\t" + "-v Display digest generated by specfile set.\n\t" + "-n Do not append \"Match\" or \"No Match\" to displayed digests.\n\t" + "-r Recursively descend directories.\n\t" + "-m Do not read /proc/mounts for entries to be excluded.\n\t" + "-d Delete non-matching digest entries.\n\t" + "-D Delete all digest entries.\n\t" + "-e Directory to exclude (repeat option for more than one directory).\n\t" + "-f Optional specfile for calculating the digest.\n\t" + "pathname Path to search for xattr \"security.restorecon_last\" entries.\n\n", + progname); + exit(-1); +} + +int main(int argc, char **argv) +{ + int opt, rc; + unsigned int xattr_flags = 0, delete_digest = 0, recurse = 0; + unsigned int delete_all_digests = 0, ignore_mounts = 0; + bool display_digest = false; + char *sha1_buf, **specfiles, *fc_file = NULL; + unsigned char *fc_digest = NULL; + size_t i, fc_digest_len = 0, num_specfiles; + + struct stat sb; + struct selabel_handle *hnd = NULL; + struct dir_xattr *current, *next, **xattr_list = NULL; + + bool no_comment = true; + + if (argc < 2) + usage(argv[0]); + + if (is_selinux_enabled() <= 0) { + fprintf(stderr, + "SELinux must be enabled to perform this operation.\n"); + exit(-1); + } + + exclude_list = NULL; + + while ((opt = getopt(argc, argv, "vnrmdDe:f:")) > 0) { + switch (opt) { + case 'v': + display_digest = true; + break; + case 'n': + no_comment = false; + break; + case 'r': + recurse = SELINUX_RESTORECON_XATTR_RECURSE; + break; + case 'm': + ignore_mounts = SELINUX_RESTORECON_XATTR_IGNORE_MOUNTS; + break; + case 'd': + delete_digest = + SELINUX_RESTORECON_XATTR_DELETE_NONMATCH_DIGESTS; + break; + case 'D': + delete_all_digests = + SELINUX_RESTORECON_XATTR_DELETE_ALL_DIGESTS; + break; + case 'e': + if (lstat(optarg, &sb) < 0 && errno != EACCES) { + fprintf(stderr, "Can't stat exclude path \"%s\", %s - ignoring.\n", + optarg, strerror(errno)); + break; + } + add_exclude(optarg); + break; + case 'f': + fc_file = optarg; + break; + default: + usage(argv[0]); + } + } + + if (optind >= argc) { + fprintf(stderr, "No pathname specified\n"); + exit(-1); + } + + struct selinux_opt selinux_opts[] = { + { SELABEL_OPT_PATH, fc_file }, + { SELABEL_OPT_DIGEST, (char *)1 } + }; + + hnd = selabel_open(SELABEL_CTX_FILE, selinux_opts, 2); + if (!hnd) { + switch (errno) { + case EOVERFLOW: + fprintf(stderr, "Error: Number of specfiles or" + " specfile buffer caused an overflow.\n"); + break; + default: + fprintf(stderr, "Error: selabel_open: %s\n", + strerror(errno)); + } + exit(-1); + } + + /* Use own handle as need to allow different file_contexts. */ + selinux_restorecon_set_sehandle(hnd); + + if (display_digest) { + if (selabel_digest(hnd, &fc_digest, &fc_digest_len, + &specfiles, &num_specfiles) < 0) { + fprintf(stderr, + "Error: selabel_digest: Digest not available.\n"); + selabel_close(hnd); + exit(-1); + } + + sha1_buf = malloc(fc_digest_len * 2 + 1); + if (!sha1_buf) { + fprintf(stderr, + "Error allocating digest buffer: %s\n", + strerror(errno)); + selabel_close(hnd); + exit(-1); + } + + for (i = 0; i < fc_digest_len; i++) + sprintf((&sha1_buf[i * 2]), "%02x", fc_digest[i]); + + printf("specfiles SHA1 digest: %s\n", sha1_buf); + + printf("calculated using the following specfile(s):\n"); + if (specfiles) { + for (i = 0; i < num_specfiles; i++) + printf("%s\n", specfiles[i]); + } + free(sha1_buf); + printf("\n"); + } + + if (exclude_list) + selinux_restorecon_set_exclude_list + ((const char **)exclude_list); + + xattr_flags = delete_digest | delete_all_digests | + ignore_mounts | recurse; + + if (selinux_restorecon_xattr(argv[optind], xattr_flags, &xattr_list)) { + fprintf(stderr, + "Error selinux_restorecon_xattr: %s\n", + strerror(errno)); + rc = -1; + goto out; + } + + if (xattr_list) { + current = *xattr_list; + while (current) { + next = current->next; + printf("%s ", current->directory); + + switch (current->result) { + case MATCH: + printf("Digest: %s%s", current->digest, + no_comment ? " Match\n" : "\n"); + break; + case NOMATCH: + printf("Digest: %s%s", current->digest, + no_comment ? " No Match\n" : "\n"); + break; + case DELETED_MATCH: + printf("Deleted Digest: %s%s", current->digest, + no_comment ? " Match\n" : "\n"); + break; + case DELETED_NOMATCH: + printf("Deleted Digest: %s%s", + current->digest, + no_comment ? " No Match\n" : "\n"); + break; + case ERROR: + printf("Digest: %s Error removing xattr\n", + current->digest); + break; + } + current = next; + } + /* Free memory */ + current = *xattr_list; + while (current) { + next = current->next; + free(current->directory); + free(current->digest); + free(current); + current = next; + } + } + + rc = 0; +out: + selabel_close(hnd); + restore_finish(); + return rc; +}