diff --git a/policycoreutils-rhat.patch b/policycoreutils-rhat.patch index 7ec3663..cb849fb 100644 --- a/policycoreutils-rhat.patch +++ b/policycoreutils-rhat.patch @@ -17,6 +17,49 @@ index 9cfe3bc..9c242d4 100644 INOTIFYH = $(shell ls /usr/include/sys/inotify.h 2>/dev/null) +diff --git a/policycoreutils/audit2allow/audit2allow b/policycoreutils/audit2allow/audit2allow +index e9d5882..8e0c396 100644 +--- a/policycoreutils/audit2allow/audit2allow ++++ b/policycoreutils/audit2allow/audit2allow +@@ -236,7 +236,7 @@ class AuditToPolicy: + import seobject + for i in self.__parser.avc_msgs: + rc = i.type +- bools = i.bools ++ data = i.data + if rc >= 0: + print "%s\n\tWas caused by:" % i.message + if rc == audit2why.ALLOW: +@@ -250,15 +250,15 @@ class AuditToPolicy: + print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n" + continue + if rc == audit2why.BOOLEAN: +- if len(bools) > 1: ++ if len(data) > 1: + print "\tOne of the following booleans was set incorrectly." +- for b in bools: ++ for b in data: + print "\tDescription:\n\t%s\n" % seobject.boolean_desc(b[0]) + print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1]) + else: +- print "\tThe boolean %s was set incorrectly. " % (bools[0][0]) +- print "\tDescription:\n\t%s\n" % seobject.boolean_desc(bools[0][0]) +- print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (bools[0][0], bools[0][1]) ++ print "\tThe boolean %s was set incorrectly. " % (data[0][0]) ++ print "\tDescription:\n\t%s\n" % seobject.boolean_desc(data[0][0]) ++ print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1]) + continue + + if rc == audit2why.TERULE: +@@ -270,6 +270,8 @@ class AuditToPolicy: + print "\t\tPolicy constraint violation.\n" + print "\t\tMay require adding a type attribute to the domain or type to satisfy the constraint.\n" + print "\t\tConstraints are defined in the policy sources in policy/constraints (general), policy/mcs (MCS), and policy/mls (MLS).\n" ++ for reason in data: ++ print "\t\tNote: Possible cause is the source and target %s differ\n" % reason + continue + + if rc == audit2why.RBAC: diff --git a/policycoreutils/audit2allow/sepolgen-ifgen b/policycoreutils/audit2allow/sepolgen-ifgen index ef4bec3..9b313ec 100644 --- a/policycoreutils/audit2allow/sepolgen-ifgen @@ -284928,7 +284971,7 @@ index b31bafe..c79b4bc 100644 if (!root_path) { printf("malloc error (%s)\n", strerror(errno)); diff --git a/policycoreutils/setfiles/restore.c b/policycoreutils/setfiles/restore.c -index 9a7d315..1d0c354 100644 +index 9a7d315..35b32a5 100644 --- a/policycoreutils/setfiles/restore.c +++ b/policycoreutils/setfiles/restore.c @@ -1,5 +1,6 @@ @@ -284968,17 +285011,18 @@ index 9a7d315..1d0c354 100644 if (!r_opts->hnd) { perror(r_opts->selabel_opt_path); exit(1); -@@ -104,8 +109,7 @@ static int restore(FTSENT *ftsent) +@@ -104,8 +109,8 @@ static int restore(FTSENT *ftsent) { char *my_file = strdupa(ftsent->fts_path); int ret = -1; - char *context, *newcon; - int user_only_changed = 0; + security_context_t curcon = NULL, newcon = NULL; ++ float progress; if (match(my_file, ftsent->fts_statp, &newcon) < 0) /* Check for no matching specification. */ -@@ -114,7 +118,12 @@ static int restore(FTSENT *ftsent) +@@ -114,7 +119,14 @@ static int restore(FTSENT *ftsent) if (r_opts->progress) { r_opts->count++; if (r_opts->count % STAR_COUNT == 0) { @@ -284986,13 +285030,15 @@ index 9a7d315..1d0c354 100644 + if (r_opts->progress == 1) { + fprintf(stdout, "*"); + } else { -+ int progress = 100.0 * r_opts->count / r_opts->nfile; -+ fprintf(stdout, "\r%d%%", progress); ++ if (r_opts->nfile > 0) { ++ progress = (r_opts->count < r_opts->nfile) ? (100.0 * r_opts->count / r_opts->nfile) : 100; ++ fprintf(stdout, "\r%-.1f%%", progress); ++ } + } fflush(stdout); } } -@@ -139,74 +148,105 @@ static int restore(FTSENT *ftsent) +@@ -139,74 +151,105 @@ static int restore(FTSENT *ftsent) printf("%s: %s matched by %s\n", r_opts->progname, my_file, newcon); } @@ -285075,7 +285121,7 @@ index 9a7d315..1d0c354 100644 + if (! conb) { + context_free(cona); + goto out; - } ++ } + + types_differ = strcmp(context_type_get(cona), context_type_get(conb)); + if (types_differ) { @@ -285092,16 +285138,16 @@ index 9a7d315..1d0c354 100644 + + if (!types_differ || err) { + goto out; -+ } -+ } -+ -+ if (r_opts->verbose) { -+ printf("%s reset %s context %s->%s\n", -+ r_opts->progname, my_file, curcon ?: "", newcon); + } } - if (r_opts->logging && !user_only_changed) { - if (context) ++ if (r_opts->verbose) { ++ printf("%s reset %s context %s->%s\n", ++ r_opts->progname, my_file, curcon ?: "", newcon); ++ } ++ + if (r_opts->logging && r_opts->change) { + if (curcon) syslog(LOG_INFO, "relabeling %s from %s to %s\n", @@ -285127,7 +285173,7 @@ index 9a7d315..1d0c354 100644 goto out; /* -@@ -218,14 +258,17 @@ static int restore(FTSENT *ftsent) +@@ -218,14 +261,17 @@ static int restore(FTSENT *ftsent) r_opts->progname, my_file, newcon, strerror(errno)); goto skip; } @@ -285146,97 +285192,33 @@ index 9a7d315..1d0c354 100644 freecon(newcon); return ERR; } -@@ -250,6 +293,44 @@ static int apply_spec(FTSENT *ftsent) +@@ -250,6 +296,8 @@ static int apply_spec(FTSENT *ftsent) return rc; } -+static unsigned round_up(unsigned x, unsigned m) -+{ -+ return m * ((-1 + m + x) / m); -+} -+ -+static unsigned int *bitmap_alloc(unsigned nbits) -+{ -+ unsigned const w_bitmap = round_up(nbits, 8*sizeof(int)) / -+ (8*sizeof(int)); -+ return calloc(w_bitmap, sizeof(int)); -+} -+ -+static void bitmap_free(unsigned int *bmap) -+{ -+ free(bmap); -+} -+ -+#define LG_BPW ((4==sizeof(int)) \ -+ ? 5 \ -+ : ((8==sizeof(int)) \ -+ ? 6 \ -+ : 31 )) -+ -+static unsigned int bitmap_test(unsigned int *const map, unsigned bit) -+{ -+ return -+ map[bit>>LG_BPW] & (1u<<((-1+ (8*sizeof(int))) & bit)); -+} -+ -+static unsigned int bitmap_set(unsigned int *const map, unsigned bit) -+{ -+ unsigned int old = bitmap_test(map, bit); -+ map[bit>>LG_BPW] |= (1u<<((-1+ (8*sizeof(int))) & bit)); -+ return old; -+} -+ +#include + static int process_one(char *name, int recurse_this_path) { int rc = 0; -@@ -284,6 +365,14 @@ static int process_one(char *name, int recurse_this_path) - /* Keep the inode of the first one. */ - dev_num = ftsent->fts_statp->st_dev; - -+ unsigned int *i_bitmap = 0; -+ struct statvfs statvfs_buf; -+ memset(&statvfs_buf, 0, sizeof(statvfs_buf)); -+ if (!statvfs(name, &statvfs_buf)) { -+ r_opts->nfile = statvfs_buf.f_files - statvfs_buf.f_ffree; -+ i_bitmap = bitmap_alloc(statvfs_buf.f_files); -+ } -+ - do { - rc = 0; - /* Skip the post order nodes. */ -@@ -299,6 +388,21 @@ static int process_one(char *name, int recurse_this_path) +@@ -299,6 +347,7 @@ static int process_one(char *name, int recurse_this_path) continue; } } -+ /* FTS_SEEDOT is not set, so fts_read() ignores "." and "..". -+ * Thus the hardlinks for a directory should be ignored. -+ */ -+ if (ftsent->fts_info != FTS_D -+ && 1 < ftsent->fts_statp->st_nlink) { -+ /* Adjust for hardlinks. */ -+ ino_t const inum = ftsent->fts_statp->st_ino; -+ if (inum < statvfs_buf.f_files /* paranoia? */ -+ && !bitmap_test(i_bitmap, inum)) { -+ /* First time for this .st_ino */ -+ bitmap_set(i_bitmap, inum); -+ r_opts->nfile += -1+ -+ ftsent->fts_statp->st_nlink; -+ } -+ } ++ rc = apply_spec(ftsent); if (rc == SKIP) fts_set(fts_handle, ftsent, FTS_SKIP); -@@ -314,6 +418,7 @@ out: - filespec_eval(); - filespec_destroy(); - } -+ bitmap_free(i_bitmap); - if (fts_handle) - fts_close(fts_handle); - return rc; -@@ -328,10 +433,7 @@ int process_glob(char *name, int recurse) { +@@ -307,7 +356,7 @@ static int process_one(char *name, int recurse_this_path) + if (!recurse_this_path) + break; + } while ((ftsent = fts_read(fts_handle)) != NULL); +- ++ + out: + if (r_opts->add_assoc) { + if (!r_opts->quiet) +@@ -328,10 +377,7 @@ int process_glob(char *name, int recurse) { size_t i = 0; int errors; memset(&globbuf, 0, sizeof(globbuf)); @@ -285248,7 +285230,7 @@ index 9a7d315..1d0c354 100644 if (errors) return errors; -@@ -341,7 +443,9 @@ int process_glob(char *name, int recurse) { +@@ -341,7 +387,9 @@ int process_glob(char *name, int recurse) { continue; if (len > 0 && strcmp(&globbuf.gl_pathv[i][len], "/..") == 0) continue; @@ -285259,7 +285241,7 @@ index 9a7d315..1d0c354 100644 } globfree(&globbuf); return errors; -@@ -447,22 +551,6 @@ int add_exclude(const char *directory) +@@ -447,22 +495,6 @@ int add_exclude(const char *directory) return 0; } @@ -285282,8 +285264,70 @@ index 9a7d315..1d0c354 100644 /* * Evaluate the association hash table distribution. */ +@@ -595,12 +627,22 @@ static int filespec_add(ino_t ino, const security_context_t con, const char *fil + } + + #include ++int file_system_count(char *name) { ++ struct statvfs statvfs_buf; ++ int nfile = 0; ++ memset(&statvfs_buf, 0, sizeof(statvfs_buf)); ++ if (!statvfs(name, &statvfs_buf)) { ++ nfile = statvfs_buf.f_files - statvfs_buf.f_ffree; ++ } ++ return nfile; ++} ++ + /* + Search /proc/mounts for all file systems that do not support extended + attributes and add them to the exclude directory table. File systems +- that support security labels have the seclabel option. ++ that support security labels have the seclabel option, return total file count + */ +-void exclude_non_seclabel_mounts() ++int exclude_non_seclabel_mounts() + { + struct utsname uts; + FILE *fp; +@@ -609,16 +651,16 @@ void exclude_non_seclabel_mounts() + int index = 0, found = 0; + char *mount_info[4]; + char *buf = NULL, *item; +- ++ int nfile = 0; + /* Check to see if the kernel supports seclabel */ + if (uname(&uts) == 0 && strverscmp(uts.release, "2.6.30") < 0) +- return; ++ return 0; + if (is_selinux_enabled() <= 0) +- return; ++ return 0; + + fp = fopen("/proc/mounts", "r"); + if (!fp) +- return; ++ return 0; + + while ((num = getline(&buf, &len, fp)) != -1) { + found = 0; +@@ -645,6 +687,7 @@ void exclude_non_seclabel_mounts() + while (item != NULL) { + if (strcmp(item, "seclabel") == 0) { + found = 1; ++ nfile += file_system_count(mount_info[1]); + break; + } + item = strtok(NULL, ","); +@@ -657,5 +700,7 @@ void exclude_non_seclabel_mounts() + + free(buf); + fclose(fp); ++ /* return estimated #Files + 5% for directories and hard links */ ++ return nfile * 1.05; + } + diff --git a/policycoreutils/setfiles/restore.h b/policycoreutils/setfiles/restore.h -index ac27222..1a3da73 100644 +index ac27222..dfb38d0 100644 --- a/policycoreutils/setfiles/restore.h +++ b/policycoreutils/setfiles/restore.h @@ -14,6 +14,7 @@ @@ -285312,6 +285356,14 @@ index ac27222..1a3da73 100644 }; void restore_init(struct restore_opts *opts); +@@ -49,6 +52,6 @@ int exclude(const char *path); + void remove_exclude(const char *directory); + int process_one_realpath(char *name, int recurse); + int process_glob(char *name, int recurse); +-void exclude_non_seclabel_mounts(); ++int exclude_non_seclabel_mounts(); + + #endif diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8 index c8ea4bb..65a59de 100644 --- a/policycoreutils/setfiles/restorecon.8 @@ -285424,7 +285476,7 @@ index 7f700ca..2741919 100644 .B \-W display warnings about entries that had no matching files. diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c -index fa0cd6a..f64ee16 100644 +index fa0cd6a..904d061 100644 --- a/policycoreutils/setfiles/setfiles.c +++ b/policycoreutils/setfiles/setfiles.c @@ -39,7 +39,7 @@ void usage(const char *const name) @@ -285469,8 +285521,12 @@ index fa0cd6a..f64ee16 100644 altpath = NULL; -@@ -217,7 +221,7 @@ int main(int argc, char **argv) - exclude_non_seclabel_mounts(); +@@ -214,10 +218,10 @@ int main(int argc, char **argv) + } + + /* This must happen before getopt. */ +- exclude_non_seclabel_mounts(); ++ r_opts.nfile = exclude_non_seclabel_mounts(); /* Process any options. */ - while ((opt = getopt(argc, argv, "c:de:f:ilnpqrsvo:FRW0")) > 0) { diff --git a/policycoreutils-sepolgen.patch b/policycoreutils-sepolgen.patch index 5c7af1d..f90795f 100644 --- a/policycoreutils-sepolgen.patch +++ b/policycoreutils-sepolgen.patch @@ -1,3 +1,92 @@ +diff --git a/sepolgen/src/sepolgen/access.py b/sepolgen/src/sepolgen/access.py +index 649735f..cf13210 100644 +--- a/sepolgen/src/sepolgen/access.py ++++ b/sepolgen/src/sepolgen/access.py +@@ -87,7 +87,7 @@ class AccessVector: + self.perms = refpolicy.IdSet() + self.audit_msgs = [] + self.type = audit2why.TERULE +- self.bools = [] ++ self.data = [] + + # The direction of the information flow represented by this + # access vector - used for matching +@@ -256,7 +256,7 @@ class AccessVectorSet: + for av in l: + self.add_av(AccessVector(av)) + +- def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None, avc_type=audit2why.TERULE, bools=[]): ++ def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None, avc_type=audit2why.TERULE, data=[]): + """Add an access vector to the set. + """ + tgt = self.src.setdefault(src_type, { }) +@@ -269,7 +269,7 @@ class AccessVectorSet: + access.src_type = src_type + access.tgt_type = tgt_type + access.obj_class = obj_class +- access.bools = bools ++ access.data = data + access.type = avc_type + cls[obj_class, avc_type] = access + +diff --git a/sepolgen/src/sepolgen/audit.py b/sepolgen/src/sepolgen/audit.py +index 9e2ccee..73c60f6 100644 +--- a/sepolgen/src/sepolgen/audit.py ++++ b/sepolgen/src/sepolgen/audit.py +@@ -173,7 +173,6 @@ class AVCMessage(AuditMessage): + self.accesses = [] + self.denial = True + self.type = audit2why.TERULE +- self.bools = [] + + def __parse_access(self, recs, start): + # This is kind of sucky - the access that is in a space separated +@@ -241,10 +240,12 @@ class AVCMessage(AuditMessage): + tcontext = self.tcontext.to_string() + scontext = self.scontext.to_string() + access_tuple = tuple( self.accesses) ++ self.data = [] ++ + if (scontext, tcontext, self.tclass, access_tuple) in avcdict.keys(): +- self.type, self.bools = avcdict[(scontext, tcontext, self.tclass, access_tuple)] ++ self.type, self.data = avcdict[(scontext, tcontext, self.tclass, access_tuple)] + else: +- self.type, self.bools = audit2why.analyze(scontext, tcontext, self.tclass, self.accesses); ++ self.type, self.data = audit2why.analyze(scontext, tcontext, self.tclass, self.accesses); + if self.type == audit2why.NOPOLICY: + self.type = audit2why.TERULE + if self.type == audit2why.BADTCON: +@@ -258,7 +259,16 @@ class AVCMessage(AuditMessage): + if self.type == audit2why.BADCOMPUTE: + raise ValueError("Error during access vector computation") + +- avcdict[(scontext, tcontext, self.tclass, access_tuple)] = (self.type, self.bools) ++ if self.type == audit2why.CONSTRAINT: ++ self.data = [] ++ if self.scontext.user != self.tcontext.user: ++ self.data.append("user") ++ if self.scontext.role != self.tcontext.role and self.tcontext.role != "object_r": ++ self.data.append("role") ++ if self.scontext.level != self.tcontext.level: ++ self.data.append("level") ++ ++ avcdict[(scontext, tcontext, self.tclass, access_tuple)] = (self.type, self.data) + + class PolicyLoadMessage(AuditMessage): + """Audit message indicating that the policy was reloaded.""" +@@ -507,10 +517,10 @@ class AuditParser: + if avc_filter: + if avc_filter.filter(avc): + av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass, +- avc.accesses, avc, avc_type=avc.type, bools=avc.bools) ++ avc.accesses, avc, avc_type=avc.type, data=avc.data) + else: + av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass, +- avc.accesses, avc, avc_type=avc.type, bools=avc.bools) ++ avc.accesses, avc, avc_type=avc.type, data=avc.data) + return av_set + + class AVCTypeFilter: diff --git a/sepolgen/src/sepolgen/matching.py b/sepolgen/src/sepolgen/matching.py index 1a9a3e5..d56dd92 100644 --- a/sepolgen/src/sepolgen/matching.py @@ -30,3 +119,49 @@ index 1a9a3e5..d56dd92 100644 def __iter__(self): return iter(self.children) +diff --git a/sepolgen/src/sepolgen/policygen.py b/sepolgen/src/sepolgen/policygen.py +index c3d665c..cc9f8ea 100644 +--- a/sepolgen/src/sepolgen/policygen.py ++++ b/sepolgen/src/sepolgen/policygen.py +@@ -166,14 +166,16 @@ class PolicyGenerator: + rule.comment += "#!!!! This avc has a dontaudit rule in the current policy\n" + + if av.type == audit2why.BOOLEAN: +- if len(av.bools) > 1: +- rule.comment += "#!!!! This avc can be allowed using one of the these booleans:\n# %s\n" % ", ".join(map(lambda x: x[0], av.bools)) ++ if len(av.data) > 1: ++ rule.comment += "#!!!! This avc can be allowed using one of the these booleans:\n# %s\n" % ", ".join(map(lambda x: x[0], av.data)) + else: +- rule.comment += "#!!!! This avc can be allowed using the boolean '%s'\n" % av.bools[0][0] ++ rule.comment += "#!!!! This avc can be allowed using the boolean '%s'\n" % av.data[0][0] + + if av.type == audit2why.CONSTRAINT: + rule.comment += "#!!!! This avc is a constraint violation. You will need to add an attribute to either the source or target type to make it work.\n" + rule.comment += "#Constraint rule: " ++ for reason in av.data: ++ rule.comment += "\n#\tPossible cause source context and target context '%s' differ\b" % reason + + try: + if ( av.type == audit2why.TERULE and +diff --git a/sepolgen/src/sepolgen/refpolicy.py b/sepolgen/src/sepolgen/refpolicy.py +index b138e3d..7ce8f9d 100644 +--- a/sepolgen/src/sepolgen/refpolicy.py ++++ b/sepolgen/src/sepolgen/refpolicy.py +@@ -799,7 +799,7 @@ class Require(Leaf): + self.types = IdSet() + self.obj_classes = { } + self.roles = IdSet() +- self.bools = IdSet() ++ self.data = IdSet() + self.users = IdSet() + + def add_obj_class(self, obj_class, perms): +@@ -816,7 +816,7 @@ class Require(Leaf): + s.append("\tclass %s %s;" % (obj_class, perms.to_space_str())) + for role in self.roles: + s.append("\trole %s;" % role) +- for bool in self.bools: ++ for bool in self.data: + s.append("\tbool %s;" % bool) + for user in self.users: + s.append("\tuser %s;" % user) diff --git a/policycoreutils.spec b/policycoreutils.spec index 25f2295..bcdce5b 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -7,7 +7,7 @@ Summary: SELinux policy core utilities Name: policycoreutils Version: 2.1.12 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv2 Group: System Environment/Base # Based on git repository with tag 20101221