Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp2947069pxb; Tue, 13 Apr 2021 14:26:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxauz2vbEa5bbiBM3uY8EsuVvKqZ/daukKq5VShialwyiJZhhIeT61yj91bV8Ozyr+bmlNO X-Received: by 2002:a17:906:3e97:: with SMTP id a23mr34699142ejj.440.1618349169426; Tue, 13 Apr 2021 14:26:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618349169; cv=none; d=google.com; s=arc-20160816; b=gF1wSx017mFLLO+xOf24AG+RLXhgzEZJ6neTxCKjAoYhAucRY9/P79gIEPwXSjvxfh zJQTj8SMNakmGWuKmYB3epVbrnsqyKECa7X3Wucl6M60XVc2qwODZmiBEIXX+krWDgOu CK76pxRfa5gshCgdLB7aqE58lNV56UHF/ELbtCspdlyBmXJ86qpAdFrSnvfOKPQ0Kht8 1TweFielK7zglE5FqhWhsnDraE0z0tmOCn0hfRn16lG9Y4lv4S+sb5FCnmWoaWMzFJkE aekb713UCOddpP55giUu6Y0mH8r+3YELcJvXvriLV22NLDLLWfQM6H50NH20yAq0VD85 nsWQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=3FvqmXbTPGrExPdYFPrOm7MfDEznWQ3cYJunL5tX4XI=; b=GAAo7ofM+XUDhLKt2CfMQdLvu1HBGMg6N5XR20UdAXW0RJUUuUyqKlTZlIG450881o EHsbxMvb62kppB68oGVStygC4RITahIfD5NMSPIeFEvnwYnwDryPci1qQO9ufJInvOb1 B8czvWEdHKbK3n0q7372bv2ZcIZ2HBJX/lM7Ojrv11Z8C/DrRu5zsSJqnv87TK3lVVSb gQeuGbUVo9jxYGz5V+8gDpxTiW9tNYpRCHoAHFAUPMqHoDPElIc46zYjgtLFOmUu1wOQ jKMAR7rXNXLZFquU/ERTnsBzh/xRzdim56yDkR9PA9vb57EgF82Q35j0H4p7hUSZYbPL Z3GQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kinvolk.io header.s=google header.b="QnUaa/Ob"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kinvolk.io Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f7si7233207ejw.608.2021.04.13.14.25.46; Tue, 13 Apr 2021 14:26:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kinvolk.io header.s=google header.b="QnUaa/Ob"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kinvolk.io Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346758AbhDMQET (ORCPT + 99 others); Tue, 13 Apr 2021 12:04:19 -0400 Received: from mail-ed1-f53.google.com ([209.85.208.53]:46934 "EHLO mail-ed1-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346790AbhDMQEM (ORCPT ); Tue, 13 Apr 2021 12:04:12 -0400 Received: by mail-ed1-f53.google.com with SMTP id h10so19995658edt.13 for ; Tue, 13 Apr 2021 09:03:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kinvolk.io; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3FvqmXbTPGrExPdYFPrOm7MfDEznWQ3cYJunL5tX4XI=; b=QnUaa/ObnOTdkd9TXid6IcrAuQRmrpANhQd/Cl/ecdkS4vV8JdhUGaB3TX1BaZEkJl OLPkpNcWWih05sUoZGIts+wX+ho3yP3gfTX24SzZEnp3WBBUiOxgJ7OBlJeQTJ9vufc4 EeDy1jwWolYm8HcDn75LtEXjHw3X39ADV84RU= 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=3FvqmXbTPGrExPdYFPrOm7MfDEznWQ3cYJunL5tX4XI=; b=mV8eQbN6/5jDxuX4XqxjI2f9mx+y5Z2qWZdPoC4Fp/vPIXFEO5Sb+oQJFYQAWBvBVS bIoDOLBZZG+uZf/K4QnWmDidDan686utCdqWRSozZNSNbsawmGunJ6kwnl5cH+CdcjM0 YRfiQBMCdme5/e36/YUiQFvCRfTQcS/nsou0YascTemWGct63/yhKUJ/5molbFPAjIgF cKBNg5LNrPFpQD/ghR3TUO8gIQtpv3UOb7Cc47xIjfGbtk9Qf36WhNL7NIIGrBvy+3Rt IF1H//MrOsHb/Qosss4IywZDCGq4mTNprwXA6hboOhL1q7MKFzKukq0DOjKI32K6Taff R6iA== X-Gm-Message-State: AOAM530jGsyb9vG0NE8J8XUv+Y/Z+Eq53xnlgfmRkaAsqpq74PP0GxdX iBLD+v8Lfr3xfGQupaam8e8qSw== X-Received: by 2002:a50:82e5:: with SMTP id 92mr263078edg.141.1618329772096; Tue, 13 Apr 2021 09:02:52 -0700 (PDT) Received: from localhost.localdomain ([2a02:8109:9880:57f0:ba7c:cdd5:fff7:623c]) by smtp.gmail.com with ESMTPSA id gb4sm8162852ejc.122.2021.04.13.09.02.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 09:02:51 -0700 (PDT) From: Rodrigo Campos To: Kees Cook , Andy Lutomirski , Will Drewry , linux-kernel@vger.kernel.org, containers@lists.linux-foundation.org Cc: Rodrigo Campos , Sargun Dhillon , =?UTF-8?q?Mauricio=20V=C3=A1squez=20Bernal?= , Alban Crequy , stable@vger.kernel.org Subject: [PATCH 1/1] seccomp: Always "goto wait" if the list is empty Date: Tue, 13 Apr 2021 18:01:51 +0200 Message-Id: <20210413160151.3301-2-rodrigo@kinvolk.io> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210413160151.3301-1-rodrigo@kinvolk.io> References: <20210413160151.3301-1-rodrigo@kinvolk.io> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It is possible for the thread with the seccomp filter attached (target) to be waken up by an addfd message, but the list be empty. This happens when the addfd ioctl on the other side (seccomp agent) is interrupted by a signal such as SIGURG. In that case, the target erroneously and prematurely returns from the syscall to userspace even though the seccomp agent didn't ask for it. This happens in the following scenario: seccomp_notify_addfd() | seccomp_do_user_notification() | | err = wait_for_completion_interruptible(&n.ready); complete(&knotif->ready); | ret = wait_for_completion_interruptible(&kaddfd.completion); | // interrupted | | mutex_lock(&filter->notify_lock); | list_del(&kaddfd.list); | mutex_unlock(&filter->notify_lock); | | mutex_lock(&match->notify_lock); | // This is false, addfd is false | if (addfd && n.state != SECCOMP_NOTIFY_REPLIED) | | ret = n.val; | err = n.error; | flags = n.flags; So, the process blocked in seccomp_do_user_notification() will see a response. As n is 0 initialized and wasn't set, it will see a 0 as return value from the syscall. The seccomp agent, when retrying the interrupted syscall, will see an ENOENT error as the notification no longer exists (it was already answered by this bug). This patch fixes the issue by splitting the if in two parts: if we were woken up and the state is not replied, we will always do a "goto wait". And if that happens and there is an addfd element on the list, we will add the fd before "goto wait". This issue is present since 5.9, when addfd was added. Fixes: 7cf97b1254550 Cc: stable@vger.kernel.org # 5.9+ Signed-off-by: Rodrigo Campos --- kernel/seccomp.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 63b40d12896b..1b34598f0e07 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -1107,11 +1107,20 @@ static int seccomp_do_user_notification(int this_syscall, err = wait_for_completion_interruptible(&n.ready); mutex_lock(&match->notify_lock); if (err == 0) { - /* Check if we were woken up by a addfd message */ - addfd = list_first_entry_or_null(&n.addfd, - struct seccomp_kaddfd, list); - if (addfd && n.state != SECCOMP_NOTIFY_REPLIED) { - seccomp_handle_addfd(addfd); + + if (n.state != SECCOMP_NOTIFY_REPLIED) { + /* + * It is possible to be waken-up by an addfd message but + * the list be empty. This can happen if the addfd + * ioctl() is interrupted, as it deletes the element. + * + * So, check if indeed there is an element in the list. + */ + addfd = list_first_entry_or_null(&n.addfd, + struct seccomp_kaddfd, list); + if (addfd) + seccomp_handle_addfd(addfd); + mutex_unlock(&match->notify_lock); goto wait; } -- 2.30.2