From: <ssm...@us...> - 2007-02-20 13:28:03
|
Revision: 2234 http://svn.sourceforge.net/selinux/?rev=2234&view=rev Author: ssmalley Date: 2007-02-20 05:27:20 -0800 (Tue, 20 Feb 2007) Log Message: ----------- Author: Tod...@sp... Email: Tod...@sp... Subject: PATCH: setfiles memory leak Date: Wed, 7 Feb 2007 12:09:56 -0500 (EST) This patch fixes a memory leak on an error path. - todd Modified Paths: -------------- trunk/policycoreutils/setfiles/setfiles.c Modified: trunk/policycoreutils/setfiles/setfiles.c =================================================================== --- trunk/policycoreutils/setfiles/setfiles.c 2007-02-20 13:25:22 UTC (rev 2233) +++ trunk/policycoreutils/setfiles/setfiles.c 2007-02-20 13:27:20 UTC (rev 2234) @@ -357,6 +357,7 @@ "%s: %s not reset customized by admin to %s\n", progname, my_file, context); } + freecon(context); goto out; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kma...@us...> - 2007-05-11 14:31:22
|
Revision: 2437 http://svn.sourceforge.net/selinux/?rev=2437&view=rev Author: kmacmillan Date: 2007-05-11 07:31:21 -0700 (Fri, 11 May 2007) Log Message: ----------- Author: Stephen Smalley Email: sd...@ty... Subject: Coalesce setfiles and restorecon into a single program Date: Fri, 04 May 2007 15:39:47 -0400 On Fri, 2007-05-04 at 15:19 -0400, Stephen Smalley wrote: > restorecon started life as a much simpler program, but has gradually > grown to being largely a duplicate of setfiles, only differing in its > interface and default behaviors. Meanwhile, people keep adding features > and options to both programs, leading to inconsistencies. > > This patch coalesces setfiles and restorecon into a single program > presenting different interfaces and default behaviors depending on > basename(argv[0]), making restorecon a symlink to setfiles. > > Unresolved issue: Current policy defines separate domains for the two > programs. We need to either coalesce the domains as well, or if there > is legitimate reason for separating them, restorecon could remain a > separate binary (either a complete separate copy or a wrapper) even if > the sources are coalesced. > > Comments? > Grr...bug fix patch below, applies on top of the original one. Acked-by: Karl MacMillan <kma...@me...> Modified Paths: -------------- trunk/policycoreutils/setfiles/setfiles.c Modified: trunk/policycoreutils/setfiles/setfiles.c =================================================================== --- trunk/policycoreutils/setfiles/setfiles.c 2007-05-11 14:30:29 UTC (rev 2436) +++ trunk/policycoreutils/setfiles/setfiles.c 2007-05-11 14:31:21 UTC (rev 2437) @@ -541,6 +541,7 @@ exit(0); } /* Parent: Check and label the files. */ + rc = 0; close(pipe_fds[1]); if (nftw(name, apply_spec, 1024, nftw_flags)) { fprintf(stderr, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ssm...@us...> - 2007-06-05 13:56:29
|
Revision: 2459 http://svn.sourceforge.net/selinux/?rev=2459&view=rev Author: ssmalley Date: 2007-06-05 06:55:56 -0700 (Tue, 05 Jun 2007) Log Message: ----------- Author: Daniel J Walsh Email: dw...@re... Subject: setfiles -c is failing do to bad checking on options. Date: Mon, 04 Jun 2007 18:01:16 -0400 Acked-by: Stephen Smalley <sd...@ty...> Modified Paths: -------------- trunk/policycoreutils/setfiles/setfiles.c Modified: trunk/policycoreutils/setfiles/setfiles.c =================================================================== --- trunk/policycoreutils/setfiles/setfiles.c 2007-06-05 13:47:52 UTC (rev 2458) +++ trunk/policycoreutils/setfiles/setfiles.c 2007-06-05 13:55:56 UTC (rev 2459) @@ -858,8 +858,6 @@ if (strcmp(input_filename, "-") != 0) fclose(f); } else { - if (optind >= argc) - usage(argv[0]); for (i = optind; i < argc; i++) { errors |= process_one(argv[i]); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ssm...@us...> - 2007-06-05 13:59:43
|
Revision: 2460 http://svn.sourceforge.net/selinux/?rev=2460&view=rev Author: ssmalley Date: 2007-06-05 06:59:27 -0700 (Tue, 05 Jun 2007) Log Message: ----------- Author: Yuichi Nakamura Email: yn...@hi... Subject: Bug in restorecon Date: Tue, 5 Jun 2007 09:20:55 +0900 On Mon, 04 Jun 2007 09:28:44 -0400 Stephen Smalley wrote: > On Mon, 2007-06-04 at 03:18 +0900, Yuichi Nakamura wrote: > In that case, why have 'fullname' vs. 'name' at all? Just directly > manipulate name and use it throughout. fullname is unnecessary, so removed. > Make sure that setfiles -r /path/to/altroot > file_contexts /path/to/altroot still works as expected, e.g. > labels /path/to/altroot/etc/shadow with the label of /etc/shadow in > policy. I tested, "touch /altroot/etc/shadow, setfiles -r /altroot" then /altroot/etc/shadow was labeled as same label for /etc/shadow. Please see below patch. Modified Paths: -------------- trunk/policycoreutils/setfiles/setfiles.c Modified: trunk/policycoreutils/setfiles/setfiles.c =================================================================== --- trunk/policycoreutils/setfiles/setfiles.c 2007-06-05 13:55:56 UTC (rev 2459) +++ trunk/policycoreutils/setfiles/setfiles.c 2007-06-05 13:59:27 UTC (rev 2460) @@ -146,20 +146,19 @@ int match(const char *name, struct stat *sb, char **con) { int ret; - const char *fullname = name; char path[PATH_MAX + 1]; if (excludeCtr > 0) { - if (exclude(fullname)) { + if (exclude(name)) { return -1; } } - ret = lstat(fullname, sb); + ret = lstat(name, sb); if (ret) { if (ignore_enoent && errno == ENOENT) return 0; fprintf(stderr, "%s: unable to stat file %s: %s\n", progname, - fullname, strerror(errno)); + name, strerror(errno)); return -1; } @@ -168,12 +167,12 @@ if (verbose > 1) fprintf(stderr, "Warning! %s refers to a symbolic link, not following last component.\n", - fullname); + name); char *p = NULL, *file_sep; - char *tmp_path = strdupa(fullname); + char *tmp_path = strdupa(name); size_t len = 0; if (!tmp_path) { - fprintf(stderr, "strdupa on %s failed: %s\n", fullname, + fprintf(stderr, "strdupa on %s failed: %s\n", name, strerror(errno)); return -1; } @@ -192,7 +191,7 @@ if (p) len = strlen(p); if (!p || len + strlen(file_sep) + 2 > PATH_MAX) { - fprintf(stderr, "realpath(%s) failed %s\n", fullname, + fprintf(stderr, "realpath(%s) failed %s\n", name, strerror(errno)); return -1; } @@ -203,25 +202,23 @@ p++; } strcpy(p, file_sep); - fullname = path; - if (excludeCtr > 0 && exclude(fullname)) + name = path; + if (excludeCtr > 0 && exclude(name)) return -1; } else { char *p; - p = realpath(fullname, path); + p = realpath(name, path); if (!p) { - fprintf(stderr, "realpath(%s) failed %s\n", fullname, + fprintf(stderr, "realpath(%s) failed %s\n", name, strerror(errno)); return -1; } - fullname = p; - if (excludeCtr > 0 && exclude(fullname)) + name = p; + if (excludeCtr > 0 && exclude(name)) return -1; } } - /* fullname will be the real file that gets labeled - * name will be what is matched in the policy */ if (NULL != rootpath) { if (0 != strncmp(rootpath, name, rootpathlen)) { fprintf(stderr, "%s: %s is not located in %s\n", This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ew...@us...> - 2007-06-20 18:35:49
|
Revision: 2485 http://svn.sourceforge.net/selinux/?rev=2485&view=rev Author: ewalsh Date: 2007-06-20 11:35:39 -0700 (Wed, 20 Jun 2007) Log Message: ----------- This patch changes setfiles to use the new interface. Signed-off-by: Eamon Walsh <ew...@ty...> Acked-by: Stephen Smalley <sd...@ty...> Modified Paths: -------------- trunk/policycoreutils/setfiles/setfiles.c Modified: trunk/policycoreutils/setfiles/setfiles.c =================================================================== --- trunk/policycoreutils/setfiles/setfiles.c 2007-06-20 18:34:57 UTC (rev 2484) +++ trunk/policycoreutils/setfiles/setfiles.c 2007-06-20 18:35:39 UTC (rev 2485) @@ -16,6 +16,7 @@ #include <limits.h> #include <sepol/sepol.h> #include <selinux/selinux.h> +#include <selinux/label.h> #include <syslog.h> #include <libgen.h> #ifdef USE_AUDIT @@ -70,21 +71,165 @@ static int abort_on_error; /* Abort the file tree walk upon an error. */ static int add_assoc; /* Track inode associations for conflict detection. */ static int nftw_flags; /* Flags to nftw, e.g. follow links, follow mounts */ -static int matchpathcon_flags; /* Flags to matchpathcon */ +static int base_only; /* Don't use local file_contexts customizations */ +static int ctx_validate; /* Validate contexts */ +static const char *altpath; /* Alternate path to file_contexts */ -static void -#ifdef __GNUC__ - __attribute__ ((format(printf, 1, 2))) -#endif - qprintf(const char *fmt, ...) +/* Label interface handle */ +static struct selabel_handle *hnd; + +/* + * An association between an inode and a context. + */ +typedef struct file_spec { + ino_t ino; /* inode number */ + char *con; /* matched context */ + char *file; /* full pathname */ + struct file_spec *next; /* next association in hash bucket chain */ +} file_spec_t; + +/* + * The hash table of associations, hashed by inode number. + * Chaining is used for collisions, with elements ordered + * by inode number in each bucket. Each hash bucket has a dummy + * header. + */ +#define HASH_BITS 16 +#define HASH_BUCKETS (1 << HASH_BITS) +#define HASH_MASK (HASH_BUCKETS-1) +static file_spec_t *fl_head; + +/* + * Try to add an association between an inode and a context. + * If there is a different context that matched the inode, + * then use the first context that matched. + */ +int filespec_add(ino_t ino, const security_context_t con, const char *file) { - va_list ap; - va_start(ap, fmt); - if (!quiet) - vfprintf(stdout, fmt, ap); - va_end(ap); + file_spec_t *prevfl, *fl; + int h, ret; + struct stat sb; + + if (!fl_head) { + fl_head = malloc(sizeof(file_spec_t) * HASH_BUCKETS); + if (!fl_head) + goto oom; + memset(fl_head, 0, sizeof(file_spec_t) * HASH_BUCKETS); + } + + h = (ino + (ino >> HASH_BITS)) & HASH_MASK; + for (prevfl = &fl_head[h], fl = fl_head[h].next; fl; + prevfl = fl, fl = fl->next) { + if (ino == fl->ino) { + ret = lstat(fl->file, &sb); + if (ret < 0 || sb.st_ino != ino) { + freecon(fl->con); + free(fl->file); + fl->file = strdup(file); + if (!fl->file) + goto oom; + fl->con = strdup(con); + if (!fl->con) + goto oom; + return 1; + } + + if (strcmp(fl->con, con) == 0) + return 1; + + fprintf(stderr, + "%s: conflicting specifications for %s and %s, using %s.\n", + __FUNCTION__, file, fl->file, fl->con); + free(fl->file); + fl->file = strdup(file); + if (!fl->file) + goto oom; + return 1; + } + + if (ino > fl->ino) + break; + } + + fl = malloc(sizeof(file_spec_t)); + if (!fl) + goto oom; + fl->ino = ino; + fl->con = strdup(con); + if (!fl->con) + goto oom_freefl; + fl->file = strdup(file); + if (!fl->file) + goto oom_freefl; + fl->next = prevfl->next; + prevfl->next = fl; + return 0; + oom_freefl: + free(fl); + oom: + fprintf(stderr, + "%s: insufficient memory for file label entry for %s\n", + __FUNCTION__, file); + return -1; } +/* + * Evaluate the association hash table distribution. + */ +void filespec_eval(void) +{ + file_spec_t *fl; + int h, used, nel, len, longest; + + if (!fl_head) + return; + + used = 0; + longest = 0; + nel = 0; + for (h = 0; h < HASH_BUCKETS; h++) { + len = 0; + for (fl = fl_head[h].next; fl; fl = fl->next) { + len++; + } + if (len) + used++; + if (len > longest) + longest = len; + nel += len; + } + + printf + ("%s: hash table stats: %d elements, %d/%d buckets used, longest chain length %d\n", + __FUNCTION__, nel, used, HASH_BUCKETS, longest); +} + +/* + * Destroy the association hash table. + */ +void filespec_destroy(void) +{ + file_spec_t *fl, *tmp; + int h; + + if (!fl_head) + return; + + for (h = 0; h < HASH_BUCKETS; h++) { + fl = fl_head[h].next; + while (fl) { + tmp = fl; + fl = fl->next; + freecon(tmp->con); + free(tmp->file); + free(tmp); + } + fl_head[h].next = NULL; + } + free(fl_head); + fl_head = NULL; +} + static int add_exclude(const char *directory) { struct stat sb; @@ -230,9 +375,9 @@ if (rootpath != NULL && name[0] == '\0') /* this is actually the root dir of the alt root */ - return matchpathcon_index("/", sb->st_mode, con); + return selabel_lookup_raw(hnd, con, "/", sb->st_mode); else - return matchpathcon_index(name, sb->st_mode, con); + return selabel_lookup_raw(hnd, con, name, sb->st_mode); } void usage(const char *const name) @@ -282,7 +427,7 @@ { char *my_file = strdupa(file); struct stat my_sb; - int i, j, ret; + int ret; char *context, *newcon; int user_only_changed = 0; size_t len = strlen(my_file); @@ -293,10 +438,9 @@ if (len > 1 && my_file[len - 1] == '/') my_file[len - 1] = 0; - i = match(my_file, &my_sb, &newcon); - if (i < 0) - /* No matching specification. */ - return 0; + if (match(my_file, &my_sb, &newcon) < 0) + /* Check for no matching specification. */ + return (errno == ENOENT) ? 0 : -1; if (progress) { count++; @@ -317,14 +461,13 @@ * then use the last matching specification. */ if (add_assoc) { - j = matchpathcon_filespec_add(my_sb.st_ino, i, my_file); - if (j < 0) + ret = filespec_add(my_sb.st_ino, newcon, my_file); + if (ret < 0) goto err; - if (j != i) { + if (ret > 0) /* There was already an association and it took precedence. */ goto out; - } } if (debug) { @@ -460,33 +603,25 @@ rootpathlen = len; } -int canoncon(const char *path, unsigned lineno, char **contextp) +int canoncon(char **contextp) { char *context = *contextp, *tmpcon; - int valid = 1; + int rc = 0; if (policyfile) { - valid = (sepol_check_context(context) >= 0); - } else if (security_canonicalize_context_raw(context, &tmpcon) < 0) { - if (errno != ENOENT) { - valid = 0; - inc_err(); + if (sepol_check_context(context) < 0) { + fprintf(stderr, "invalid context %s\n", context); + exit(1); } - } else { + } else if (security_canonicalize_context_raw(context, &tmpcon) == 0) { free(context); *contextp = tmpcon; + } else if (errno != ENOENT) { + rc = -1; + inc_err(); } - if (!valid) { - fprintf(stderr, "%s: line %u has invalid context %s\n", - path, lineno, context); - - /* Exit immediately if we're in checking mode. */ - if (policyfile) - exit(1); - } - - return !valid; + return rc; } static int pre_stat(const char *file_unused __attribute__ ((unused)), @@ -557,10 +692,9 @@ out: if (add_assoc) { - set_matchpathcon_printf(&qprintf); - matchpathcon_filespec_eval(); - set_matchpathcon_printf(NULL); - matchpathcon_filespec_destroy(); + if (!quiet) + filespec_eval(); + filespec_destroy(); } return rc; @@ -605,14 +739,20 @@ int main(int argc, char **argv) { struct stat sb; - int opt, rc, i = 0; + int opt, i = 0; char *input_filename = NULL; int use_input_file = 0; char *buf = NULL; size_t buf_len; char *base; + struct selinux_opt opts[] = { + { SELABEL_OPT_VALIDATE, NULL }, + { SELABEL_OPT_BASEONLY, NULL }, + { SELABEL_OPT_PATH, NULL } + }; memset(excludeArray, 0, sizeof(excludeArray)); + altpath = NULL; progname = strdup(argv[0]); if (!progname) { @@ -637,7 +777,7 @@ abort_on_error = 1; add_assoc = 1; nftw_flags = FTW_PHYS | FTW_MOUNT; - matchpathcon_flags = MATCHPATHCON_VALIDATE | MATCHPATHCON_NOTRANS; + ctx_validate = 1; } else { /* * restorecon: @@ -648,15 +788,15 @@ * Follows mounts, * Does lazy validation of contexts upon use. */ - if (strcmp(base, RESTORECON)) - qprintf("Executed with an unrecognized name (%s), defaulting to %s behavior.\n", base, RESTORECON); + if (strcmp(base, RESTORECON) && !quiet) + printf("Executed with an unrecognized name (%s), defaulting to %s behavior.\n", base, RESTORECON); iamrestorecon = 1; recurse = 0; expand_realpath = 1; abort_on_error = 0; add_assoc = 0; nftw_flags = FTW_PHYS; - matchpathcon_flags = MATCHPATHCON_NOTRANS; + ctx_validate = 0; /* restorecon only: silent exit if no SELinux. Allows unconditional execution by scripts. */ @@ -664,8 +804,6 @@ exit(0); } - set_matchpathcon_flags(matchpathcon_flags); - /* Process any options. */ while ((opt = getopt(argc, argv, "c:de:f:ilnpqrsvo:FRW")) > 0) { switch (opt) { @@ -700,9 +838,8 @@ /* Only process the specified file_contexts file, not any .homedirs or .local files, and do not perform context translations. */ - set_matchpathcon_flags(MATCHPATHCON_BASEONLY | - MATCHPATHCON_NOTRANS | - MATCHPATHCON_VALIDATE); + base_only = 1; + ctx_validate = 1; break; } @@ -812,7 +949,8 @@ /* Use our own invalid context checking function so that we can support either checking against the active policy or checking against a binary policy file. */ - set_matchpathcon_canoncon(&canoncon); + selinux_set_callback(SELINUX_CB_VALIDATE, + (union selinux_callback)&canoncon); if (stat(argv[optind], &sb) < 0) { perror(argv[optind]); @@ -824,19 +962,24 @@ exit(1); } - /* Load the file contexts configuration and check it. */ - rc = matchpathcon_init(argv[optind]); - if (rc < 0) { - perror(argv[optind]); - exit(1); - } - + altpath = argv[optind]; optind++; + } - if (nerr) - exit(1); + /* Load the file contexts configuration and check it. */ + opts[0].value = (char *)ctx_validate; + opts[1].value = (char *)base_only; + opts[2].value = altpath; + + hnd = selabel_open(SELABEL_CTX_FILE, opts, 3); + if (!hnd) { + perror(altpath); + exit(1); } + if (nerr) + exit(1); + if (use_input_file) { FILE *f = stdin; ssize_t len; @@ -863,8 +1006,10 @@ maybe_audit_mass_relabel(); if (warn_no_match) - matchpathcon_checkmatches(argv[0]); + selabel_stats(hnd); + selabel_close(hnd); + if (outfile) fclose(outfile); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ssm...@us...> - 2008-05-16 13:06:33
|
Revision: 2880 http://selinux.svn.sourceforge.net/selinux/?rev=2880&view=rev Author: ssmalley Date: 2008-05-16 06:06:26 -0700 (Fri, 16 May 2008) Log Message: ----------- Author: Stephen Smalley Email: sd...@ty... Subject: livecd-creator + selinux Date: Fri, 16 May 2008 07:57:38 -0400 On Thu, 2008-05-15 at 17:20 -0400, Eric Paris wrote: > On Thu, 2008-05-15 at 16:47 -0400, Stephen Smalley wrote: > > On Thu, 2008-05-15 at 16:33 -0400, Eric Paris wrote: > > > #4 At the end of the rpm transaction when everything is installed it > > > calls restorecon and I get one for (I assume) every file almost all of > > > which look like: > > > > > > /sbin/restorecon reset /srv context system_u:object_r:var_t:s0->system_u:object_r:var_t:s0 > > > > > > Notice nothing changed? Again I assume its my hack of a /selinux which > > > causes it and I'll try to run down why, but maybe someone else sees that > > > quickly. > > > > That suggests it is being called with the -f (force) flag from > > e.g. /sbin/fixfiles. selinux-policy.spec does a > > fixfiles -C file_contexts.pre restore > > > > fixfiles -C does a diff between the old and new file contexts > > configurations and applies restorecon to the result. There is some > > serious magic in there, and it is all Dan's fault ;) > > ok, in the livecd-creator kickstart.py I see > > if os.path.exists(self.path("/sbin/restorecon")): > self.call(["/sbin/restorecon", "-l", "-v", "-r", "-F", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/selinux", "/"]) > > So there is our -F. Is there a way to get it to fix "user" without > getting it to fix "things that aren't wrong" I think we should change setfiles/restorecon to just not do that even with -F. IIRC, changing it to always invoke setfilecon even if the contexts were the same was motivated by the problem we used to have where the in-core label and the on-disk xattr could get out of sync. Patch below. Note that restorecon is just a link to setfiles that presents a different default user interface and behaviors (ever since I coalesced them). Modified Paths: -------------- trunk/policycoreutils/setfiles/setfiles.c Modified: trunk/policycoreutils/setfiles/setfiles.c =================================================================== --- trunk/policycoreutils/setfiles/setfiles.c 2008-05-05 15:23:37 UTC (rev 2879) +++ trunk/policycoreutils/setfiles/setfiles.c 2008-05-16 13:06:26 UTC (rev 2880) @@ -495,7 +495,7 @@ * specification. */ if ((strcmp(newcon, "<<none>>") == 0) || - (context && (strcmp(context, newcon) == 0) && !force)) { + (context && (strcmp(context, newcon) == 0))) { freecon(context); goto out; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |