Message ID | 20240129184014.work.593-kees@kernel.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-43360-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp764113dyb; Mon, 29 Jan 2024 10:48:54 -0800 (PST) X-Google-Smtp-Source: AGHT+IG9haygLh5tKfyHUMEhwqiwVF+bJeJQRnvU13uFp/jzwKpcXm9Ko/uf3t8V4+55GBJ05iy+ X-Received: by 2002:a05:6402:5168:b0:55d:8112:6424 with SMTP id d8-20020a056402516800b0055d81126424mr4405647ede.21.1706554134555; Mon, 29 Jan 2024 10:48:54 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706554134; cv=pass; d=google.com; s=arc-20160816; b=kL49KOarIAPfANCaU/AIAkcvQbFdWL/uwRzkiZIeVXhgPQV5olVpDllCwlJ0gEolae 4s75vo9zlhktWISDdheGaXQPiBzn8bufv6IYx74SM5mXuX7wP1CKgnFCTWZ3fFBvzZCg x5zh0s0AWdvQYJ5IaG7jt8SeomzZ3wFgXEcwpSyLvjEeHRAhA15IZx/e2/bIqIJp3LWT eCYCaWfpXIYw5aacH438dWgk+0Rl/uxDViZ2zVnWQXsB4A8z+jC8rzbl/SK/c++AardE hh6yLolEvPY4kYRAr2LyHxRSVjNt6LOdQzxlTlw7QcLtS3EFsGpV4MJIRBzutMBWAGDg p5Zw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=1FndaoLuezk++wxgVrcH5NtXJoTq/9EmRf7oCHvFRc0=; fh=bhBBR14yLf6QfE2GYel9ErJm6vSEVTcN5k5tGEbND9o=; b=nX41mxZGlxis8cgksyvtvMWuEz+Xd46aPTYmRJhtoXzTeCVRkfkvhZxdHtqEWw+taK qgRrAZC2avj8cIdqbnUV9NyJebCxVan0oPqxco/2oQTJgt19UT2kz7RRgqaWOba6nWTp 6FUAIiHmAq5wJTANC+qIMWRCapoCsqQwgUS165ZLG8tsT2culLs5RX5ybkX+9CALBt99 bJ14Ea1o/eT8JhO70GAjOqC49d2/kZyKdzGz2gqVG285GQYW/bUog+8W48lcHsaiNbQ2 A/XePHQaATr5Dv7dEhSoKYRkoTFlJIa5DDYuE3e2hJg8tiRSkR5zC1PVKM4ogOfXUWxO +xYA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=YKVpCR0o; arc=pass (i=1 spf=pass spfdomain=chromium.org dkim=pass dkdomain=chromium.org dmarc=pass fromdomain=chromium.org); spf=pass (google.com: domain of linux-kernel+bounces-43360-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-43360-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id 14-20020a0564021f4e00b0055cd7634453si3764555edz.505.2024.01.29.10.48.54 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Jan 2024 10:48:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-43360-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=YKVpCR0o; arc=pass (i=1 spf=pass spfdomain=chromium.org dkim=pass dkdomain=chromium.org dmarc=pass fromdomain=chromium.org); spf=pass (google.com: domain of linux-kernel+bounces-43360-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-43360-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 2353E1F26EF2 for <ouuuleilei@gmail.com>; Mon, 29 Jan 2024 18:48:27 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DDBF71586CF; Mon, 29 Jan 2024 18:40:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="YKVpCR0o" Received: from mail-oo1-f41.google.com (mail-oo1-f41.google.com [209.85.161.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2C6866F092 for <linux-kernel@vger.kernel.org>; Mon, 29 Jan 2024 18:40:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706553621; cv=none; b=lCs5Rkg45BHIAOAAT0yPZgPFwReJfdxVTyhxysV3URVGuFNiPIa18aMPsndvPXyuaYKNTHsFqOihah2oNbC/b4WfWf0HTPegtQqEBOYxS7Wi1VMHutUEgF6I3V2jyExk5RJ5DBbpVOSfWVve2mKs9bunnDEHEPmMX2Rn8K5nCk4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706553621; c=relaxed/simple; bh=R2t7ERucYntEaiouukVxBCXGGyHD7wa90M6aZ+Evuwc=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=YH0m1NsP9btF5t08G7R9MymSBnqP3zSykurCCCxGn5wVFCaYlbbg2Rt8BKQET/3rHHP/4DFmJpomm8CtoseC8Nz2JMMGV8ukasL6RT1aYKPGMwXBmKiZmAhcqZjm7BpMLlxxIZ2Fm90AtpgYB3/+LiczB6zXq/2JMKxbCzTZ44Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=YKVpCR0o; arc=none smtp.client-ip=209.85.161.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Received: by mail-oo1-f41.google.com with SMTP id 006d021491bc7-598699c0f1eso1500482eaf.2 for <linux-kernel@vger.kernel.org>; Mon, 29 Jan 2024 10:40:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1706553618; x=1707158418; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=1FndaoLuezk++wxgVrcH5NtXJoTq/9EmRf7oCHvFRc0=; b=YKVpCR0oacknJ8wxTULb127zriOH+E//z3pPhQins5bYgYqK+4Dgdze79PZCCzP3Bo 95DyjSBEyL0oAeynXPoI5anVT0xLw4Txap1NGjkIQcnEwbmK/Lt71ejXEddXjTtZav6s aLIAP5XARwhNVephydle/KFdQm0r/p7Op5uq0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706553618; x=1707158418; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=1FndaoLuezk++wxgVrcH5NtXJoTq/9EmRf7oCHvFRc0=; b=rofgVDFgHpOx6pobRkPG0GCO/tta3oErPdytwU1XC5v9JHKNiMgOm3X5PV3/IfwH0v WQqMyOiotfGfnePalTIjTxMktDVVIoWXXNXVWZ0c7B5OZbMSEd7FdITTbPKxlo77DBGJ WRaOf7WpIK23fmXLv2Obdlf3xQbMAkTRtDaRJIE9UABWA9EPu1hjslS2tbxy4zoLP/Vr AuBG46kfGOTyQMxcIviIQ5eKFWXfbsMtjPiSTCH6lgtklL2kwRtSBO1wBfvF3524aJ+6 f2w2FufH3AUizCQaBd3TWF5SAITPDL1oMxBSEVReBJC/e5boAAeUXhnSr4UTyfu04A/C jpgA== X-Gm-Message-State: AOJu0Yy3xYLMWglWBVjLxehVqv3mjZzQwPzvy1IbsuKhVDukyU7wI957 f334USFFCyanYCrNpF3ARoVXnE9CbeJaIOkY9IFxDlTGIgBCQ0H9jL+uxsbtiA== X-Received: by 2002:a05:6358:d592:b0:178:632d:656f with SMTP id ms18-20020a056358d59200b00178632d656fmr2226352rwb.62.1706553618251; Mon, 29 Jan 2024 10:40:18 -0800 (PST) Received: from www.outflux.net ([198.0.35.241]) by smtp.gmail.com with ESMTPSA id u13-20020a63454d000000b005cd86cd9055sm6450299pgk.1.2024.01.29.10.40.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Jan 2024 10:40:17 -0800 (PST) From: Kees Cook <keescook@chromium.org> To: Christian Brauner <brauner@kernel.org> Cc: Kees Cook <keescook@chromium.org>, Alexander Viro <viro@zeniv.linux.org.uk>, Jan Kara <jack@suse.cz>, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH] select: Avoid wrap-around instrumentation in do_sys_poll() Date: Mon, 29 Jan 2024 10:40:15 -0800 Message-Id: <20240129184014.work.593-kees@kernel.org> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2692; i=keescook@chromium.org; h=from:subject:message-id; bh=R2t7ERucYntEaiouukVxBCXGGyHD7wa90M6aZ+Evuwc=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBlt/EPCgLg3aGtKRVzbHxjO78YeZKfPnx5tmaL9 ehYjSVEgj6JAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCZbfxDwAKCRCJcvTf3G3A JudFD/4uj/y23P8K+iLzDJ8hOxwYy4bJl41fAFTr2k6Q1vBAcDDMCSOq7ZggcPMb7ixLGFwyNcY KlAInc1U0WE9ttaTeseDa0Rj/x8VV4ygOBIkywlomWkVKJXAMRv3RzT0H/MtQBaayJVZ7+a6KIG 03JEZgOWmMKFT6mMl9hDu65yy37G7tRzOfLbWF7hcuzhEz2Z6hUhkl/yXUwNq3/ml5T3D+DuSFw ySoX+Bk/uLVmIEtFiRK4WrXbLH8ld3qwsU1CN8GNApzcJhb2Nb8E0pjM8QRvm+SLGznR9p0yXut Cj/UnGpJs1l+GIvDv/n6H4aRvcXauUntzoT+qLmYseBhos4YiHAtT/1GVFx/IWfPeV0/Or9Gxol 1VQUpH5v09Z0yt3IxuJXLmYMhFxOKgVAubQk9JQZafDMW0Y8Y9FAcXJ1O0r6TmhE8lZba2qiTi7 /4VTVfjzPLrfyrJy/+h8yt2OmQhT5kU06J39wfOYI8b39I+B9Fduig96lgysYFTZC4dYLniRgbv n5QosAv43xkYCX9W7n7GASxlft7ESwATPaZ0bb5JEOV012ZuuX0TyK61a/ZeR/Yzhi9LrYnNwRT qhOS1mgazV2q9wTf5a+VzSWFPqz+4Yxb0Cpb5cMk1Y7UVCXCA4xjJ+sni5dnXpvgxgxOeSkYiP+ BYy8vSA Ho8G6Txw== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: 8bit X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789451708302680889 X-GMAIL-MSGID: 1789451708302680889 |
Series |
select: Avoid wrap-around instrumentation in do_sys_poll()
|
|
Commit Message
Kees Cook
Jan. 29, 2024, 6:40 p.m. UTC
The mix of int, unsigned int, and unsigned long used by struct
poll_list::len, todo, len, and j meant that the signed overflow
sanitizer got worried it needed to instrument several places where
arithmetic happens between these variables. Since all of the variables
are always positive and bounded by unsigned int, use a single type in
all places. Additionally expand the zero-test into an explicit range
check before updating "todo".
This keeps sanitizer instrumentation[1] out of a UACCESS path:
vmlinux.o: warning: objtool: do_sys_poll+0x285: call to __ubsan_handle_sub_overflow() with UACCESS enabled
Link: https://github.com/KSPP/linux/issues/26 [1]
Cc: Christian Brauner <brauner@kernel.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
fs/select.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
Comments
On Mon, 29 Jan 2024 10:40:15 -0800, Kees Cook wrote: > The mix of int, unsigned int, and unsigned long used by struct > poll_list::len, todo, len, and j meant that the signed overflow > sanitizer got worried it needed to instrument several places where > arithmetic happens between these variables. Since all of the variables > are always positive and bounded by unsigned int, use a single type in > all places. Additionally expand the zero-test into an explicit range > check before updating "todo". > > [...] Applied to the vfs.misc branch of the vfs/vfs.git tree. Patches in the vfs.misc branch should appear in linux-next soon. Please report any outstanding bugs that were missed during review in a new review to the original patch series allowing us to drop it. It's encouraged to provide Acked-bys and Reviewed-bys even though the patch has now been applied. If possible patch trailers will be updated. Note that commit hashes shown below are subject to change due to rebase, trailer updates or similar. If in doubt, please check the listed branch. tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git branch: vfs.misc [1/1] select: Avoid wrap-around instrumentation in do_sys_poll() https://git.kernel.org/vfs/vfs/c/ecd1f34f1242
On Mon 29-01-24 10:40:15, Kees Cook wrote: > The mix of int, unsigned int, and unsigned long used by struct > poll_list::len, todo, len, and j meant that the signed overflow > sanitizer got worried it needed to instrument several places where > arithmetic happens between these variables. Since all of the variables > are always positive and bounded by unsigned int, use a single type in > all places. Additionally expand the zero-test into an explicit range > check before updating "todo". > > This keeps sanitizer instrumentation[1] out of a UACCESS path: > > vmlinux.o: warning: objtool: do_sys_poll+0x285: call to __ubsan_handle_sub_overflow() with UACCESS enabled > > Link: https://github.com/KSPP/linux/issues/26 [1] > Cc: Christian Brauner <brauner@kernel.org> > Cc: Alexander Viro <viro@zeniv.linux.org.uk> > Cc: Jan Kara <jack@suse.cz> > Cc: linux-fsdevel@vger.kernel.org > Signed-off-by: Kees Cook <keescook@chromium.org> Yeah, good cleanup. Feel free to add: Reviewed-by: Jan Kara <jack@suse.cz> Honza > --- > fs/select.c | 13 +++++++------ > 1 file changed, 7 insertions(+), 6 deletions(-) > > diff --git a/fs/select.c b/fs/select.c > index 0ee55af1a55c..11a3b1312abe 100644 > --- a/fs/select.c > +++ b/fs/select.c > @@ -839,7 +839,7 @@ SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg) > > struct poll_list { > struct poll_list *next; > - int len; > + unsigned int len; > struct pollfd entries[]; > }; > > @@ -975,14 +975,15 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, > struct timespec64 *end_time) > { > struct poll_wqueues table; > - int err = -EFAULT, fdcount, len; > + int err = -EFAULT, fdcount; > /* Allocate small arguments on the stack to save memory and be > faster - use long to make sure the buffer is aligned properly > on 64 bit archs to avoid unaligned access */ > long stack_pps[POLL_STACK_ALLOC/sizeof(long)]; > struct poll_list *const head = (struct poll_list *)stack_pps; > struct poll_list *walk = head; > - unsigned long todo = nfds; > + unsigned int todo = nfds; > + unsigned int len; > > if (nfds > rlimit(RLIMIT_NOFILE)) > return -EINVAL; > @@ -998,9 +999,9 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, > sizeof(struct pollfd) * walk->len)) > goto out_fds; > > - todo -= walk->len; > - if (!todo) > + if (walk->len >= todo) > break; > + todo -= walk->len; > > len = min(todo, POLLFD_PER_PAGE); > walk = walk->next = kmalloc(struct_size(walk, entries, len), > @@ -1020,7 +1021,7 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, > > for (walk = head; walk; walk = walk->next) { > struct pollfd *fds = walk->entries; > - int j; > + unsigned int j; > > for (j = walk->len; j; fds++, ufds++, j--) > unsafe_put_user(fds->revents, &ufds->revents, Efault); > -- > 2.34.1 >
diff --git a/fs/select.c b/fs/select.c index 0ee55af1a55c..11a3b1312abe 100644 --- a/fs/select.c +++ b/fs/select.c @@ -839,7 +839,7 @@ SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg) struct poll_list { struct poll_list *next; - int len; + unsigned int len; struct pollfd entries[]; }; @@ -975,14 +975,15 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, struct timespec64 *end_time) { struct poll_wqueues table; - int err = -EFAULT, fdcount, len; + int err = -EFAULT, fdcount; /* Allocate small arguments on the stack to save memory and be faster - use long to make sure the buffer is aligned properly on 64 bit archs to avoid unaligned access */ long stack_pps[POLL_STACK_ALLOC/sizeof(long)]; struct poll_list *const head = (struct poll_list *)stack_pps; struct poll_list *walk = head; - unsigned long todo = nfds; + unsigned int todo = nfds; + unsigned int len; if (nfds > rlimit(RLIMIT_NOFILE)) return -EINVAL; @@ -998,9 +999,9 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, sizeof(struct pollfd) * walk->len)) goto out_fds; - todo -= walk->len; - if (!todo) + if (walk->len >= todo) break; + todo -= walk->len; len = min(todo, POLLFD_PER_PAGE); walk = walk->next = kmalloc(struct_size(walk, entries, len), @@ -1020,7 +1021,7 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, for (walk = head; walk; walk = walk->next) { struct pollfd *fds = walk->entries; - int j; + unsigned int j; for (j = walk->len; j; fds++, ufds++, j--) unsafe_put_user(fds->revents, &ufds->revents, Efault);