Esempio n. 1
0
int toi_netlink_setup(struct user_helper_data *uhd)
{
	/* In case userui didn't cleanup properly on us */
	toi_netlink_close_complete(uhd);

	if (netlink_prepare(uhd) < 0) {
		printk(KERN_INFO "Netlink prepare failed.\n");
		return 1;
	}

	if (toi_launch_userspace_program(uhd->program, uhd->netlink_id,
				UMH_WAIT_EXEC, uhd->debug) < 0) {
		printk(KERN_INFO "Launch userspace program failed.\n");
		toi_netlink_close_complete(uhd);
		return 1;
	}

	/* Wait 2 seconds for the userspace process to make contact */
	wait_for_completion_timeout(&uhd->wait_for_process, 2*HZ);

	if (uhd->pid == -1) {
		printk(KERN_INFO "%s: Failed to contact userspace process.\n",
				uhd->name);
		toi_netlink_close_complete(uhd);
		return 1;
	}

	return 0;
}
Esempio n. 2
0
static int toi_nl_gen_rcv_msg(struct user_helper_data *uhd,
		struct sk_buff *skb, struct nlmsghdr *nlh)
{
	int type = nlh->nlmsg_type;
	int *data;
	int err;

	if (uhd->debug)
		printk(KERN_ERR "toi_user_rcv_skb: Received message %d.\n",
				type);

	/* Let the more specific handler go first. It returns
	 * 1 for valid messages that it doesn't know. */
	err = uhd->rcv_msg(skb, nlh);
	if (err != 1)
		return err;

	/* Only allow one task to receive NOFREEZE privileges */
	if (type == NETLINK_MSG_NOFREEZE_ME && uhd->pid != -1) {
		printk(KERN_INFO "Received extra nofreeze me requests.\n");
		return -EBUSY;
	}

	data = NLMSG_DATA(nlh);

	switch (type) {
	case NETLINK_MSG_NOFREEZE_ME:
		return nl_set_nofreeze(uhd, nlh->nlmsg_pid);
	case NETLINK_MSG_GET_DEBUGGING:
		send_whether_debugging(uhd);
		return 0;
	case NETLINK_MSG_READY:
		if (nlh->nlmsg_len != NLMSG_LENGTH(sizeof(u32))) {
			printk(KERN_INFO "Invalid ready mesage.\n");
			if (uhd->not_ready)
				uhd->not_ready();
			return -EINVAL;
		}
		return nl_ready(uhd, (u32) *data);
	case NETLINK_MSG_CLEANUP:
		toi_netlink_close_complete(uhd);
		return 0;
	}

	return -EINVAL;
}
Esempio n. 3
0
static int netlink_prepare(struct user_helper_data *uhd)
{
	struct netlink_kernel_cfg cfg = {
		.groups = 0,
		.input = toi_user_rcv_skb,
	};

	uhd->next = uhd_list;
	uhd_list = uhd;

	uhd->sock_seq = 0x42c0ffee;
	uhd->nl = netlink_kernel_create(&init_net, uhd->netlink_id, &cfg);
	if (!uhd->nl) {
		printk(KERN_INFO "Failed to allocate netlink socket for %s.\n",
				uhd->name);
		return -ENOMEM;
	}

	toi_fill_skb_pool(uhd);

	return 0;
}

void toi_netlink_close(struct user_helper_data *uhd)
{
	struct task_struct *t;

	toi_read_lock_tasklist();
	t = find_task_by_pid_ns(uhd->pid, &init_pid_ns);
	if (t)
		t->flags &= ~PF_NOFREEZE;
	toi_read_unlock_tasklist();

	toi_send_netlink_message(uhd, NETLINK_MSG_CLEANUP, NULL, 0);
}
EXPORT_SYMBOL_GPL(toi_netlink_close);

int toi_netlink_setup(struct user_helper_data *uhd)
{
	/* In case userui didn't cleanup properly on us */
	toi_netlink_close_complete(uhd);

	if (netlink_prepare(uhd) < 0) {
		printk(KERN_INFO "Netlink prepare failed.\n");
		return 1;
	}

	if (toi_launch_userspace_program(uhd->program, uhd->netlink_id,
				UMH_WAIT_EXEC, uhd->debug) < 0) {
		printk(KERN_INFO "Launch userspace program failed.\n");
		toi_netlink_close_complete(uhd);
		return 1;
	}

	/* Wait 2 seconds for the userspace process to make contact */
	wait_for_completion_timeout(&uhd->wait_for_process, 2*HZ);

	if (uhd->pid == -1) {
		printk(KERN_INFO "%s: Failed to contact userspace process.\n",
				uhd->name);
		toi_netlink_close_complete(uhd);
		return 1;
	}

	return 0;
}
void toi_usm_exit(void)
{
	toi_netlink_close_complete(&usm_helper_data);
	toi_unregister_module(&usm_ops);
}