Beispiel #1
0
void brp_parse_config()
{
	/*
	 * Free memory associated with previous config parsing
	 */
	free_config();

	/*
	 * Ensure we're using a root-modifiable-only configuration file, just in case.
	 */
	if (!check_config_secure(CONFIG)) {
		fprintf(stderr, "brp: config file at "CONFIG" is not secure, refusing to continue.\n");
		exit(1);
	}

	int nsec;
	struct section *sec = parse_config(CONFIG, &nsec), *sec_curr = sec;

	if (sec == NULL)
		exit(1);

	size_t arrsz = 0;
	while(sec_curr) {
		if (strcmp(sec_curr->name, "stratum-order"))
			out_item_count += sec_curr->nent;
		else {
			arrsz = sec_curr->nent+1;
			stratum = calloc(sec_curr->nent+1, sizeof(void *));

			struct entry *e = sec_curr->e;
			while(e) {
				_add_stratum(&stratum, &arrsz, e->lhs);
				e = e->next;
			}
		}
		sec_curr = sec_curr->next;
	}

	struct dirent *dent;
	DIR *d = opendir("/bedrock/run/enabled_strata/");
	if (!d) {
		perror("Failed to list enabled strata");
		exit(1);
	}

	if (!arrsz) {
		arrsz = 1;
		stratum = calloc(1, sizeof(void *));
	}
	while((dent = readdir(d)))
		if (strncmp(dent->d_name, ".", 1) && strncmp(dent->d_name, "..", 2))
			_add_stratum(&stratum, &arrsz, dent->d_name);

	closedir(d);

	char **tmp_s = stratum;
	nstratum = 0;
	while(*tmp_s) {
		nstratum++;
		tmp_s++;
	}

	stratum_len = malloc(sizeof(size_t)*nstratum);

	for(int st = 0; st < nstratum; st++)
		stratum_len[st] = strlen(stratum[st]);

	out_items = malloc(out_item_count*sizeof(struct out_item));
	sec_curr = sec;

	int i = 0;
	int curr_filter = 0;
	while(sec_curr) {
		struct entry *e = sec_curr->e;
		if (strcmp(sec_curr->name, "pass") == 0) {
			curr_filter = FILTER_PASS;
		} else if (strcmp(sec_curr->name, "brc-wrap") == 0) {
			curr_filter = FILTER_BRC_WRAP;
		} else if (strcmp(sec_curr->name, "exec-filter") == 0) {
			curr_filter = FILTER_EXEC;
		} else if (strcmp(sec_curr->name, "stratum-order") == 0){
			sec_curr = sec_curr->next;
			continue;
		} else {
			fprintf(stderr, "brp: Failed to parse config\n");
			exit(1);
		}
		while(e) {
			/* get path */
			out_items[i].path = strdup(e->lhs);
			out_items[i].path_len = e->lhs_len;

			if (out_items[i].path[out_items[i].path_len-1] == '/') {
				out_items[i].file_type = FILE_TYPE_DIRECTORY;
				out_items[i].path[--out_items[i].path_len] = '\0';
			} else
				out_items[i].file_type = FILE_TYPE_NORMAL;

			out_items[i].filter = curr_filter;

			out_items[i].in_items = malloc(e->nrhs*sizeof(struct in_item));

			struct rhs *r = e->r;
			struct in_item *in_items = out_items[i].in_items;
			int j = 0;
			while(r) {
				in_items[j].stratum_id = -1;
				if (r->str[0] != '/') {
					// The in_path might start with a stratum
					// specification
					char *colon = strchr(r->str, ':');
					if (!colon || colon[1] != '/') {
						// Invalid path, just ignore
						r = r->next;
						continue;
					}
					in_items[j].path = strdup(colon+1);
					for (int st = 0; st < nstratum; st++)
						if (strncmp(r->str, stratum[st], colon-r->str) == 0) {
							in_items[j].stratum_id = st;
							break;
						}
					if (in_items[j].stratum_id == -1) {
						r = r->next;
						continue;
					}
				} else
					in_items[j].path = strdup(r->str);
				in_items[j].path_len = strlen(in_items[j].path);
				j++;

				r = r->next;
			}
			out_items[i].in_item_count = j;
			i++;
			e = e->next;
		}
		sec_curr = sec_curr->next;
	}

	free_sections(sec);
}
Beispiel #2
0
void
elf_mod_symload(int strtablen)
{
	Elf_Ehdr ehdr;
	char *shstrtab;
	struct elf_section *head, *s;
	char *symbuf, *strbuf;

	/*
	 * Seek to the text offset to start loading...
	 */
	if (lseek(modfd, 0, SEEK_SET) == -1)
		err(12, "lseek");
	if (read_elf_header(modfd, &ehdr) < 0)
		return;

	shstrtab = read_shstring_table(modfd, &ehdr);
	read_sections(modfd, &ehdr, shstrtab, &head);

	for (s = head; s; s = s->next) {
		struct elf_section *p = s;

		if ((p->type == SHT_SYMTAB) || (p->type == SHT_DYNSYM)) {
			if (debug)
				fprintf(stderr, "loading `%s': addr = %p, "
				    "size = %#lx\n",
				    s->name, s->addr, (u_long)s->size);
			/*
			 * Seek to the file offset to start loading it...
			 */
			if (lseek(modfd, p->offset, SEEK_SET) == -1)
				err(12, "lseek");
			symbuf = malloc(p->size);
			if (symbuf == 0)
				err(13, "malloc");
			if (read(modfd, symbuf, p->size) != p->size)
				err(14, "read");

			loadsym(symbuf, p->size);
			free(symbuf);
		}
	}

	for (s = head; s; s = s->next) {
		struct elf_section *p = s;

		if ((p->type == SHT_STRTAB) &&
		    (strcmp(p->name, ".strtab") == 0 )) {
			if (debug)
				fprintf(stderr, "loading `%s': addr = %p, "
				    "size = %#lx\n",
				    s->name, s->addr, (u_long)s->size);
			/*
			 * Seek to the file offset to start loading it...
			 */
			if (lseek(modfd, p->offset, SEEK_SET) == -1)
				err(12, "lseek");
			strbuf = malloc(p->size);
			if (strbuf == 0)
				err(13, "malloc");
			if (read(modfd, strbuf, p->size) != p->size)
				err(14, "read");

			loadsym(strbuf, p->size);
			free(strbuf);
		}
	}

	free(shstrtab);
	free_sections(head);
	return;
}
Beispiel #3
0
/* return size needed by the module */
int
elf_mod_sizes(int fd, size_t *modsize, int *strtablen,
    struct lmc_resrv *resrvp, struct stat *sp)
{
	Elf_Ehdr ehdr;
	ssize_t off = 0;
	size_t data_hole = 0;
	char *shstrtab, *strtab;
	struct elf_section *head, *s, *stab;

