Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90f62cf3 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by David S. Miller
Browse files

net: Use netlink_ns_capable to verify the permisions of netlink messages



It is possible by passing a netlink socket to a more privileged
executable and then to fool that executable into writing to the socket
data that happens to be valid netlink message to do something that
privileged executable did not intend to do.

To keep this from happening replace bare capable and ns_capable calls
with netlink_capable, netlink_net_calls and netlink_ns_capable calls.
Which act the same as the previous calls except they verify that the
opener of the socket had the desired permissions as well.

Reported-by: default avatarAndy Lutomirski <luto@amacapital.net>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent aa4cf945
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -466,7 +466,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
	type -= CRYPTO_MSG_BASE;
	link = &crypto_dispatch[type];

	if (!capable(CAP_NET_ADMIN))
	if (!netlink_capable(skb, CAP_NET_ADMIN))
		return -EPERM;

	if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
+1 −1
Original line number Diff line number Diff line
@@ -369,7 +369,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
		return;

	/* Can only change if privileged. */
	if (!capable(CAP_NET_ADMIN)) {
	if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) {
		err = EPERM;
		goto out;
	}
+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
			goto next_msg;
		}

		if (!capable(CAP_SYS_ADMIN)) {
		if (!netlink_capable(skb, CAP_SYS_ADMIN)) {
			err = -EPERM;
			goto next_msg;
		}
+2 −2
Original line number Diff line number Diff line
@@ -643,13 +643,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
		if ((task_active_pid_ns(current) != &init_pid_ns))
			return -EPERM;

		if (!capable(CAP_AUDIT_CONTROL))
		if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
			err = -EPERM;
		break;
	case AUDIT_USER:
	case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
	case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
		if (!capable(CAP_AUDIT_WRITE))
		if (!netlink_capable(skb, CAP_AUDIT_WRITE))
			err = -EPERM;
		break;
	default:  /* bad msg */
+2 −2
Original line number Diff line number Diff line
@@ -804,7 +804,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh)
	u8 limhops = 0;
	int err = 0;

	if (!capable(CAP_NET_ADMIN))
	if (!netlink_capable(skb, CAP_NET_ADMIN))
		return -EPERM;

	if (nlmsg_len(nlh) < sizeof(*r))
@@ -893,7 +893,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh)
	u8 limhops = 0;
	int err = 0;

	if (!capable(CAP_NET_ADMIN))
	if (!netlink_capable(skb, CAP_NET_ADMIN))
		return -EPERM;

	if (nlmsg_len(nlh) < sizeof(*r))
Loading