From patchwork Wed Dec 2 14:59:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Whitcroft X-Patchwork-Id: 551397 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 7485C14030F; Thu, 3 Dec 2015 02:00:03 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1a48sz-0000yO-42; Wed, 02 Dec 2015 15:00:01 +0000 Received: from mail-wm0-f45.google.com ([74.125.82.45]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1a48sl-0000rv-7Q for kernel-team@lists.ubuntu.com; Wed, 02 Dec 2015 14:59:47 +0000 Received: by wmww144 with SMTP id w144so60478427wmw.0 for ; Wed, 02 Dec 2015 06:59:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=lyiVbLl9dUSAGnRiGEF8cq+pTrM/t6Hk0CTnSaWdJ6I=; b=PnYXROsfabPBb9IerBOfuHk8jNanhs1LDBsl6aEnoFQFNNxsPLB3ZOjsx1UCtqfQFr 5Ur1cx2a4a8gJu/t8mMMnZd/wfUe5gImTTnBwvtqmxRD1OgF5rJDIdho+o17u60iKIIW 8EXPgd8mIZvur5CQR8JGbGhRhgOoKbVJ7VGzvlSvwn9O+ZvDx3QvtrdiJ3qKV+G+fCeG HGem9aPZErVhrwoPa3hd42MtW1D+xTTl0angXEyuoUQ5xG4Xp/ZDWw4iLvQ/Ok4/EPkg 4Zu/XbYzabP/iJNcjD+3k6pMw0Kr/ghMJO8afKX6+iVTm/Hg8/08lvCABRwZIxrL8a8R cTsA== X-Gm-Message-State: ALoCoQkxce36o/FvvmmsuRI/bJk0zmTwoSEkGzi9PCygkMtqDQGLzeov9XWXM83BHJMCzc7Cv+pZ X-Received: by 10.194.111.199 with SMTP id ik7mr5505183wjb.167.1449068387041; Wed, 02 Dec 2015 06:59:47 -0800 (PST) Received: from localhost ([2001:470:6973:2:55ab:1437:1293:1d55]) by smtp.gmail.com with ESMTPSA id h4sm3137036wjx.41.2015.12.02.06.59.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Dec 2015 06:59:46 -0800 (PST) From: Andy Whitcroft To: kernel-team@lists.ubuntu.com Subject: [wily/master-next 4/7] KEYS: Fix crash when attempt to garbage collect an uninstantiated keyring Date: Wed, 2 Dec 2015 14:59:34 +0000 Message-Id: <1449068377-21867-5-git-send-email-apw@canonical.com> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1449068377-21867-1-git-send-email-apw@canonical.com> References: <1449068377-21867-1-git-send-email-apw@canonical.com> Cc: Andy Whitcroft X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: David Howells The following sequence of commands: i=`keyctl add user a a @s` keyctl request2 keyring foo bar @t keyctl unlink $i @s tries to invoke an upcall to instantiate a keyring if one doesn't already exist by that name within the user's keyring set. However, if the upcall fails, the code sets keyring->type_data.reject_error to -ENOKEY or some other error code. When the key is garbage collected, the key destroy function is called unconditionally and keyring_destroy() uses list_empty() on keyring->type_data.link - which is in a union with reject_error. Subsequently, the kernel tries to unlink the keyring from the keyring names list - which oopses like this: BUG: unable to handle kernel paging request at 00000000ffffff8a IP: [] keyring_destroy+0x3d/0x88 ... Workqueue: events key_garbage_collector ... RIP: 0010:[] keyring_destroy+0x3d/0x88 RSP: 0018:ffff88003e2f3d30 EFLAGS: 00010203 RAX: 00000000ffffff82 RBX: ffff88003bf1a900 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 000000003bfc6901 RDI: ffffffff81a73a40 RBP: ffff88003e2f3d38 R08: 0000000000000152 R09: 0000000000000000 R10: ffff88003e2f3c18 R11: 000000000000865b R12: ffff88003bf1a900 R13: 0000000000000000 R14: ffff88003bf1a908 R15: ffff88003e2f4000 ... CR2: 00000000ffffff8a CR3: 000000003e3ec000 CR4: 00000000000006f0 ... Call Trace: [] key_gc_unused_keys.constprop.1+0x5d/0x10f [] key_garbage_collector+0x1fa/0x351 [] process_one_work+0x28e/0x547 [] worker_thread+0x26e/0x361 [] ? rescuer_thread+0x2a8/0x2a8 [] kthread+0xf3/0xfb [] ? kthread_create_on_node+0x1c2/0x1c2 [] ret_from_fork+0x3f/0x70 [] ? kthread_create_on_node+0x1c2/0x1c2 Note the value in RAX. This is a 32-bit representation of -ENOKEY. The solution is to only call ->destroy() if the key was successfully instantiated. Reported-by: Dmitry Vyukov Signed-off-by: David Howells Tested-by: Dmitry Vyukov (cherry picked from commit f05819df10d7b09f6d1eb6f8534a8f68e5a4fe61) CVE-2015-7872 BugLink: http://bugs.launchpad.net/bugs/1508856 Signed-off-by: Andy Whitcroft --- security/keys/gc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/security/keys/gc.c b/security/keys/gc.c index 39eac1f..addf060 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c @@ -134,8 +134,10 @@ static noinline void key_gc_unused_keys(struct list_head *keys) kdebug("- %u", key->serial); key_check(key); - /* Throw away the key data */ - if (key->type->destroy) + /* Throw away the key data if the key is instantiated */ + if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && + !test_bit(KEY_FLAG_NEGATIVE, &key->flags) && + key->type->destroy) key->type->destroy(key); security_key_free(key);