Exemple #1
0
int sha1sum_file(char *fnam, unsigned char *digest)
{
	char *buf;
	int ret;
	FILE *f;
	long flen;

	if (!fnam)
		return -1;
	process_lock();
	f = fopen_cloexec(fnam, "r");
	process_unlock();
	if (f < 0) {
		SYSERROR("Error opening template");
		return -1;
	}
	if (fseek(f, 0, SEEK_END) < 0) {
		SYSERROR("Error seeking to end of template");
		lock_fclose(f);
		return -1;
	}
	if ((flen = ftell(f)) < 0) {
		SYSERROR("Error telling size of template");
		lock_fclose(f);
		return -1;
	}
	if (fseek(f, 0, SEEK_SET) < 0) {
		SYSERROR("Error seeking to start of template");
		lock_fclose(f);
		return -1;
	}
	if ((buf = malloc(flen+1)) == NULL) {
		SYSERROR("Out of memory");
		lock_fclose(f);
		return -1;
	}
	if (fread(buf, 1, flen, f) != flen) {
		SYSERROR("Failure reading template");
		free(buf);
		lock_fclose(f);
		return -1;
	}
	if (lock_fclose(f) < 0) {
		SYSERROR("Failre closing template");
		free(buf);
		return -1;
	}
	buf[flen] = '\0';
	ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, buf, flen, (void *)digest);
	free(buf);
	return ret;
}
Exemple #2
0
void Sender::createDataFile(char* apcDir) {
	if (apcDir == NULL) {
		return;
	}

	mDataFileName = (char*)malloc(strlen(apcDir) + 12);
	sprintf(mDataFileName, "%s/0000000000", apcDir);
	mDataFile = fopen_cloexec(mDataFileName, "wb");
	if (!mDataFile) {
		logg->logError("Failed to open binary file: %s", mDataFileName);
		handleException();
	}
}
Exemple #3
0
static bool collect_subsytems(void)
{
	char *line = NULL, *tab1;
	size_t sz = 0, i;
	FILE *f;

	if (subsystems) // already initialized
		return true;

	f = fopen_cloexec("/proc/cgroups", "r");
	if (!f)
		return false;
	while (getline(&line, &sz, f) != -1) {
		char **tmp;
		if (line[0] == '#')
			continue;
		if (!line[0])
			continue;
		tab1 = strchr(line, '\t');
		if (!tab1)
			continue;
		*tab1 = '\0';
		tmp = realloc(subsystems, (nr_subsystems+1)*sizeof(char *));
		if (!tmp)
			goto out_free;

		subsystems = tmp;
		tmp[nr_subsystems] = strdup(line);
		if (!tmp[nr_subsystems])
			goto out_free;
		nr_subsystems++;
	}
	fclose(f);

	if (!nr_subsystems) {
		ERROR("No cgroup subsystems found");
		return false;
	}

	return true;

out_free:
	fclose(f);
	for (i = 0; i < nr_subsystems; i++)
		free(subsystems[i]);
	free(subsystems);
	subsystems = NULL;
	nr_subsystems = 0;
	return false;
}
bool FtraceSource::prepare() {
	{
		struct sigaction act;
		act.sa_handler = handler;
		act.sa_flags = (int)SA_RESETHAND;
		if (sigaction(SIGUSR1, &act, NULL) != 0) {
			logg->logError("sigaction failed: %s\n", strerror(errno));
			handleException();
		}
	}

	gSessionData->ftraceDriver.prepare();

	if (DriverSource::readIntDriver("/sys/kernel/debug/tracing/tracing_on", &mTracingOn)) {
		logg->logError("Unable to read if ftrace is enabled");
		handleException();
	}

	if (DriverSource::writeDriver("/sys/kernel/debug/tracing/tracing_on", "0") != 0) {
		logg->logError("Unable to turn ftrace off before truncating the buffer");
		handleException();
	}

	{
		int fd;
		fd = open("/sys/kernel/debug/tracing/trace", O_WRONLY | O_TRUNC | O_CLOEXEC, 0666);
		if (fd < 0) {
			logg->logError("Unable truncate ftrace buffer: %s", strerror(errno));
			handleException();
		}
		close(fd);
	}

	if (DriverSource::writeDriver("/sys/kernel/debug/tracing/trace_clock", "perf") != 0) {
		logg->logError("Unable to switch ftrace to the perf clock, please ensure you are running Linux 3.10 or later");
		handleException();
	}

	mFtraceFh = fopen_cloexec("/sys/kernel/debug/tracing/trace_pipe", "rb");
	if (mFtraceFh == NULL) {
		logg->logError("Unable to open trace_pipe");
		handleException();
	}

	return true;
}
Exemple #5
0
static bool collect_subsytems(void)
{
	char *line = NULL;
	nih_local char **cgm_subsys_list = NULL;
	size_t sz = 0;
	FILE *f = NULL;

	if (subsystems) // already initialized
		return true;

	subsystems_inone = malloc(2 * sizeof(char *));
	if (!subsystems_inone)
		return false;
	subsystems_inone[0] = "all";
	subsystems_inone[1] = NULL;

	if (lxc_list_controllers(&cgm_subsys_list)) {
		while (cgm_subsys_list[nr_subsystems]) {
			char **tmp = NIH_MUST( realloc(subsystems,
						(nr_subsystems+2)*sizeof(char *)) );
			tmp[nr_subsystems] = NIH_MUST(
					strdup(cgm_subsys_list[nr_subsystems++]) );
			subsystems = tmp;
		}
		if (nr_subsystems)
			subsystems[nr_subsystems] = NULL;
		goto collected;
	}

	INFO("cgmanager_list_controllers failed, falling back to /proc/self/cgroups");
	f = fopen_cloexec("/proc/self/cgroup", "r");
	if (!f) {
		f = fopen_cloexec("/proc/1/cgroup", "r");
		if (!f)
			return false;
	}
	while (getline(&line, &sz, f) != -1) {
		/* file format: hierarchy:subsystems:group,
		 * with multiple subsystems being ,-separated */
		char *slist, *end, *p, *saveptr = NULL, **tmp;

		if (!line[0])
			continue;

		slist = strchr(line, ':');
		if (!slist)
			continue;
		slist++;
		end = strchr(slist, ':');
		if (!end)
			continue;
		*end = '\0';

		for (p = strtok_r(slist, ",", &saveptr);
				p;
				p = strtok_r(NULL, ",", &saveptr)) {
			tmp = realloc(subsystems, (nr_subsystems+2)*sizeof(char *));
			if (!tmp)
				goto out_free;

			subsystems = tmp;
			tmp[nr_subsystems] = strdup(p);
			tmp[nr_subsystems+1] = NULL;
			if (!tmp[nr_subsystems])
				goto out_free;
			nr_subsystems++;
		}
	}
	fclose(f);
	f = NULL;

	free(line);
	line = NULL;

collected:
	if (!nr_subsystems) {
		ERROR("No cgroup subsystems found");
		return false;
	}

	/* make sure that cgroup.use can be and is honored */
	const char *cgroup_use = lxc_global_config_value("lxc.cgroup.use");
	if (!cgroup_use && errno != 0)
		goto final_verify;
	if (cgroup_use) {
		if (!verify_and_prune(cgroup_use)) {
			free_subsystems();
			return false;
		}
		subsystems_inone[0] = NIH_MUST( strdup(cgroup_use) );
		cgm_all_controllers_same = false;
	}

final_verify:
	return verify_final_subsystems(cgroup_use);

out_free:
	free(line);
	if (f)
		fclose(f);
	free_subsystems();
	return false;
}
Exemple #6
0
Fichier : utils.c Projet : dgsb/lxc
const char *lxc_global_config_value(const char *option_name)
{
	static const char * const options[][2] = {
		{ "lxc.bdev.lvm.vg",        DEFAULT_VG      },
		{ "lxc.bdev.lvm.thin_pool", DEFAULT_THIN_POOL },
		{ "lxc.bdev.zfs.root",      DEFAULT_ZFSROOT },
		{ "lxc.lxcpath",            NULL            },
		{ "lxc.default_config",     NULL            },
		{ "lxc.cgroup.pattern",     DEFAULT_CGROUP_PATTERN },
		{ "lxc.cgroup.use",         NULL            },
		{ NULL, NULL },
	};

	/* placed in the thread local storage pool for non-bionic targets */
#ifdef HAVE_TLS
	static __thread const char *values[sizeof(options) / sizeof(options[0])] = { 0 };
#else
	static const char *values[sizeof(options) / sizeof(options[0])] = { 0 };
#endif
	char *user_config_path = NULL;
	char *user_default_config_path = NULL;
	char *user_lxc_path = NULL;

	if (geteuid() > 0) {
		const char *user_home = getenv("HOME");
		if (!user_home)
			user_home = "/";

		user_config_path = malloc(sizeof(char) * (22 + strlen(user_home)));
		user_default_config_path = malloc(sizeof(char) * (26 + strlen(user_home)));
		user_lxc_path = malloc(sizeof(char) * (19 + strlen(user_home)));

		sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home);
		sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home);
		sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home);
	}
	else {
		user_config_path = strdup(LXC_GLOBAL_CONF);
		user_default_config_path = strdup(LXC_DEFAULT_CONFIG);
		user_lxc_path = strdup(LXCPATH);
	}

	const char * const (*ptr)[2];
	size_t i;
	char buf[1024], *p, *p2;
	FILE *fin = NULL;

	for (i = 0, ptr = options; (*ptr)[0]; ptr++, i++) {
		if (!strcmp(option_name, (*ptr)[0]))
			break;
	}
	if (!(*ptr)[0]) {
		free(user_config_path);
		free(user_default_config_path);
		free(user_lxc_path);
		errno = EINVAL;
		return NULL;
	}

	if (values[i]) {
		free(user_config_path);
		free(user_default_config_path);
		free(user_lxc_path);
		return values[i];
	}

	fin = fopen_cloexec(user_config_path, "r");
	free(user_config_path);
	if (fin) {
		while (fgets(buf, 1024, fin)) {
			if (buf[0] == '#')
				continue;
			p = strstr(buf, option_name);
			if (!p)
				continue;
			/* see if there was just white space in front
			 * of the option name
			 */
			for (p2 = buf; p2 < p; p2++) {
				if (*p2 != ' ' && *p2 != '\t')
					break;
			}
			if (p2 < p)
				continue;
			p = strchr(p, '=');
			if (!p)
				continue;
			/* see if there was just white space after
			 * the option name
			 */
			for (p2 += strlen(option_name); p2 < p; p2++) {
				if (*p2 != ' ' && *p2 != '\t')
					break;
			}
			if (p2 < p)
				continue;
			p++;
			while (*p && (*p == ' ' || *p == '\t')) p++;
			if (!*p)
				continue;

			free(user_default_config_path);

			if (strcmp(option_name, "lxc.lxcpath") == 0) {
				free(user_lxc_path);
				user_lxc_path = copy_global_config_value(p);
				remove_trailing_slashes(user_lxc_path);
				values[i] = user_lxc_path;
				goto out;
			}

			values[i] = copy_global_config_value(p);
			free(user_lxc_path);
			goto out;
		}
	}
	/* could not find value, use default */
	if (strcmp(option_name, "lxc.lxcpath") == 0) {
		remove_trailing_slashes(user_lxc_path);
		values[i] = user_lxc_path;
		free(user_default_config_path);
	}
	else if (strcmp(option_name, "lxc.default_config") == 0) {
		values[i] = user_default_config_path;
		free(user_lxc_path);
	}
	else {
		free(user_default_config_path);
		free(user_lxc_path);
		values[i] = (*ptr)[1];
	}
	/* special case: if default value is NULL,
	 * and there is no config, don't view that
	 * as an error... */
	if (!values[i])
		errno = 0;

