int _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutex_attr) { struct pthread_mutex_attr mattr, *mattrp; if ((mutex_attr == NULL) || (*mutex_attr == NULL)) return (__pthread_mutex_init(mutex, &static_mattr)); else { mattr = **mutex_attr; mattr.m_flags |= MUTEX_FLAGS_PRIVATE; mattrp = &mattr; return (__pthread_mutex_init(mutex, &mattrp)); } }
struct regex_data *regex_data_create(void) { struct regex_data *regex_data = (struct regex_data *)calloc(1, sizeof(struct regex_data)); __pthread_mutex_init(®ex_data->match_mutex, NULL); return regex_data; }
/* opendir just makes an open() call - it return NULL if it fails * (open sets errno), otherwise it returns a DIR * pointer. */ DIR *opendir(const char *name) { int fd; struct stat statbuf; DIR *ptr; #ifndef O_DIRECTORY /* O_DIRECTORY is linux specific and has been around since like 2.1.x */ if (stat(name, &statbuf)) return NULL; if (!S_ISDIR(statbuf.st_mode)) { __set_errno(ENOTDIR); return NULL; } # define O_DIRECTORY 0 #endif if ((fd = open(name, O_RDONLY|O_NDELAY|O_DIRECTORY)) < 0) return NULL; /* Note: we should check to make sure that between the stat() and open() * call, 'name' didnt change on us, but that's only if O_DIRECTORY isnt * defined and since Linux has supported it for like ever, i'm not going * to worry about it right now (if ever). */ if (fstat(fd, &statbuf) < 0) goto close_and_ret; /* According to POSIX, directory streams should be closed when * exec. From "Anna Pluzhnikov" <*****@*****.**>. */ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { int saved_errno; close_and_ret: saved_errno = errno; close(fd); __set_errno(saved_errno); return NULL; } if (!(ptr = malloc(sizeof(*ptr)))) goto nomem_close_and_ret; ptr->dd_fd = fd; ptr->dd_nextloc = ptr->dd_size = ptr->dd_nextoff = 0; ptr->dd_max = statbuf.st_blksize; if (ptr->dd_max < 512) ptr->dd_max = 512; if (!(ptr->dd_buf = calloc(1, ptr->dd_max))) { free(ptr); nomem_close_and_ret: close(fd); __set_errno(ENOMEM); return NULL; } __pthread_mutex_init(&(ptr->dd_lock), NULL); return ptr; }
void __fresetlockfiles (void) { #ifdef USE_IN_LIBIO _IO_ITER i; pthread_mutexattr_t attr; __pthread_mutexattr_init (&attr); __pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE_NP); for (i = _IO_iter_begin(); i != _IO_iter_end(); i = _IO_iter_next(i)) __pthread_mutex_init (_IO_iter_file(i)->_lock, &attr); __pthread_mutexattr_destroy (&attr); _IO_list_resetlock(); #endif }
static int load_mmap(FILE *fp, size_t len, struct selabel_handle *rec, const char *path) { struct saved_data *data = (struct saved_data *)rec->data; int rc; char *addr, *str_buf; int *stem_map; struct mmap_area *mmap_area; uint32_t i, magic, version; uint32_t entry_len, stem_map_len, regex_array_len; const char *reg_version; const char *reg_arch; char reg_arch_matches = 0; mmap_area = malloc(sizeof(*mmap_area)); if (!mmap_area) { return -1; } addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fileno(fp), 0); if (addr == MAP_FAILED) { free(mmap_area); perror("mmap"); return -1; } /* save where we mmap'd the file to cleanup on close() */ mmap_area->addr = mmap_area->next_addr = addr; mmap_area->len = mmap_area->next_len = len; mmap_area->next = data->mmap_areas; data->mmap_areas = mmap_area; /* check if this looks like an fcontext file */ rc = next_entry(&magic, mmap_area, sizeof(uint32_t)); if (rc < 0 || magic != SELINUX_MAGIC_COMPILED_FCONTEXT) return -1; /* check if this version is higher than we understand */ rc = next_entry(&version, mmap_area, sizeof(uint32_t)); if (rc < 0 || version > SELINUX_COMPILED_FCONTEXT_MAX_VERS) return -1; reg_version = regex_version(); if (!reg_version) return -1; reg_arch = regex_arch_string(); if (!reg_arch) return -1; if (version >= SELINUX_COMPILED_FCONTEXT_PCRE_VERS) { len = strlen(reg_version); rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0) return -1; /* Check version lengths */ if (len != entry_len) return -1; /* Check if regex version mismatch */ str_buf = malloc(entry_len + 1); if (!str_buf) return -1; rc = next_entry(str_buf, mmap_area, entry_len); if (rc < 0) { free(str_buf); return -1; } str_buf[entry_len] = '\0'; if ((strcmp(str_buf, reg_version) != 0)) { free(str_buf); return -1; } free(str_buf); if (version >= SELINUX_COMPILED_FCONTEXT_REGEX_ARCH) { len = strlen(reg_arch); rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0) return -1; /* Check arch string lengths */ if (len != entry_len) { /* * Skip the entry and conclude that we have * a mismatch, which is not fatal. */ next_entry(NULL, mmap_area, entry_len); goto end_arch_check; } /* Check if arch string mismatch */ str_buf = malloc(entry_len + 1); if (!str_buf) return -1; rc = next_entry(str_buf, mmap_area, entry_len); if (rc < 0) { free(str_buf); return -1; } str_buf[entry_len] = '\0'; reg_arch_matches = strcmp(str_buf, reg_arch) == 0; free(str_buf); } } end_arch_check: /* allocate the stems_data array */ rc = next_entry(&stem_map_len, mmap_area, sizeof(uint32_t)); if (rc < 0) return -1; /* * map indexed by the stem # in the mmap file and contains the stem * number in the data stem_arr */ stem_map = calloc(stem_map_len, sizeof(*stem_map)); if (!stem_map) return -1; for (i = 0; i < stem_map_len; i++) { char *buf; uint32_t stem_len; int newid; /* the length does not inlude the nul */ rc = next_entry(&stem_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !stem_len) { rc = -1; goto out; } /* Check for stem_len wrap around. */ if (stem_len < UINT32_MAX) { buf = (char *)mmap_area->next_addr; /* Check if over-run before null check. */ rc = next_entry(NULL, mmap_area, (stem_len + 1)); if (rc < 0) goto out; if (buf[stem_len] != '\0') { rc = -1; goto out; } } else { rc = -1; goto out; } /* store the mapping between old and new */ newid = find_stem(data, buf, stem_len); if (newid < 0) { newid = store_stem(data, buf, stem_len); if (newid < 0) { rc = newid; goto out; } data->stem_arr[newid].from_mmap = 1; } stem_map[i] = newid; } /* allocate the regex array */ rc = next_entry(®ex_array_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !regex_array_len) { rc = -1; goto out; } for (i = 0; i < regex_array_len; i++) { struct spec *spec; int32_t stem_id, meta_chars; uint32_t mode = 0, prefix_len = 0; rc = grow_specs(data); if (rc < 0) goto out; spec = &data->spec_arr[data->nspec]; spec->from_mmap = 1; /* Process context */ rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !entry_len) { rc = -1; goto out; } str_buf = malloc(entry_len); if (!str_buf) { rc = -1; goto out; } rc = next_entry(str_buf, mmap_area, entry_len); if (rc < 0) { free(str_buf); goto out; } if (str_buf[entry_len - 1] != '\0') { free(str_buf); rc = -1; goto out; } spec->lr.ctx_raw = str_buf; if (strcmp(spec->lr.ctx_raw, "<<none>>") && rec->validating) { if (selabel_validate(rec, &spec->lr) < 0) { selinux_log(SELINUX_ERROR, "%s: context %s is invalid\n", path, spec->lr.ctx_raw); goto out; } } /* Process regex string */ rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !entry_len) { rc = -1; goto out; } spec->regex_str = (char *)mmap_area->next_addr; rc = next_entry(NULL, mmap_area, entry_len); if (rc < 0) goto out; if (spec->regex_str[entry_len - 1] != '\0') { rc = -1; goto out; } /* Process mode */ if (version >= SELINUX_COMPILED_FCONTEXT_MODE) rc = next_entry(&mode, mmap_area, sizeof(uint32_t)); else rc = next_entry(&mode, mmap_area, sizeof(mode_t)); if (rc < 0) goto out; spec->mode = mode; /* map the stem id from the mmap file to the data->stem_arr */ rc = next_entry(&stem_id, mmap_area, sizeof(int32_t)); if (rc < 0) goto out; if (stem_id < 0 || stem_id >= (int32_t)stem_map_len) spec->stem_id = -1; else spec->stem_id = stem_map[stem_id]; /* retrieve the hasMetaChars bit */ rc = next_entry(&meta_chars, mmap_area, sizeof(uint32_t)); if (rc < 0) goto out; spec->hasMetaChars = meta_chars; /* and prefix length for use by selabel_lookup_best_match */ if (version >= SELINUX_COMPILED_FCONTEXT_PREFIX_LEN) { rc = next_entry(&prefix_len, mmap_area, sizeof(uint32_t)); if (rc < 0) goto out; spec->prefix_len = prefix_len; } rc = regex_load_mmap(mmap_area, &spec->regex, reg_arch_matches, &spec->regex_compiled); if (rc < 0) goto out; __pthread_mutex_init(&spec->regex_lock, NULL); data->nspec++; } rc = 0; out: free(stem_map); return rc; }