--- x/net/ipv4/cipso_ipv4.c +++ y/net/ipv4/cipso_ipv4.c @@ -1848,6 +1848,7 @@ static int cipso_v4_get_actual_opt_len(c * values on failure. * */ +static DEFINE_SPINLOCK(setattr_spinlock); int cipso_v4_sock_setattr(struct sock *sk, const struct cipso_v4_doi *doi_def, const struct netlbl_lsm_secattr *secattr, @@ -1899,6 +1900,7 @@ int cipso_v4_sock_setattr(struct sock *s kfree(buf); buf = NULL; + spin_lock(&setattr_spinlock); sk_inet = inet_sk(sk); old = rcu_dereference_protected(sk_inet->inet_opt, sk_locked); @@ -1912,6 +1914,7 @@ int cipso_v4_sock_setattr(struct sock *s rcu_assign_pointer(sk_inet->inet_opt, opt); if (old) kfree_rcu(old, rcu); + spin_unlock(&setattr_spinlock); return 0; @@ -1975,10 +1978,12 @@ int cipso_v4_req_setattr(struct request_ kfree(buf); buf = NULL; + spin_lock(&setattr_spinlock); req_inet = inet_rsk(req); opt = unrcu_pointer(xchg(&req_inet->ireq_opt, RCU_INITIALIZER(opt))); if (opt) kfree_rcu(opt, rcu); + spin_unlock(&setattr_spinlock); return 0; @@ -2057,9 +2062,11 @@ void cipso_v4_sock_delattr(struct sock * struct inet_sock *sk_inet; int hdr_delta; + spin_lock(&setattr_spinlock); sk_inet = inet_sk(sk); hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt); + spin_unlock(&setattr_spinlock); if (inet_test_bit(IS_ICSK, sk) && hdr_delta > 0) { struct inet_connection_sock *sk_conn = inet_csk(sk); sk_conn->icsk_ext_hdr_len -= hdr_delta; @@ -2077,7 +2084,9 @@ void cipso_v4_sock_delattr(struct sock * */ void cipso_v4_req_delattr(struct request_sock *req) { + spin_lock(&setattr_spinlock); cipso_v4_delopt(&inet_rsk(req)->ireq_opt); + spin_unlock(&setattr_spinlock); } /**