	if (read_elf_header(fd, &ehdr) < 0)
		return -1;
	shstrtab = read_shstring_table(fd, &ehdr);
	read_sections(fd, &ehdr, shstrtab, &head);

	for (s = head; s; s = s->next) {
		/* XXX impossible! */
		if (s->type == SHT_STRTAB && s->type == SHT_SYMTAB &&
		    s->type == SHT_DYNSYM)
			continue;
		if (debug)
			fprintf(stderr,
			    "%s: addr = %p size = %#lx align = %#lx\n",
			    s->name, s->addr, (u_long)s->size, (u_long)s->align);
		/*
		 * XXX try to get rid of the hole before the data
		 * section that GNU-ld likes to put there
		 */
		if (strcmp(s->name, ".data") == 0 && s->addr > (void *)off) {
			data_offset = roundup(off, s->align);
			if (debug)
				fprintf(stderr, ".data section forced to "
				    "offset %p (was %p)\n",
				    (void *)data_offset, s->addr);
			/* later remove size of compressed hole from off */
			data_hole = (ssize_t)s->addr - data_offset;
		}
		off = (ssize_t)s->addr + s->size;
	}
	off -= data_hole;

	/* XXX round to pagesize? */
	*modsize = roundup(off, sysconf(_SC_PAGESIZE));

	/* get string table length */
	strtab = read_string_table(fd, head, strtablen);
	free(shstrtab);
	free(strtab);

	/* get symbol table sections */
	get_symtab(&head);
	stab = head;
	resrvp->sym_symsize = 0;
	while (stab) {
		resrvp->sym_symsize += stab->size;
		stab = stab->next;
	}
	resrvp->sym_size = resrvp->sym_symsize + *strtablen;
	free_sections(head);

