Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp461572ybv; Fri, 7 Feb 2020 02:39:59 -0800 (PST) X-Google-Smtp-Source: APXvYqxPDPOMqfzL0/bUldjqopRDaUYduaT/1VuT3N5iev++FxelZxD9gngJ6Hvfhj6gbq7Mgo/i X-Received: by 2002:a05:6830:2154:: with SMTP id r20mr2240726otd.131.1581071999000; Fri, 07 Feb 2020 02:39:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581071998; cv=none; d=google.com; s=arc-20160816; b=QEHEA6YvYfsQhNLl2D4/T0u/P4oAYb+V5Q+5QM5HUma6SpVtXjz6wpIH0erM4S9tIZ TRhTo2aeBgh+mj4eRsMKcDL3ne1TEFju1q2+mrfNSh3J3B3ZStnNsa8xoNs+didkUgnz HbzdPildq1Ai1Q3ZOUik/g77eTlnDx+gAD7EH6XHHMfYHu4kATRYshFEN1xTIf10YyHn B3ZB558zm1lr39UN8KNcnPWu1WwsrVeMjFM0UiPfpnD9CinH+F5pPRDVio6KQmcLnKVz gaxuaHLo4lBgPqvzUUNtHM+gn0uBsNoEYij+1wlACi4enhcFhHNNa5HgJap7eCrq5HRH UqGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=m8xqc0jfB/yBaWPmmchEBBglZJ/VBe1jDOf+DDjAxBY=; b=n4SDRhE6Kr0r+IuF7KwMOjuLsFmPgX5gR9WeepMDQhkqSYaxEeOuMuifYQNyRs1Sss DWLmgKdYCELdBME/jIldu9KJaCNC73E7dya3uwmKVaTJMsxvfQMHwtKMe0XPtycS+2Yu uicIA+S3qJCY7mBizzgUpNNXecJsKGqs+JrlsJsrqr1Rb9EllCYqr8+FhRretQP1ZVv1 ScVhO8SA7D9DZIgaxCXRFVckdfa7ZDlwVGJbtozgo1V+tyxcfTNscvgZZNBb28U1Wggs gaGVoNztVpzpu7X3tsRmiaTIG+Tp3eMbHlJklSaq/bG0BE17RwbClwthuvbqKjcKIghm sFiw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cloudflare.com header.s=google header.b=cz7aL+v4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=cloudflare.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i3si1454029otc.272.2020.02.07.02.39.46; Fri, 07 Feb 2020 02:39:58 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@cloudflare.com header.s=google header.b=cz7aL+v4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=cloudflare.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726954AbgBGKit (ORCPT + 99 others); Fri, 7 Feb 2020 05:38:49 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:50524 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726674AbgBGKit (ORCPT ); Fri, 7 Feb 2020 05:38:49 -0500 Received: by mail-wm1-f66.google.com with SMTP id a5so2055112wmb.0 for ; Fri, 07 Feb 2020 02:38:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloudflare.com; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=m8xqc0jfB/yBaWPmmchEBBglZJ/VBe1jDOf+DDjAxBY=; b=cz7aL+v4INeA1E2fIe7snXWsd4QN9xku06qy7gADtcdEa06Uorj+7dCZeUIRrsawMw dPXGYNx1wGCDHd2LMtMlBFmI9719CjcoyLM1UlhuuTbh4/Eca14yaUxv9dsH55GUiAwj ZAbKsmkYmzELw251CF1qPzBN1rBboopH8QbRI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=m8xqc0jfB/yBaWPmmchEBBglZJ/VBe1jDOf+DDjAxBY=; b=Jomkrv/88CR++D6rZ2eVrMcB0GGmKLNap5gAGiWaUqEPCrLPzLBOYYBBCmDxHW1zqI A94XAhC+Z+kej0E0GgbKC2wfYwXRFGAQu8z1XQXOrumatlnocL1HwYS7kGIKLEGvYvGl eqCB2Nx5hDORk+RMg6KTC2eyKh6X1aHjtF9QWCM2jdQQcmL5CidyknVqNtOmzA6PpkUS K2RXWFzHy6S+l69hVFfJb6ZjvN1RphVvYMq30nY/l+UJd2zzRsS4wzsCvuc6B21DjsHq 24OID3kxdrpXvp3oO2pRYhw5e9B8CrjQr40P9P2oGwAxG4HXqBL3Bp7FPasXnnFDo1LH 6iWw== X-Gm-Message-State: APjAAAVw7j6zFiavFZI2KQo9xVi25WUjGLgPZBusjdTi5MKpYTmCu6vT rPV9y6Wm0TClL4FxqvDe8XqHsw== X-Received: by 2002:a05:600c:2109:: with SMTP id u9mr3810981wml.183.1581071925982; Fri, 07 Feb 2020 02:38:45 -0800 (PST) Received: from localhost.localdomain ([2a06:98c0:1000:8250:28a5:3485:3116:20f5]) by smtp.gmail.com with ESMTPSA id k16sm2777887wru.0.2020.02.07.02.38.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Feb 2020 02:38:45 -0800 (PST) From: Lorenz Bauer To: John Fastabend , Daniel Borkmann , "David S. Miller" , Jakub Kicinski , Alexei Starovoitov , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko Cc: kernel-team@cloudflare.com, Lorenz Bauer , netdev@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH bpf] bpf: sockmap: check update requirements after locking Date: Fri, 7 Feb 2020 10:37:12 +0000 Message-Id: <20200207103713.28175-1-lmb@cloudflare.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It's currently possible to insert sockets in unexpected states into a sockmap, due to a TOCTTOU when updating the map from a syscall. sock_map_update_elem checks that sk->sk_state == TCP_ESTABLISHED, locks the socket and then calls sock_map_update_common. At this point, the socket may have transitioned into another state, and the earlier assumptions don't hold anymore. Crucially, it's conceivable (though very unlikely) that a socket has become unhashed. This breaks the sockmap's assumption that it will get a callback via sk->sk_prot->unhash. Fix this by checking the (fixed) sk_type and sk_protocol without the lock, followed by a locked check of sk_state. Unfortunately it's not possible to push the check down into sock_(map|hash)_update_common, since BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB run before the socket has transitioned from TCP_SYN_RECV into TCP_ESTABLISHED. Signed-off-by: Lorenz Bauer Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") --- net/core/sock_map.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/net/core/sock_map.c b/net/core/sock_map.c index 8998e356f423..36a2433e183f 100644 --- a/net/core/sock_map.c +++ b/net/core/sock_map.c @@ -416,14 +416,16 @@ static int sock_map_update_elem(struct bpf_map *map, void *key, ret = -EINVAL; goto out; } - if (!sock_map_sk_is_suitable(sk) || - sk->sk_state != TCP_ESTABLISHED) { + if (!sock_map_sk_is_suitable(sk)) { ret = -EOPNOTSUPP; goto out; } sock_map_sk_acquire(sk); - ret = sock_map_update_common(map, idx, sk, flags); + if (sk->sk_state != TCP_ESTABLISHED) + ret = -EOPNOTSUPP; + else + ret = sock_map_update_common(map, idx, sk, flags); sock_map_sk_release(sk); out: fput(sock->file); @@ -739,14 +741,16 @@ static int sock_hash_update_elem(struct bpf_map *map, void *key, ret = -EINVAL; goto out; } - if (!sock_map_sk_is_suitable(sk) || - sk->sk_state != TCP_ESTABLISHED) { + if (!sock_map_sk_is_suitable(sk)) { ret = -EOPNOTSUPP; goto out; } sock_map_sk_acquire(sk); - ret = sock_hash_update_common(map, key, sk, flags); + if (sk->sk_state != TCP_ESTABLISHED) + ret = -EOPNOTSUPP; + else + ret = sock_hash_update_common(map, key, sk, flags); sock_map_sk_release(sk); out: fput(sock->file); -- 2.20.1