From owner-dev-commits-src-all@freebsd.org Tue Aug 31 20:40:30 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D5DDC675F6C; Tue, 31 Aug 2021 20:40:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4GzfG65JbXz3LNY; Tue, 31 Aug 2021 20:40:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9A5E1186C0; Tue, 31 Aug 2021 20:40:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 17VKeUW6004899; Tue, 31 Aug 2021 20:40:30 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 17VKeURS004898; Tue, 31 Aug 2021 20:40:30 GMT (envelope-from git) Date: Tue, 31 Aug 2021 20:40:30 GMT Message-Id: <202108312040.17VKeURS004898@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 3138392a46a4 - main - itimer: Serialize access to the p_itimers array MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 3138392a46a4a8ecfb8e36e9970e88bbae9caed3 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 Aug 2021 20:40:30 -0000 The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=3138392a46a4a8ecfb8e36e9970e88bbae9caed3 commit 3138392a46a4a8ecfb8e36e9970e88bbae9caed3 Author: Mark Johnston AuthorDate: 2021-08-31 20:38:05 +0000 Commit: Mark Johnston CommitDate: 2021-08-31 20:38:05 +0000 itimer: Serialize access to the p_itimers array Fix the following race between itimer_proc_continue() and process exit. itimer_proc_continue() may be called via realitexpire(), the real interval timer. Note that exit1() drains this timer _after_ draining and freeing itimers. Moreover, itimers_exit() is called without the process lock held; it only acquires the proc lock when deleting individual itimers, so once they are drained we free p->p_itimers without any synchronization. Thus, itimer_proc_continue() may load a non-NULL p->p_itimers array and iterate over it after it has been freed. Fix the problem by using the process lock when clearing p->p_itimers, to synchronize with itimer_proc_continue(). Formally, accesses to this field should be protected by the process lock anyway, and since the array is allocated lazily this will not incur any overhead in the common case. Reported by: syzbot+c40aa8bf54fe333fc50b@syzkaller.appspotmail.com Reported by: syzbot+929be2f32503bbc3844f@syzkaller.appspotmail.com Reviewed by: kib MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D31759 --- sys/kern/kern_time.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 323ef9a1f7a0..a52dc83e9b4c 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1822,8 +1822,11 @@ itimers_event_exit_exec(int start_idx, struct proc *p) } if (its->its_timers[0] == NULL && its->its_timers[1] == NULL && its->its_timers[2] == NULL) { - free(its, M_SUBPROC); + /* Synchronize with itimer_proc_continue(). */ + PROC_LOCK(p); p->p_itimers = NULL; + PROC_UNLOCK(p); + free(its, M_SUBPROC); } }