out:
	if (fin)
		fclose(fin);

	return values[i];
}
Exemple #7
0
const char *lxc_global_config_value(const char *option_name)
{
	static const char *options[][2] = {
		{ "lvm_vg",          DEFAULT_VG      },
		{ "lvm_thin_pool",   DEFAULT_THIN_POOL },
		{ "zfsroot",         DEFAULT_ZFSROOT },
		{ "lxcpath",         LXCPATH         },
		{ "cgroup.pattern",  DEFAULT_CGROUP_PATTERN },
		{ "cgroup.use",      NULL            },
		{ NULL, NULL },
	};
	/* Protected by a mutex to eliminate conflicting load and store operations */ 
	static const char *values[sizeof(options) / sizeof(options[0])] = { 0 };
	const char *(*ptr)[2];
	const char *value;
	size_t i;
	char buf[1024], *p, *p2;
	FILE *fin = NULL;

	for (i = 0, ptr = options; (*ptr)[0]; ptr++, i++) {
		if (!strcmp(option_name, (*ptr)[0]))
			break;
	}
	if (!(*ptr)[0]) {
		errno = EINVAL;
		return NULL;
	}

	static_lock();
	if (values[i]) {
		value = values[i];
		static_unlock();
		return value;
	}
	static_unlock();

	process_lock();
	fin = fopen_cloexec(LXC_GLOBAL_CONF, "r");
	process_unlock();
	if (fin) {
		while (fgets(buf, 1024, fin)) {
			if (buf[0] == '#')
				continue;
			p = strstr(buf, option_name);
			if (!p)
				continue;
			/* see if there was just white space in front
			 * of the option name
			 */
			for (p2 = buf; p2 < p; p2++) {
				if (*p2 != ' ' && *p2 != '\t')
					break;
			}
			if (p2 < p)
				continue;
			p = strchr(p, '=');
			if (!p)
				continue;
			/* see if there was just white space after
			 * the option name
			 */
			for (p2 += strlen(option_name); p2 < p; p2++) {
				if (*p2 != ' ' && *p2 != '\t')
					break;
			}
			if (p2 < p)
				continue;
			p++;
			while (*p && (*p == ' ' || *p == '\t')) p++;
			if (!*p)
				continue;
			static_lock();
			values[i] = copy_global_config_value(p);
			static_unlock();
			goto out;
		}
	}
	/* could not find value, use default */
	static_lock();
	values[i] = (*ptr)[1];
	/* special case: if default value is NULL,
	 * and there is no config, don't view that
	 * as an error... */
	if (!values[i])
		errno = 0;
	static_unlock();

out:
	process_lock();
	if (fin)
		fclose(fin);
	process_unlock();
	static_lock();
	value = values[i];
	static_unlock();
	return value;
}
static bool collect_subsytems(void)
{
    char *line = NULL;
    size_t sz = 0;
    FILE *f;

    if (subsystems) // already initialized
        return true;

    subsystems_inone = malloc(2 * sizeof(char *));
    if (!subsystems_inone)
        return false;
    subsystems_inone[0] = "all";
    subsystems_inone[1] = NULL;

    f = fopen_cloexec("/proc/self/cgroup", "r");
    if (!f) {
        f = fopen_cloexec("/proc/1/cgroup", "r");
        if (!f)
            return false;
    }
    while (getline(&line, &sz, f) != -1) {
        /* file format: hierarchy:subsystems:group,
         * with multiple subsystems being ,-separated */
        char *slist, *end, *p, *saveptr = NULL, **tmp;

        if (!line[0])
            continue;

        slist = strchr(line, ':');
        if (!slist)
            continue;
        slist++;
        end = strchr(slist, ':');
        if (!end)
            continue;
        *end = '\0';

        for (p = strtok_r(slist, ",", &saveptr);
                p;
                p = strtok_r(NULL, ",", &saveptr)) {
            tmp = realloc(subsystems, (nr_subsystems+2)*sizeof(char *));
            if (!tmp)
                goto out_free;

            subsystems = tmp;
            tmp[nr_subsystems] = strdup(p);
            tmp[nr_subsystems+1] = NULL;
            if (!tmp[nr_subsystems])
                goto out_free;
            nr_subsystems++;
        }
    }
    fclose(f);

    free(line);
    if (!nr_subsystems) {
        ERROR("No cgroup subsystems found");
        return false;
    }

    return true;

out_free:
    free(line);
    fclose(f);
    free_subsystems();
    return false;
}
Exemple #9
0
/*
 * Sets the process title to the specified title. Note:
 *   1. this function requires root to succeed
 *   2. it clears /proc/self/environ
 *   3. it may not succed (e.g. if title is longer than /proc/self/environ +
 *      the original title)
 */
