bpf: Propagate modified uaddrlen from cgroup sockaddr programs
[platform/kernel/linux-starfive.git] / kernel / bpf / cgroup.c
index 03b3d44..ac37bd5 100644 (file)
@@ -1450,6 +1450,9 @@ EXPORT_SYMBOL(__cgroup_bpf_run_filter_sk);
  *                                       provided by user sockaddr
  * @sk: sock struct that will use sockaddr
  * @uaddr: sockaddr struct provided by user
+ * @uaddrlen: Pointer to the size of the sockaddr struct provided by user. It is
+ *            read-only for AF_INET[6] uaddr but can be modified for AF_UNIX
+ *            uaddr.
  * @atype: The type of program to be executed
  * @t_ctx: Pointer to attach type specific context
  * @flags: Pointer to u32 which contains higher bits of BPF program
@@ -1462,6 +1465,7 @@ EXPORT_SYMBOL(__cgroup_bpf_run_filter_sk);
  */
 int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
                                      struct sockaddr *uaddr,
+                                     int *uaddrlen,
                                      enum cgroup_bpf_attach_type atype,
                                      void *t_ctx,
                                      u32 *flags)
@@ -1473,6 +1477,7 @@ int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
        };
        struct sockaddr_storage unspec;
        struct cgroup *cgrp;
+       int ret;
 
        /* Check socket family since not all sockets represent network
         * endpoint (e.g. AF_UNIX).
@@ -1483,11 +1488,19 @@ int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
        if (!ctx.uaddr) {
                memset(&unspec, 0, sizeof(unspec));
                ctx.uaddr = (struct sockaddr *)&unspec;
+               ctx.uaddrlen = 0;
+       } else {
+               ctx.uaddrlen = *uaddrlen;
        }
 
        cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
-       return bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run,
-                                    0, flags);
+       ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run,
+                                   0, flags);
+
+       if (!ret && uaddr)
+               *uaddrlen = ctx.uaddrlen;
+
+       return ret;
 }
 EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_addr);