Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp2236141imm; Thu, 2 Aug 2018 08:18:07 -0700 (PDT) X-Google-Smtp-Source: AAOMgpejKKnPLZZyEVPNM6afcXWl5DkinB+ZXYFroOLCH78+bxTc01ReLo/P/tQK0tfZw4nUUxk1 X-Received: by 2002:a17:902:8506:: with SMTP id bj6-v6mr2734604plb.210.1533223087789; Thu, 02 Aug 2018 08:18:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533223087; cv=none; d=google.com; s=arc-20160816; b=nadFA3MenEw9jMAZ965qdeBLy95DloUiSdHPvBvitaXp7sJCwQIt0wAhc4GGUp/Br0 21QPAjEfGHFhZixSMzs7bSX3HC4IOKipPD9tVbRUKZ9mbgMHtJLPhcJlBaJ4nXh4axY+ cPLr7dYtgR3Gjl49wFsGpZp0MdSxZtPvAjUuHnFzjPsPaoQJiWAxMJg6Q2R/1NDS0Z3d MLyGrEZKYhiiPvVVWI7H2XI0bVnpBGXfpvCUYTO1HZ++v5YT8TLCuX08q73WWE2VlnXU Cncm5IEUW2QxYxU1RfQzLDeZDyWnR4kPxlCAqZIy+kFVCOJM/vmrjRnb5qF4AYM5iCvy mN2A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:mime-version :message-id:date:dkim-signature:arc-authentication-results; bh=6sQbQQ0iCDtdUpVAZxvEQ0oR/nl1vjCXI7dHj4pP/rE=; b=Y+zfLQNf8dGFRwegK+9O6Wqy28leXKA0tNweAsNnQclb8o44yhtj6F9Pu9txOMj6DS FoaEED/QKjRQ5tLoKikFugFEwAidZRD7fsLiwKcqKtiyP44A7Oyx/RlhKMyWa2tTs5cC FU5KDbNwwTizVADzR9d/DpLtJPlIwWCJVp4XwvckAKYeMQZ09Dwt92urukReHUIa+wC7 ZaAzTT08PSl6CTMRBFJoq5zSwf1YMLcO1ul/UxEjMr1L0gcZUxd26jso8Krxp4yM3EK2 w8omZESPitNunoIX6olD+XQr1xkskGzUr4JlIY/E2oL8V2AqB5cv+TuqECJnlVajvGc4 G7DA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=Nu8NNdVB; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x5-v6si1578815plv.19.2018.08.02.08.17.52; Thu, 02 Aug 2018 08:18:07 -0700 (PDT) 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=@google.com header.s=20161025 header.b=Nu8NNdVB; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732637AbeHBRHm (ORCPT + 99 others); Thu, 2 Aug 2018 13:07:42 -0400 Received: from mail-qt0-f202.google.com ([209.85.216.202]:35817 "EHLO mail-qt0-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732625AbeHBRHl (ORCPT ); Thu, 2 Aug 2018 13:07:41 -0400 Received: by mail-qt0-f202.google.com with SMTP id x26-v6so1877197qtb.2 for ; Thu, 02 Aug 2018 08:16:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=6sQbQQ0iCDtdUpVAZxvEQ0oR/nl1vjCXI7dHj4pP/rE=; b=Nu8NNdVBvtru4KHtYB3VYmjMcs0N0yWXF0tsNCJBLwJn6b+i1S3XKnOruOoEjZ76kq ib8qYFo1Sto9bXQGsGZXZXuWFDXFwHCCV0KZ/9eTNLTY5L8Ld8NY10CTHRdmUGoyYICl 0xo4Qo2mtMNEHnr+Fgk2CWsJxBHY039H+a19BZb4gVboxGj3/QrIFOFc6sp0kBX+64Y3 M6uMfrG0pBH5ZKO/NnDGsZZK3EFdN/PC+TAvEvzKQZGK8L/k60WGZDfa30z7s/RhMAXv uA7Yy//6lBntU9oio4FBQtpItqORVFN+AY0JcyKjcUj4rXRBgIwe3wRw3BG8FtACTdwU UhLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=6sQbQQ0iCDtdUpVAZxvEQ0oR/nl1vjCXI7dHj4pP/rE=; b=BDqgpK9h43kyg7rZMoz308HalG4GxVmsomCyIVW1Ay4IHx+hXPnNhsfNoe9elynvdM IZMa9w1lPrVg8Wbd/2GguUjJY34MVwHqasUfHwLGhKG3hdU54v0LaRZeyOhc5A1bR0sQ C6/ZpOxo3+2JqwxrpIjOhvMpIWYy2dlOcLtxLNiuzU4Ufbahcrp+VNhT66xY7wOAasRA wepfGrJavLaHtaRzbJLwr/36aSvfwSbTS7CvKLGqBUAVjpGtWuOvaKSaPXMnAXLS5AC1 Mxv+e53/1SdadHvotvGRFQvNduksjhrlrDXWKPCNuRm5pxuKiB6OCbp6qBxQzQDxOITV amew== X-Gm-Message-State: AOUpUlF+Wagj+NKornc1YUgl37458cgblBuINv9csszenLOaj5qv0GdJ eFEadLT9gDcgcJO6Ke6NP0zWU7OLCA== X-Received: by 2002:a0c:c711:: with SMTP id w17-v6mr1773203qvi.9.1533222963567; Thu, 02 Aug 2018 08:16:03 -0700 (PDT) Date: Thu, 2 Aug 2018 17:15:39 +0200 Message-Id: <20180802151539.5373-1-jannh@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.18.0.597.ga71716f1ad-goog Subject: [PATCH] reiserfs: fix broken xattr handling (heap corruption, bad retval) From: Jann Horn To: reiserfs-devel@vger.kernel.org, Andrew Morton , jannh@google.com Cc: linux-kernel@vger.kernel.org, Jeff Mahoney , Eric Biggers , Al Viro Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This fixes the following issues: - When a buffer size is supplied to reiserfs_listxattr() such that each individual name fits, but the concatenation of all names doesn't fit, reiserfs_listxattr() overflows the supplied buffer. This leads to a kernel heap overflow (verified using KASAN) followed by an out-of-bounds usercopy and is therefore a security bug. - When a buffer size is supplied to reiserfs_listxattr() such that a name doesn't fit, -ERANGE should be returned. But reiserfs instead just truncates the list of names; I have verified that if the only xattr on a file has a longer name than the supplied buffer length, listxattr() incorrectly returns zero. With my patch applied, -ERANGE is returned in both cases and the memory corruption doesn't happen anymore. Credit for making me clean this code up a bit goes to Al Viro, who pointed out that the ->actor calling convention is suboptimal and should be changed. Fixes: 48b32a3553a5 ("reiserfs: use generic xattr handlers") Cc: stable@vger.kernel.org Signed-off-by: Jann Horn --- Triggering the bug: root@debian:/home/user# mount -o user_xattr reiserimg reisermount/ root@debian:/home/user# cd reisermount/ root@debian:/home/user/reisermount# touch test_file root@debian:/home/user/reisermount# setfattr -n user.foo1 -v A test_file root@debian:/home/user/reisermount# setfattr -n user.foo2 -v A test_file root@debian:/home/user/reisermount# setfattr -n user.foo3 -v A test_file root@debian:/home/user/reisermount# setfattr -n user.foo4 -v A test_file root@debian:/home/user/reisermount# setfattr -n user.foo5 -v A test_file root@debian:/home/user/reisermount# setfattr -n user.foo6 -v A test_file root@debian:/home/user/reisermount# cat xattr_test.c #include #include #include #include #include int main(int argc, char **argv) { if (argc != 2) errx(1, "bad invocation"); char list[10]; int res = listxattr(argv[1], list, sizeof(list)); if (res == -1) err(1, "listxattr failed"); printf("listxattr returned %d\n", res); for (char *p = list; p < list+res-1; p = p + strlen(p) + 1) { printf("list entry: %s\n", p); } } root@debian:/home/user/reisermount# gcc -o xattr_test xattr_test.c root@debian:/home/user/reisermount# ./xattr_test test_file Segmentation fault root@debian:/home/user/reisermount# Result: [ 122.071318] ================================================================== [ 122.072334] BUG: KASAN: slab-out-of-bounds in listxattr_filler+0x170/0x1b0 [ 122.073173] Write of size 9 at addr ffff8801c43b474a by task xattr_test/923 [ 122.074030] [ 122.074223] CPU: 1 PID: 923 Comm: xattr_test Not tainted 4.18.0-rc7+ #67 [ 122.075050] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 [ 122.076107] Call Trace: [ 122.076453] dump_stack+0x71/0xab [ 122.076900] print_address_description+0x6a/0x250 [ 122.077514] kasan_report+0x258/0x380 [ 122.077961] ? listxattr_filler+0x170/0x1b0 [ 122.078469] memcpy+0x34/0x50 [ 122.078894] listxattr_filler+0x170/0x1b0 [...] fs/reiserfs/xattr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index ff94fad477e4..48cdfc81fe10 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -792,8 +792,10 @@ static int listxattr_filler(struct dir_context *ctx, const char *name, return 0; size = namelen + 1; if (b->buf) { - if (size > b->size) + if (b->pos + size > b->size) { + b->pos = -ERANGE; return -ERANGE; + } memcpy(b->buf + b->pos, name, namelen); b->buf[b->pos + namelen] = 0; } -- 2.18.0.597.ga71716f1ad-goog