int setproctitle(char *title)
{
	char buf[2048], *tmp;
	FILE *f;
	int i, len, ret = 0;
	unsigned long arg_start, arg_end, env_start, env_end;

	f = fopen_cloexec("/proc/self/stat", "r");
	if (!f) {
		return -1;
	}

	tmp = fgets(buf, sizeof(buf), f);
	fclose(f);
	if (!tmp) {
		return -1;
	}

	/* Skip the first 47 fields, column 48-51 are ARG_START and
	 * ARG_END. */
	tmp = strchr(buf, ' ');
	for (i = 0; i < 46; i++) {
		if (!tmp)
			return -1;
		tmp = strchr(tmp+1, ' ');
	}

	if (!tmp)
		return -1;

	i = sscanf(tmp, "%lu %lu %lu %lu", &arg_start, &arg_end, &env_start, &env_end);
	if (i != 4) {
		return -1;
	}

	/* Include the null byte here, because in the calculations below we
	 * want to have room for it. */
	len = strlen(title) + 1;

	/* We're truncating the environment, so we should use at most the
	 * length of the argument + environment for the title. */
	if (len > env_end - arg_start) {
		arg_end = env_end;
		len = env_end - arg_start;
	} else {
		/* Only truncate the environment if we're actually going to
		 * overwrite part of it. */
		if (len >= arg_end - arg_start) {
			env_start = env_end;
		}

		arg_end = arg_start + len;

		/* check overflow */
		if (arg_end < len || arg_end < arg_start) {
			return -1;
		}

	}

	strcpy((char*)arg_start, title);

	ret |= prctl(PR_SET_MM, PR_SET_MM_ARG_START,   arg_start, 0, 0);
	ret |= prctl(PR_SET_MM, PR_SET_MM_ARG_END,     arg_end, 0, 0);
	ret |= prctl(PR_SET_MM, PR_SET_MM_ENV_START,   env_start, 0, 0);
	ret |= prctl(PR_SET_MM, PR_SET_MM_ENV_END,     env_end, 0, 0);

	return ret;
}
Exemple #10
0
mxml_node_t *EventsXML::getTree() {
#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len
	char path[PATH_MAX];
	mxml_node_t *xml = NULL;
	FILE *fl;

	// Avoid unused variable warning
	(void)events_xml_len;

	// Load the provided or default events xml
	if (gSessionData->mEventsXMLPath) {
		strncpy(path, gSessionData->mEventsXMLPath, PATH_MAX);
		fl = fopen_cloexec(path, "r");
		if (fl) {
			xml = mxmlLoadFile(NULL, fl, MXML_NO_CALLBACK);
			fclose(fl);
		}
	}
	if (xml == NULL) {
		logg->logMessage("Unable to locate events.xml, using default");
		xml = mxmlLoadString(NULL, (const char *)events_xml, MXML_NO_CALLBACK);
	}

	// Append additional events XML
	if (gSessionData->mEventsXMLAppend) {
		fl = fopen_cloexec(gSessionData->mEventsXMLAppend, "r");
		if (fl == NULL) {
			logg->logError("Unable to open additional events XML %s", gSessionData->mEventsXMLAppend);
			handleException();
		}
		mxml_node_t *append = mxmlLoadFile(NULL, fl, MXML_NO_CALLBACK);
		fclose(fl);

		mxml_node_t *events = mxmlFindElement(xml, xml, "events", NULL, NULL, MXML_DESCEND);
		if (!events) {
			logg->logError("Unable to find <events> node in the events.xml, please ensure the first two lines of events XML starts with:\n"
				       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
				       "<events>");
			handleException();
		}

		XMLList *categoryList = NULL;
		XMLList *eventList = NULL;
		{
			// Make list of all categories in xml
			mxml_node_t *node = xml;
			while (true) {
				node = mxmlFindElement(node, xml, "category", NULL, NULL, MXML_DESCEND);
				if (node == NULL) {
					break;
				}
				categoryList = new XMLList(categoryList, node);
			}

			// Make list of all events in xml
			node = xml;
			while (true) {
				node = mxmlFindElement(node, xml, "event", NULL, NULL, MXML_DESCEND);
				if (node == NULL) {
					break;
				}
				eventList = new XMLList(eventList, node);
			}
		}

		// Handle events
		for (mxml_node_t *node = mxmlFindElement(append, append, "event", NULL, NULL, MXML_DESCEND),
		       *next = mxmlFindElement(node, append, "event", NULL, NULL, MXML_DESCEND);
		     node != NULL;
		     node = next, next = mxmlFindElement(node, append, "event", NULL, NULL, MXML_DESCEND)) {
			const char *const category = mxmlElementGetAttr(mxmlGetParent(node), "name");
			const char *const title = mxmlElementGetAttr(node, "title");
			const char *const name = mxmlElementGetAttr(node, "name");
			if (category == NULL || title == NULL || name == NULL) {
				logg->logError("Not all event XML nodes have the required title and name and parent name attributes");
				handleException();
			}

			// Replace any duplicate events
			for (XMLList *event = eventList; event != NULL; event = event->getPrev()) {
				const char *const category2 = mxmlElementGetAttr(mxmlGetParent(event->getNode()), "name");
				const char *const title2 = mxmlElementGetAttr(event->getNode(), "title");
				const char *const name2 = mxmlElementGetAttr(event->getNode(), "name");
				if (category2 == NULL || title2 == NULL || name2 == NULL) {
					logg->logError("Not all event XML nodes have the required title and name and parent name attributes");
					handleException();
				}

				if (strcmp(category, category2) == 0 && strcmp(title, title2) == 0 && strcmp(name, name2) == 0) {
					logg->logMessage("Replacing counter %s %s: %s", category, title, name);
					mxml_node_t *parent = mxmlGetParent(event->getNode());
					mxmlDelete(event->getNode());
					mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
					event->setNode(node);
					break;
				}
			}
		}

		// Handle categories
		for (mxml_node_t *node = strcmp(mxmlGetElement(append), "category") == 0 ? append : mxmlFindElement(append, append, "category", NULL, NULL, MXML_DESCEND),
		       *next = mxmlFindElement(node, append, "category", NULL, NULL, MXML_DESCEND);
		     node != NULL;
		     node = next, next = mxmlFindElement(node, append, "category", NULL, NULL, MXML_DESCEND)) {
			// After replacing duplicate events, a category may be empty
			if (mxmlGetFirstChild(node) == NULL) {
				continue;
			}

			const char *const name = mxmlElementGetAttr(node, "name");
			if (name == NULL) {
				logg->logError("Not all event XML categories have the required name attribute");
				handleException();
			}

			// Merge identically named categories
			bool merged = false;
			for (XMLList *category = categoryList; category != NULL; category = category->getPrev()) {
				const char *const name2 = mxmlElementGetAttr(category->getNode(), "name");
				if (name2 == NULL) {
					logg->logError("Not all event XML categories have the required name attribute");
					handleException();
				}

				if (strcmp(name, name2) == 0) {
					logg->logMessage("Merging category %s", name);
					while (true) {
						mxml_node_t *child = mxmlGetFirstChild(node);
						if (child == NULL) {
							break;
						}
						mxmlAdd(category->getNode(), MXML_ADD_AFTER, mxmlGetLastChild(category->getNode()), child);
					}
					merged = true;
					break;
				}
			}

			if (merged) {
				continue;
			}

			// Add new categories
			logg->logMessage("Appending category %s", name);
			mxmlAdd(events, MXML_ADD_AFTER, mxmlGetLastChild(events), node);
		}

		XMLList::free(eventList);
		XMLList::free(categoryList);

		mxmlDelete(append);
	}

	return xml;
}