bpf: Propagate modified uaddrlen from cgroup sockaddr programs
[platform/kernel/linux-rpi.git] / net / ipv6 / af_inet6.c
index 368824f..4375bfa 100644 (file)
@@ -199,6 +199,9 @@ lookup_protocol:
        if (INET_PROTOSW_REUSE & answer_flags)
                sk->sk_reuse = SK_CAN_REUSE;
 
+       if (INET_PROTOSW_ICSK & answer_flags)
+               inet_init_csk_locks(sk);
+
        inet = inet_sk(sk);
        inet_assign_bit(IS_ICSK, sk, INET_PROTOSW_ICSK & answer_flags);
 
@@ -453,7 +456,7 @@ int inet6_bind_sk(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        /* BPF prog is run before any checks are done so that if the prog
         * changes context in a wrong way it will be caught.
         */
-       err = BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr,
+       err = BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, &addr_len,
                                                 CGROUP_INET6_BIND, &flags);
        if (err)
                return err;
@@ -519,6 +522,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
                  int peer)
 {
        struct sockaddr_in6 *sin = (struct sockaddr_in6 *)uaddr;
+       int sin_addr_len = sizeof(*sin);
        struct sock *sk = sock->sk;
        struct inet_sock *inet = inet_sk(sk);
        struct ipv6_pinfo *np = inet6_sk(sk);
@@ -538,7 +542,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
                sin->sin6_addr = sk->sk_v6_daddr;
                if (np->sndflow)
                        sin->sin6_flowinfo = np->flow_label;
-               BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin,
+               BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len,
                                       CGROUP_INET6_GETPEERNAME);
        } else {
                if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
@@ -546,13 +550,13 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
                else
                        sin->sin6_addr = sk->sk_v6_rcv_saddr;
                sin->sin6_port = inet->inet_sport;
-               BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin,
+               BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len,
                                       CGROUP_INET6_GETSOCKNAME);
        }
        sin->sin6_scope_id = ipv6_iface_scope_id(&sin->sin6_addr,
                                                 sk->sk_bound_dev_if);
        release_sock(sk);
-       return sizeof(*sin);
+       return sin_addr_len;
 }
 EXPORT_SYMBOL(inet6_getname);