Пример #1
0
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));
	}
}
Пример #2
0
struct regex_data *regex_data_create(void)
{
	struct regex_data *regex_data =
		(struct regex_data *)calloc(1, sizeof(struct regex_data));
	__pthread_mutex_init(&regex_data->match_mutex, NULL);
	return regex_data;
}
Пример #3
0
/* 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;
}
Пример #4
0
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
}
Пример #5
0
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(&regex_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;
}