summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChenbo Feng <fengc@google.com>2017-03-22 17:27:35 -0700
committerMichael Bestas <mkbestas@lineageos.org>2022-04-19 00:51:38 +0300
commit1710f46491716938fbf538fb6643d77c676aa9c7 (patch)
tree530b2e2c9e1c9b672b91ccc86c2702369db67aae
parent7b8bf634ea1a7114d8929692860ef57d49ec7dc8 (diff)
BACKPORT: UPSTREAM: Add a eBPF helper function to retrieve socket uid
Cherry-pick from commit 6acc5c2910689fc6ee181bf63085c5efff6a42bd Returns the owner uid of the socket inside a sk_buff. This is useful to perform per-UID accounting of network traffic or per-UID packet filtering. The socket need to be a fullsock otherwise overflowuid is returned. Signed-off-by: Chenbo Feng <fengc@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Bug: 30950746 Change-Id: Idc00947ccfdd4e9f2214ffc4178d701cd9ead0ac Signed-off-by: Chatur27 <jasonbright2709@gmail.com>
-rw-r--r--include/uapi/linux/bpf.h9
-rw-r--r--net/core/filter.c20
2 files changed, 29 insertions, 0 deletions
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 92803fd8467d..5bac307880a6 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -543,6 +543,15 @@ enum bpf_func_id {
*/
BPF_FUNC_get_socket_cookie,
+ /**
+ * u32 bpf_get_socket_uid(skb)
+ * Get the owner uid of the socket stored inside sk_buff.
+ * @skb: pointer to skb
+ * Return: uid of the socket owner on success or 0 if the socket pointer
+ * inside sk_buff is NULL
+ */
+ BPF_FUNC_get_socket_uid,
+
__BPF_FUNC_MAX_ID,
};
diff --git a/net/core/filter.c b/net/core/filter.c
index f75d8ad887ea..bfc5ab6ad10c 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2498,6 +2498,24 @@ static const struct bpf_func_proto bpf_get_socket_cookie_proto = {
.arg1_type = ARG_PTR_TO_CTX,
};
+BPF_CALL_1(bpf_get_socket_uid, struct sk_buff *, skb)
+{
+ struct sock *sk = sk_to_full_sk(skb->sk);
+ kuid_t kuid;
+
+ if (!sk || !sk_fullsock(sk))
+ return overflowuid;
+ kuid = sock_net_uid(sock_net(sk), sk);
+ return from_kuid_munged(sock_net(sk)->user_ns, kuid);
+}
+
+static const struct bpf_func_proto bpf_get_socket_uid_proto = {
+ .func = bpf_get_socket_uid,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_PTR_TO_CTX,
+};
+
static const struct bpf_func_proto *
sk_filter_func_proto(enum bpf_func_id func_id)
{
@@ -2521,6 +2539,8 @@ sk_filter_func_proto(enum bpf_func_id func_id)
return bpf_get_trace_printk_proto();
case BPF_FUNC_get_socket_cookie:
return &bpf_get_socket_cookie_proto;
+ case BPF_FUNC_get_socket_uid:
+ return &bpf_get_socket_uid_proto;
default:
return NULL;
}