From 07da577db278027eec43993be14aeec427101e28 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Tue, 29 Mar 2005 15:33:55 +0000 Subject: [PATCH] - Better handling of booleans --- libselinux-rhat.patch | 487 ++++++++++++++++++++++++++++++++++++++++-- libselinux.spec | 7 +- 2 files changed, 479 insertions(+), 15 deletions(-) diff --git a/libselinux-rhat.patch b/libselinux-rhat.patch index 5802d28..ddf8cb5 100644 --- a/libselinux-rhat.patch +++ b/libselinux-rhat.patch @@ -1,15 +1,474 @@ -diff --exclude-from=exclude -N -u -r nsalibselinux/src/matchpathcon.c libselinux-1.21.11/src/matchpathcon.c ---- nsalibselinux/src/matchpathcon.c 2005-02-22 16:34:17.000000000 -0500 -+++ libselinux-1.21.11/src/matchpathcon.c 2005-02-28 13:27:33.000000000 -0500 -@@ -679,6 +679,11 @@ - mode_t mode, - security_context_t *con) - { -+ /* If the user provides a mode but does not provide a file type -+ default to regular file */ -+ if (mode && ((mode & S_IFMT)==0)) { -+ mode = mode | S_IFREG; -+ } - int i = matchpathcon_common(name, mode); +diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/selinux.h libselinux-1.23.2/include/selinux/selinux.h +--- nsalibselinux/include/selinux/selinux.h 2005-03-17 10:34:51.000000000 -0500 ++++ libselinux-1.23.2/include/selinux/selinux.h 2005-03-28 15:02:16.000000000 -0500 +@@ -136,6 +136,16 @@ + /* Load a policy configuration. */ + extern int security_load_policy(void *data, size_t len); - if (i < 0) ++/* Translate boolean strict to name value pair. */ ++typedef struct { ++ char *name; ++ int value; ++} SELboolean; ++ /* save a list of booleans in a single transaction. */ ++extern int security_set_boolean_list(size_t boolcnt, ++ SELboolean *boollist, ++ int permanent); ++ + /* Load policy boolean settings. + Path may be NULL, in which case the booleans are loaded from + the active policy boolean configuration file. */ +diff --exclude-from=exclude -N -u -r nsalibselinux/src/booleans.c libselinux-1.23.2/src/booleans.c +--- nsalibselinux/src/booleans.c 2004-11-09 09:13:54.000000000 -0500 ++++ libselinux-1.23.2/src/booleans.c 2005-03-29 10:29:50.000000000 -0500 +@@ -238,51 +238,198 @@ + dest[i+1]='\0'; + return dest; + } ++static int process_boolean(char *buffer, char *name, int namesize, int *val) { ++ char name1[BUFSIZ]; ++ char *ptr; ++ char *tok=strtok_r(buffer,"=",&ptr); ++ if (tok) { ++ strncpy(name1,tok, BUFSIZ-1); ++ strtrim(name,name1,namesize-1); ++ if ( name[0]=='#' ) return 0; ++ tok=strtok_r(NULL,"\0",&ptr); ++ if (tok) { ++ while (isspace(*tok)) tok++; ++ *val = -1; ++ if (isdigit(tok[0])) ++ *val=atoi(tok); ++ else if (!strncasecmp(tok, "true", sizeof("true")-1)) ++ *val = 1; ++ else if (!strncasecmp(tok, "false", sizeof("false")-1)) ++ *val = 0; ++ if (*val != 0 && *val != 1) { ++ errno=EINVAL; ++ return -1; ++ } ++ ++ } ++ } ++ return 1; ++} ++static int save_booleans(size_t boolcnt, SELboolean *boollist) { ++ ssize_t len; ++ size_t i; ++ char outbuf[BUFSIZ]; ++ char *inbuf=NULL; ++ ++ /* Open file */ ++ const char *bool_file = selinux_booleans_path(); ++ char local_bool_file[PATH_MAX]; ++ char tmp_bool_file[PATH_MAX]; ++ FILE *boolf; ++ int fd; ++ int *used= (int *) malloc (sizeof(int) * boolcnt); ++ if (! used) { ++ return -1; ++ } ++ /* zero out used field */ ++ for (i=0; i < boolcnt; i++) ++ used[i]=0; ++ ++ ++ snprintf(tmp_bool_file,sizeof(tmp_bool_file),"%s.XXXXXX", bool_file); ++ fd = mkstemp(tmp_bool_file); ++ if (fd < 0) { ++ free(used); ++ return -1; ++ } ++ ++ snprintf(local_bool_file,sizeof(local_bool_file),"%s.local", bool_file); boolf = fopen(local_bool_file,"r"); ++ if (boolf != NULL) { ++ ssize_t ret; ++ size_t size=0; ++ int val; ++ char boolname[BUFSIZ]; ++ char *buffer; ++ char *inbuf=NULL; ++ while ((len=getline(&inbuf, &size, boolf)) > 0) { ++ buffer=strdup(inbuf); ++ if (!buffer) goto close_remove_fail; ++ ret=process_boolean(inbuf, boolname, sizeof(boolname), &val); ++ if (ret!=1) { ++ ret=write(fd, buffer, len); ++ free(buffer); ++ if (ret != len) ++ goto close_remove_fail; ++ } else { ++ free(buffer); ++ for (i=0; i < boolcnt; i++) { ++ if (strcmp(boollist[i].name, boolname)==0) { ++ snprintf(outbuf,sizeof(outbuf), "%s=%d\n", boolname, boollist[i].value); ++ len=strlen(outbuf); ++ used[i]=1; ++ if (write(fd, outbuf, len) != len) ++ goto close_remove_fail; ++ else ++ break; ++ } ++ } ++ if ( i == boolcnt ) { ++ snprintf(outbuf,sizeof(outbuf), "%s=%d\n", boolname, val); ++ len=strlen(outbuf); ++ if (write(fd, outbuf, len) != len) ++ goto close_remove_fail; ++ } ++ } ++ free(inbuf); ++ inbuf=NULL; ++ } ++ fclose(boolf); ++ } ++ ++ for (i=0; i < boolcnt; i++) { ++ if (used[i]==0) { ++ snprintf(outbuf,sizeof(outbuf), "%s=%d\n", boollist[i].name, boollist[i].value); ++ len=strlen(outbuf); ++ if (write(fd, outbuf, len) != len) { ++ close_remove_fail: ++ free(inbuf); ++ close(fd); ++ remove_fail: ++ unlink(tmp_bool_file); ++ free(used); ++ return -1; ++ } ++ } ++ ++ } ++ if (fchmod(fd, S_IRUSR | S_IWUSR) != 0) ++ goto close_remove_fail; ++ close(fd); ++ if (rename(tmp_bool_file, local_bool_file) != 0) ++ goto remove_fail; ++ ++ free(used); ++ return 0; ++} ++static void rollback(SELboolean *boollist, int end) ++{ ++ int i; ++ ++ for(i=0; i 0) { ++ int ret=process_boolean(inbuf, name, sizeof(name), &val); ++ if (ret==-1) ++ errors++; ++ if (ret==1) ++ if (security_set_boolean(name, val) < 0) { ++ errors++; ++ } ++ } ++ fclose(boolf); ++ ++ snprintf(localbools,sizeof(localbools), "%s.local", (path ? path : selinux_booleans_path())); ++ boolf = fopen(localbools,"r"); + ++ if (boolf != NULL) { ++ int ret; ++ while (getline(&inbuf, &len, boolf) > 0) { ++ ret=process_boolean(inbuf, name, sizeof(name), &val); ++ if (ret==-1) ++ errors++; ++ if (ret==1) + if (security_set_boolean(name, val) < 0) { +- fprintf(stderr,"error setting boolean %s to value %d \n", name, val); + errors++; + } +- } + } ++ fclose(boolf); + } +- fclose(boolf); +- + if (security_commit_booleans() < 0) + return -1; + +diff --exclude-from=exclude -N -u -r nsalibselinux/src/matchmediacon.c libselinux-1.23.2/src/matchmediacon.c +--- nsalibselinux/src/matchmediacon.c 2004-10-20 16:31:36.000000000 -0400 ++++ libselinux-1.23.2/src/matchmediacon.c 2005-03-28 16:44:29.000000000 -0500 +@@ -16,7 +16,7 @@ + { + const char *path = selinux_media_context_path(); + FILE *infile; +- char *ptr, *ptr2; ++ char *ptr, *ptr2=NULL; + int found=-1; + char current_line[PATH_MAX]; + if ((infile = fopen(path, "r")) == NULL) +diff --exclude-from=exclude -N -u -r nsalibselinux/src/matchpathcon.c libselinux-1.23.2/src/matchpathcon.c +--- nsalibselinux/src/matchpathcon.c 2005-03-17 10:34:51.000000000 -0500 ++++ libselinux-1.23.2/src/matchpathcon.c 2005-03-28 16:45:06.000000000 -0500 +@@ -531,7 +531,7 @@ + char *line_buf = NULL; + size_t line_len = 0; + unsigned int lineno, pass, i, j, maxnspec; +- spec_t *spec_copy; ++ spec_t *spec_copy=NULL; + int status=-1; + + /* Open the specification file. */ +diff --exclude-from=exclude -N -u -r nsalibselinux/utils/setenforce.c libselinux-1.23.2/utils/setenforce.c +--- nsalibselinux/utils/setenforce.c 2005-01-20 16:05:25.000000000 -0500 ++++ libselinux-1.23.2/utils/setenforce.c 2005-03-28 14:47:58.000000000 -0500 +@@ -13,7 +13,7 @@ + + int main(int argc, char **argv) + { +- int rc; ++ int rc=0; + if (argc != 2) { + usage(argv[0]); + } +diff --exclude-from=exclude -N -u -r nsalibselinux/utils/setsebool.c libselinux-1.23.2/utils/setsebool.c +--- nsalibselinux/utils/setsebool.c 2005-02-22 16:34:17.000000000 -0500 ++++ libselinux-1.23.2/utils/setsebool.c 2005-03-28 16:45:42.000000000 -0500 +@@ -8,11 +8,11 @@ + #include + #include + #include ++#include + + int permanent = 0; + +-int setbool(char **list, int start, int end); +-void rollback(char *list[], int start, int end); ++int setbool(char **list, size_t start, size_t end); + + + void usage(void) +@@ -23,7 +23,7 @@ + + int main(int argc, char **argv) + { +- int rc, start; ++ size_t rc, start; + + if (argc < 2) + usage(); +@@ -72,12 +72,20 @@ + + /* Given an array of strings in the form "boolname=value", a start index, + and a finish index...walk the list and set the bool. */ +-int setbool(char **list, int start, int end) ++int setbool(char **list, size_t start, size_t end) + { + char *name, *value_ptr; + int i=start, value; ++ int ret=0; ++ int j=0; ++ size_t boolcnt=end-start; + struct passwd *pwd; +- ++ SELboolean *vallist=calloc(boolcnt, sizeof(SELboolean)); ++ if (!vallist) { ++ fprintf(stderr, ++ "Error setting booleans: %s\n", strerror(errno)); ++ return 1; ++ } + while (i < end) { + name = list[i]; + value_ptr = strchr(list[i], '='); +@@ -85,8 +93,8 @@ + fprintf(stderr, + "setsebool: '=' not found in boolean expression %s\n", + list[i]); +- rollback(list, start, i); +- return 4; ++ ret=4; ++ goto error_label; + } + *value_ptr = 0; + value_ptr++; +@@ -99,92 +107,43 @@ + else { + fprintf(stderr, "setsebool: illegal boolean value %s\n", + value_ptr); +- rollback(list, start, i); +- return 1; ++ ret=1; ++ goto error_label; + } + +- if(security_set_boolean(name, value)) { ++ vallist[j].value = value; ++ vallist[j].name = strdup(name); ++ if (!vallist[j].name) { + fprintf(stderr, + "Error setting boolean %s to value %d (%s)\n", + name, value, strerror(errno)); +- rollback(list, start, i); +- return 2; ++ ret= 2; ++ goto error_label; + } + i++; ++ j++; + + /* Now put it back */ + value_ptr--; + *value_ptr = '='; + } + +- /* At this point we know that everything is good. Let's write +- the file if the -P option was given. */ +- if (permanent) { +- char **names; +- const char *bool_file; +- char *tmp_bool_file; +- int rc, len, fd, j; +- +- rc = security_get_boolean_names(&names, &len); +- if (rc) { +- fprintf(stderr, +- "Unable to get boolean names: %s\n", +- strerror(errno)); +- rollback(list, start, i); +- return 5; +- } ++ ret=security_set_boolean_list(boolcnt, vallist, permanent); + +- if (!len) { +- fprintf(stderr, +- "Unable to get the boolean list from kernel - exiting\n" +- ); +- rollback(list, start, i); +- return 6; +- } ++ error_label: ++ for (i=0; i < boolcnt; i++) ++ if (vallist[i].name) free(vallist[i].name); ++ free(vallist); + +- /* Open file */ +- bool_file = selinux_booleans_path(); +- tmp_bool_file = (char *) alloca (strlen(bool_file) + 8); +- strcpy(stpcpy(tmp_bool_file, bool_file), ".XXXXXX"); +- fd = mkstemp(tmp_bool_file); +- if (fd < 0) { ++ if (ret) { ++ if (errno==ENOENT) { + fprintf(stderr, +- "Error creating boolean file %s\n", +- bool_file); +- rollback(list, start, i); +- return 7; +- ++ "Error setting boolean: Invalid boolean\n"); ++ } else { ++ if (errno) ++ perror("Error setting booleans"); + } +- +- /* Walk the list in pending memory, writing each to the file */ +- for (j=0; j 1.23.2-2 +- Better handling of booleans + * Thu Mar 17 2005 Dan Walsh 1.23.2-1 - Update from NSA * Merged destructors patch from Tomas Mraz.