	return (0);
}
Beispiel #4
0
/* load a prelinked module; returns entry point */
void *
elf_mod_load(int fd)
{
	Elf_Ehdr ehdr;
	size_t zero_size = 0;
	size_t b;
	ssize_t n;
	char *shstrtab;
	struct elf_section *head, *s;
	char buf[10 * BUFSIZ];
	void *addr = NULL;

	if (read_elf_header(fd, &ehdr) < 0)
		return NULL;

	shstrtab = read_shstring_table(fd, &ehdr);
	read_sections(fd, &ehdr, shstrtab, &head);

	for (s = head; s; s = s->next) {
		if (s->type != SHT_STRTAB && s->type != SHT_SYMTAB &&
		    s->type != SHT_DYNSYM) {
			if (debug)
				fprintf(stderr, "loading `%s': addr = %p, "
				    "size = %#lx\n",
				    s->name, s->addr, (u_long)s->size);
			if (s->type == SHT_NOBITS) {
				/* skip some space */
				zero_size += s->size;
			} else {
				if (addr != NULL) {
					/*
					 * if there is a gap in the prelinked
					 * module, transfer some empty space.
					 */
					zero_size += (char*)s->addr -
					    (char*)addr;
				}
				if (zero_size) {
					loadspace(zero_size);
					zero_size = 0;
				}
				b = s->size;
				if (lseek(fd, s->offset, SEEK_SET) == -1)
					err(1, "lseek");
				while (b) {
					n = read(fd, buf, MIN(b, sizeof(buf)));
					if (n == 0)
						errx(1, "unexpected EOF");
					if (n < 0)
						err(1, "read");
					loadbuf(buf, n);
					b -= n;
				}
				addr = (char*)s->addr + s->size;
			}
		}
	}
	if (zero_size)
		loadspace(zero_size);

	free_sections(head);
	free(shstrtab);
	return (void *)ehdr.e_entry;
}
Beispiel #5
0
int main(int argc, char **argv)
{
	struct option long_options[] = {
		{"wordy", no_argument, NULL, 'w'},
		{"help", no_argument, NULL, 'h'},
	};
	struct epoll_event events[10];
	int epoll_fd = -1;
	struct itimerspec it;
	int ret;
	int status = EXIT_SUCCESS;

	if (argc > 0)
		progname = argv[0];

	for (;;) {
		int c;

		c = getopt_long(argc, argv, "wh", long_options, NULL);
		if (c == -1)
			break;

		switch (c) {
		case 'w':
			wordy = true;
			break;
		case 'h':
			usage(false);
		default:
			usage(true);
		}
	}
	if (optind != argc)
		usage(true);

	dpy = XOpenDisplay(NULL);
	if (!dpy) {
		fprintf(stderr, "unable to open display '%s'\n",
			XDisplayName(NULL));
		status = EXIT_FAILURE;
		goto out;
	}
	root = DefaultRootWindow(dpy);

	epoll_fd = epoll_create1(EPOLL_CLOEXEC);
	if (epoll_fd == -1) {
		perror("epoll_create1");
		status = EXIT_FAILURE;
		goto out;
	}

	ret = signal_fd_init(epoll_fd);
	if (ret == -1) {
		status = EXIT_FAILURE;
		goto out;
	}

	ret = timer_fd_init(epoll_fd);
	if (ret == -1) {
		status = EXIT_FAILURE;
		goto out;
	}

	ret = ctl_fd_init(epoll_fd);
	if (ret == -1) {
		status = EXIT_FAILURE;
		goto out;
	}

	if (init_plugins()) {
		status = EXIT_FAILURE;
		goto out;
	}
	if (init_sections(epoll_fd, config, sizeof(config) / sizeof(*config))) {
		status = EXIT_FAILURE;
		goto out;
	}
	if (update_timer_sections()) {
		status = EXIT_FAILURE;
		goto out;
	}

	it.it_interval.tv_sec = 1;
	it.it_interval.tv_nsec = 0;
	it.it_value.tv_sec = 1;
	it.it_value.tv_nsec = 0;
	ret = timerfd_settime(timer_cb.fd, 0, &it, NULL);
	if (ret == -1) {
		perror("timerfd_settime");
		status = EXIT_FAILURE;
		goto out;
	}

	while (!quit) {
		int i;

		update = false;

		ret = epoll_wait(epoll_fd, events,
				 sizeof(events) / sizeof(events[0]),
				 -1);
		if (ret == -1) {
			if (errno == EINTR)
				continue;
			perror("epoll_wait");
			status = EXIT_FAILURE;
			goto out;
		}

		for (i = 0; i < ret; i++) {
			struct epoll_callback *cb = events[i].data.ptr;

			ret = cb->callback(cb->fd, cb->data, events[i].events);
			if (ret) {
				status = EXIT_FAILURE;
				goto out;
			}
		}

		if (update) {
			ret = update_statusbar();
			if (ret) {
				status = EXIT_FAILURE;
				goto out;
			}
		}
	}

	status = EXIT_SUCCESS;
out:
	if (epoll_fd != -1)
		close(epoll_fd);
	free_sections();
	if (ctl_cb.fd != -1) {
		close(ctl_cb.fd);
		unlink(ctl_addr.sun_path);
	}
	if (timer_cb.fd != -1)
		close(timer_cb.fd);
	if (signal_cb.fd != -1)
		close(signal_cb.fd);
	str_free(&status_str);
	if (dpy) {
		XStoreName(dpy, root, "");
		XFlush(dpy);
		XCloseDisplay(dpy);
	}
	return status;
}