Ejemplo n.º 1
0
int btrfs_list_get_path_rootid(int fd, u64 *treeid)
{
	int  ret;
	struct btrfs_ioctl_ino_lookup_args args;

	memset(&args, 0, sizeof(args));
	args.objectid = BTRFS_FIRST_FREE_OBJECTID;

	ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
	if (ret < 0) {
		SYSWARN("Can't perform the search");
		return ret;
	}

	*treeid = args.treeid;
	return 0;
}
Ejemplo n.º 2
0
/**
 * Set close-on-exec flag to all fd`s except 0, 1, 2
 * (stdin, stdout, stderr)
 */
void setup_inherited_fds()
{
    struct dirent dirent, *direntp;
    int fd, fddir;
    DIR *dir;

    dir = opendir("/proc/self/fd");
    if (!dir) {
        SYSWARN("failed to open dir /proc/self/fd/");
        WARN("can`t check for inherited fds");
        return; //Not a critical error
    }

    fddir = dirfd(dir);

    while (!readdir_r(dir, &dirent, &direntp)) {
        char procpath[64];
        char path[PATH_MAX];

        if (!direntp)
            break;

        if (!strcmp(direntp->d_name, "."))
            continue;

        if (!strcmp(direntp->d_name, ".."))
            continue;

        fd = atoi(direntp->d_name);

        if (fd == 0 || fd == 1 || fd == 2
                || fd == fddir)
            continue;

        /* found inherited fd, setting FD_CLOEXEC */
        if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
            SYSERROR("can`t close-on-exec on fd %d", fd);
            throw -1;
        }
    }

    if (closedir(dir)) {
        SYSERROR("failed to close directory");
        throw -1;
    }
}
Ejemplo n.º 3
0
/*
 * lxc_cmd_rsp_send: Send a command response
 *
 * @fd   : file descriptor of socket to send response on
 * @rsp  : response to send
 *
 * Returns 0 on success, < 0 on failure
 */
static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
{
	ssize_t ret;

	errno = EMSGSIZE;
	ret = lxc_send_nointr(fd, rsp, sizeof(*rsp), MSG_NOSIGNAL);
	if (ret < 0 || (size_t)ret != sizeof(*rsp)) {
		SYSERROR("Failed to send command response %zd", ret);
		return -1;
	}

	if (!rsp->data || rsp->datalen <= 0)
		return 0;

	errno = EMSGSIZE;
	ret = lxc_send_nointr(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL);
	if (ret < 0 || ret != (ssize_t)rsp->datalen) {
		SYSWARN("Failed to send command response data %zd", ret);
		return -1;
	}

	return 0;
}
Ejemplo n.º 4
0
int storage_destroy_wrapper(void *data)
{
	struct lxc_conf *conf = data;

	if (setgid(0) < 0) {
		SYSERROR("Failed to setgid to 0");
		return -1;
	}

	if (setgroups(0, NULL) < 0)
		SYSWARN("Failed to clear groups");

	if (setuid(0) < 0) {
		SYSERROR("Failed to setuid to 0");
		return -1;
	}

	if (!storage_destroy(conf)) {
		ERROR("Failed to destroy storage");
		return -1;
	}

	return 0;
}
Ejemplo n.º 5
0
/*
 * lxc_cmd_rsp_recv: Receive a response to a command
 *
 * @sock  : the socket connected to the container
 * @cmd   : command to put response in
 *
 * Returns the size of the response message or < 0 on failure
 *
 * Note that if the command response datalen > 0, then data is
 * a malloc()ed buffer and should be free()ed by the caller. If
 * the response data is <= a void * worth of data, it will be
 * stored directly in data and datalen will be 0.
 *
 * As a special case, the response for LXC_CMD_CONSOLE is created
 * here as it contains an fd for the master pty passed through the
 * unix socket.
 */
static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
{
	int ret, rspfd;
	struct lxc_cmd_rsp *rsp = &cmd->rsp;

	ret = lxc_abstract_unix_recv_fds(sock, &rspfd, 1, rsp, sizeof(*rsp));
	if (ret < 0) {
		SYSWARN("Failed to receive response for command \"%s\"",
		        lxc_cmd_str(cmd->req.cmd));

		if (errno == ECONNRESET)
			return -1;

		return -1;
	}
	TRACE("Command \"%s\" received response", lxc_cmd_str(cmd->req.cmd));

	if (cmd->req.cmd == LXC_CMD_CONSOLE) {
		struct lxc_cmd_console_rsp_data *rspdata;

		/* recv() returns 0 bytes when a tty cannot be allocated,
		 * rsp->ret is < 0 when the peer permission check failed
		 */
		if (ret == 0 || rsp->ret < 0)
			return 0;

		rspdata = malloc(sizeof(*rspdata));
		if (!rspdata) {
			errno = ENOMEM;
			ERROR("Failed to allocate response buffer for command \"%s\"",
			      lxc_cmd_str(cmd->req.cmd));
			return -1;
		}

		rspdata->masterfd = rspfd;
		rspdata->ttynum = PTR_TO_INT(rsp->data);
		rsp->data = rspdata;
	}

	if (rsp->datalen == 0) {
		DEBUG("Response data length for command \"%s\" is 0",
		      lxc_cmd_str(cmd->req.cmd));
		return ret;
	}

	if ((rsp->datalen > LXC_CMD_DATA_MAX) &&
	    (cmd->req.cmd != LXC_CMD_CONSOLE_LOG)) {
		ERROR("Response data for command \"%s\" is too long: %d bytes > %d",
		      lxc_cmd_str(cmd->req.cmd), rsp->datalen, LXC_CMD_DATA_MAX);
		return -1;
	}

	if (cmd->req.cmd == LXC_CMD_CONSOLE_LOG) {
		rsp->data = malloc(rsp->datalen + 1);
		((char *)rsp->data)[rsp->datalen] = '\0';
	} else {
		rsp->data = malloc(rsp->datalen);
	}
	if (!rsp->data) {
		errno = ENOMEM;
		ERROR("Failed to allocate response buffer for command \"%s\"",
		      lxc_cmd_str(cmd->req.cmd));
		return -1;
	}

	ret = lxc_recv_nointr(sock, rsp->data, rsp->datalen, 0);
	if (ret != rsp->datalen) {
		SYSERROR("Failed to receive response data for command \"%s\"",
		         lxc_cmd_str(cmd->req.cmd));
		return -1;
	}

	return ret;
}