X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=selinux%2Fsetfiles.c;h=ca3fd93618b8e6e92f80f6927be4ae504e38edc3;hb=cfbd31a7fb0a2e76864432823da1aa956fbdfa25;hp=42207fcfbf288bd8af08727bc09b5abdd5ab254e;hpb=397137b8158298cae14efae330abc57ba11630a5;p=oweals%2Fbusybox.git diff --git a/selinux/setfiles.c b/selinux/setfiles.c index 42207fcfb..ca3fd9361 100644 --- a/selinux/setfiles.c +++ b/selinux/setfiles.c @@ -1,9 +1,49 @@ /* setfiles: based on policycoreutils 2.0.19 policycoreutils was released under GPL 2. - Port to BusyBox by 2007 Yuichi Nakamura + Port to BusyBox (c) 2007 by Yuichi Nakamura */ +//usage:#define setfiles_trivial_usage +//usage: "[-dnpqsvW] [-e DIR]... [-o FILE] [-r alt_root_path]" +//usage: IF_FEATURE_SETFILES_CHECK_OPTION( +//usage: " [-c policyfile] spec_file" +//usage: ) +//usage: " pathname" +//usage:#define setfiles_full_usage "\n\n" +//usage: "Reset file contexts under pathname according to spec_file\n" +//usage: IF_FEATURE_SETFILES_CHECK_OPTION( +//usage: "\n -c FILE Check the validity of the contexts against the specified binary policy" +//usage: ) +//usage: "\n -d Show which specification matched each file" +//usage: "\n -l Log changes in file labels to syslog" +//usage: "\n -n Don't change any file labels" +//usage: "\n -q Suppress warnings" +//usage: "\n -r DIR Use an alternate root path" +//usage: "\n -e DIR Exclude DIR" +//usage: "\n -F Force reset of context to match file_context for customizable files" +//usage: "\n -o FILE Save list of files with incorrect context" +//usage: "\n -s Take a list of files from stdin (instead of command line)" +//usage: "\n -v Show changes in file labels, if type or role are changing" +//usage: "\n -vv Show changes in file labels, if type, role, or user are changing" +//usage: "\n -W Display warnings about entries that had no matching files" +//usage: +//usage:#define restorecon_trivial_usage +//usage: "[-iFnRv] [-e EXCLUDEDIR]... [-o FILE] [-f FILE]" +//usage:#define restorecon_full_usage "\n\n" +//usage: "Reset security contexts of files in pathname\n" +//usage: "\n -i Ignore files that don't exist" +//usage: "\n -f FILE File with list of files to process" +//usage: "\n -e DIR Directory to exclude" +//usage: "\n -R,-r Recurse" +//usage: "\n -n Don't change any file labels" +//usage: "\n -o FILE Save list of files with incorrect context" +//usage: "\n -v Verbose" +//usage: "\n -vv Show changed labels" +//usage: "\n -F Force reset of context to match file_context" +//usage: "\n for customizable files, or the user section," +//usage: "\n if it has changed" + #include "libbb.h" #if ENABLE_FEATURE_SETFILES_CHECK_OPTION #include @@ -25,14 +65,6 @@ struct globals { int excludeCtr; int errors; int verbose; /* getopt32 uses it, has to be int */ - //smallint force; - //smallint progress; - //smallint debug; - //smallint dry_run; - //smallint quiet; - //smallint ignore_enoent; - //smallint take_log; - //smallint warn_no_match; smallint recurse; /* Recursive descent */ smallint follow_mounts; /* Behavior flags determined based on setfiles vs. restorecon */ @@ -43,8 +75,7 @@ struct globals { dev_t dev_id; /* Device id where target file exists */ int nerr; struct edir excludeArray[MAX_EXCLUDES]; -}; - +} FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) void BUG_setfiles_globals_too_big(void); #define INIT_G() do { \ @@ -60,14 +91,6 @@ void BUG_setfiles_globals_too_big(void); #define excludeCtr (G.excludeCtr ) #define errors (G.errors ) #define verbose (G.verbose ) -//#define force (G.force ) -//#define progress (G.progress ) -//#define debug (G.debug ) -//#define dry_run (G.dry_run ) -//#define quiet (G.quiet ) -//#define ignore_enoent (G.ignore_enoent ) -//#define take_log (G.take_log ) -//#define warn_no_match (G.warn_no_match ) #define recurse (G.recurse ) #define follow_mounts (G.follow_mounts ) #define expand_realpath (G.expand_realpath ) @@ -115,7 +138,7 @@ enum { #define FLAG_R (option_mask32 & OPT_R) -static void qprintf(const char *fmt, ...) +static void qprintf(const char *fmt UNUSED_PARAM, ...) { /* quiet, do nothing */ } @@ -128,27 +151,25 @@ static void inc_err(void) } } -static int add_exclude(const char *directory) +static void add_exclude(const char *directory) { struct stat sb; - size_t len = 0; + size_t len; if (directory == NULL || directory[0] != '/') { - bb_error_msg("full path required for exclude: %s", directory); - return 1; + bb_error_msg_and_die("full path required for exclude: %s", directory); } if (lstat(directory, &sb)) { bb_error_msg("directory \"%s\" not found, ignoring", directory); - return 0; + return; } if ((sb.st_mode & S_IFDIR) == 0) { bb_error_msg("\"%s\" is not a directory: mode %o, ignoring", directory, sb.st_mode); - return 0; + return; } if (excludeCtr == MAX_EXCLUDES) { - bb_error_msg("maximum excludes %d exceeded", MAX_EXCLUDES); - return 1; + bb_error_msg_and_die("maximum excludes %d exceeded", MAX_EXCLUDES); } len = strlen(directory); @@ -157,11 +178,9 @@ static int add_exclude(const char *directory) } excludeArray[excludeCtr].directory = xstrndup(directory, len); excludeArray[excludeCtr++].size = len; - - return 0; } -static int exclude(const char *file) +static bool exclude(const char *file) { int i = 0; for (i = 0; i < excludeCtr; i++) { @@ -182,10 +201,8 @@ static int match(const char *name, struct stat *sb, char **con) char path[PATH_MAX + 1]; char *tmp_path = xstrdup(name); - if (excludeCtr > 0) { - if (exclude(name)) { - goto err; - } + if (excludeCtr > 0 && exclude(name)) { + goto err; } ret = lstat(name, sb); if (ret) { @@ -210,7 +227,7 @@ static int match(const char *name, struct stat *sb, char **con) file_sep = strrchr(tmp_path, '/'); if (file_sep == tmp_path) { file_sep++; - p[0] = '\0'; + path[0] = '\0'; p = path; } else if (file_sep) { *file_sep++ = '\0'; @@ -270,7 +287,7 @@ static int match(const char *name, struct stat *sb, char **con) /* Compare two contexts to see if their differences are "significant", * or whether the only difference is in the user. */ -static int only_changed_user(const char *a, const char *b) +static bool only_changed_user(const char *a, const char *b) { if (FLAG_F_force) return 0; @@ -285,36 +302,29 @@ static int only_changed_user(const char *a, const char *b) static int restore(const char *file) { - char *my_file = xstrdup(file); - char *my_file_orig = my_file; + char *my_file; struct stat my_sb; int i, j, ret; char *context = NULL; char *newcon = NULL; - int user_only_changed = 0; - size_t len = strlen(my_file); + bool user_only_changed = 0; int retval = 0; - /* Skip the extra slashes at the beginning and end, if present. */ - if (file[0] == '/' && file[1] == '/') - my_file++; - if (len > 1 && my_file[len - 1] == '/') - my_file[len - 1] = '\0'; + my_file = bb_simplify_path(file); i = match(my_file, &my_sb, &newcon); if (i < 0) /* No matching specification. */ goto out; - if (FLAG_p_progress) { count++; if (count % 0x400 == 0) { /* every 1024 times */ count = (count % (80*0x400)); if (count == 0) - fputc('\n', stdout); - fputc('*', stdout); - fflush(stdout); + bb_putchar('\n'); + bb_putchar('*'); + fflush_all(); } } @@ -375,7 +385,7 @@ static int restore(const char *file) * same. For "-vv", emit everything. */ if (verbose > 1 || !user_only_changed) { bb_info_msg("%s: reset %s context %s->%s", - applet_name, my_file, context ?: "", newcon); + applet_name, my_file, context ? context : "", newcon); } } @@ -407,7 +417,7 @@ static int restore(const char *file) out: freecon(context); freecon(newcon); - free(my_file_orig); + free(my_file); return retval; err: retval--; /* -1 */ @@ -419,8 +429,11 @@ static int restore(const char *file) * This function is called by recursive_action on each file during * the directory traversal. */ -static int apply_spec(const char *file, - struct stat *sb, void *userData, int depth) +static int FAST_FUNC apply_spec( + const char *file, + struct stat *sb, + void *userData UNUSED_PARAM, + int depth UNUSED_PARAM) { if (!follow_mounts) { /* setfiles does not process across different mount points */ @@ -437,7 +450,7 @@ static int apply_spec(const char *file, static int canoncon(const char *path, unsigned lineno, char **contextp) { - static const char err_msg[] = "%s: line %u has invalid context %s"; + static const char err_msg[] ALIGN1 = "%s: line %u has invalid context %s"; char *tmpcon; char *context = *contextp; @@ -514,13 +527,12 @@ static int process_one(char *name) goto out; } -int setfiles_main(int argc, char **argv); -int setfiles_main(int argc, char **argv) +int setfiles_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int setfiles_main(int argc UNUSED_PARAM, char **argv) { struct stat sb; int rc, i = 0; const char *input_filename = NULL; - int use_input_file = 0; char *buf = NULL; size_t buf_len; int flags; @@ -563,24 +575,25 @@ int setfiles_main(int argc, char **argv) set_matchpathcon_flags(matchpathcon_flags); - opt_complementary = "e::vv:v--p:p--v"; + opt_complementary = "e::vv:v--p:p--v:v--q:q--v"; /* Option order must match OPT_x definitions! */ if (applet_name[0] == 'r') { /* restorecon */ - flags = getopt32(argc, argv, "de:f:ilnpqrsvo:FWR", + flags = getopt32(argv, "de:f:ilnpqrsvo:FWR", &exclude_dir, &input_filename, &out_filename, &verbose); } else { /* setfiles */ - flags = getopt32(argc, argv, "de:f:ilnpqr:svo:FW" - USE_FEATURE_SETFILES_CHECK_OPTION("c:"), + flags = getopt32(argv, "de:f:ilnpqr:svo:FW" + IF_FEATURE_SETFILES_CHECK_OPTION("c:"), &exclude_dir, &input_filename, &rootpath, &out_filename, - USE_FEATURE_SETFILES_CHECK_OPTION(&policyfile,) + IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,) &verbose); } + argv += optind; #if ENABLE_FEATURE_SETFILES_CHECK_OPTION if ((applet_name[0] == 's') && (flags & OPT_c)) { FILE *policystream; - policystream = xfopen(policyfile, "r"); + policystream = xfopen_for_read(policyfile); if (sepol_set_policydb_from_file(policystream) < 0) { bb_error_msg_and_die("sepol_set_policydb_from_file on %s", policyfile); } @@ -595,39 +608,15 @@ int setfiles_main(int argc, char **argv) } #endif - //if (flags & OPT_d) { - // debug = 1; - //} - if (flags & OPT_e) { - if (exclude_dir == NULL) { - bb_show_usage(); - } - while (exclude_dir) { - if (add_exclude(llist_pop(&exclude_dir))) - exit(1); - } - } - //if (flags & OPT_i) { - // ignore_enoent = 1; - //} - //if (flags & OPT_l) { - // take_log = 1; - //} - //if (flags & OPT_F) { - // force = 1; - //} - //if (flags & OPT_n) { - // dry_run = 1; - //} + while (exclude_dir) + add_exclude(llist_pop(&exclude_dir)); + if (flags & OPT_o) { outfile = stdout; if (NOT_LONE_CHAR(out_filename, '-')) { - outfile = xfopen(out_filename, "w"); + outfile = xfopen_for_write(out_filename); } } - //if (flags & OPT_q) { - // quiet = 1; - //} if (applet_name[0] == 'r') { /* restorecon */ if (flags & (OPT_r | OPT_R)) recurse = 1; @@ -636,48 +625,37 @@ int setfiles_main(int argc, char **argv) rootpathlen = strlen(rootpath); } if (flags & OPT_s) { - use_input_file = 1; input_filename = "-"; add_assoc = 0; } - //if (flags & OPT_p) { - // progress = 1; - //} - //if (flags & OPT_W) { - // warn_no_match = 1; - //} if (applet_name[0] == 's') { /* setfiles */ /* 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); - if (argc == 1) + if (!argv[0]) bb_show_usage(); - if (stat(argv[optind], &sb) < 0) { - bb_perror_msg_and_die("%s", argv[optind]); - } + xstat(argv[0], &sb); if (!S_ISREG(sb.st_mode)) { - bb_error_msg_and_die("spec file %s is not a regular file", argv[optind]); + bb_error_msg_and_die("spec file %s is not a regular file", argv[0]); } /* Load the file contexts configuration and check it. */ - rc = matchpathcon_init(argv[optind]); + rc = matchpathcon_init(argv[0]); if (rc < 0) { - bb_perror_msg_and_die("%s", argv[optind]); + bb_simple_perror_msg_and_die(argv[0]); } - - optind++; - if (nerr) - exit(1); + exit(EXIT_FAILURE); + argv++; } - if (use_input_file) { + if (input_filename) { ssize_t len; FILE *f = stdin; if (NOT_LONE_CHAR(input_filename, '-')) - f = xfopen(input_filename, "r"); + f = xfopen_for_read(input_filename); while ((len = getline(&buf, &buf_len, f)) > 0) { buf[len - 1] = '\0'; errors |= process_one(buf); @@ -685,9 +663,9 @@ int setfiles_main(int argc, char **argv) if (ENABLE_FEATURE_CLEAN_UP) fclose_if_not_stdin(f); } else { - if (optind >= argc) + if (!argv[0]) bb_show_usage(); - for (i = optind; i < argc; i++) { + for (i = 0; argv[i]; i++) { errors |= process_one(argv[i]); } }