From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qk0-f196.google.com ([209.85.220.196]:34097 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752122AbdJFVwa (ORCPT ); Fri, 6 Oct 2017 17:52:30 -0400 Received: by mail-qk0-f196.google.com with SMTP id b124so10150280qke.1 for ; Fri, 06 Oct 2017 14:52:30 -0700 (PDT) Date: Fri, 6 Oct 2017 18:52:25 -0300 From: Ernesto =?utf-8?Q?A=2E_Fern=C3=A1ndez?= To: linux-fsdevel@vger.kernel.org Cc: Sergei Antonov , Vyacheslav Dubeyko , Hin-Tak Leung , Al Viro , Christoph Hellwig , Ernesto =?utf-8?Q?A=2E_Fern=C3=A1ndez?= Subject: [PATCH] hfsplus: fix segfault when deleting all attrs of a file Message-ID: <20171006215222.GA4736@debian.home> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Sender: linux-fsdevel-owner@vger.kernel.org List-ID: A segmentation fault can be triggered by setting many xattrs to a file and then deleting it. The number must be high enough for more than one b-tree node to be needed for storage. When hfs_brec_remove() is called as part of hfsplus_delete_all_attrs(), fd->search_key will not be set to any specific value. It does not matter because we intend to remove all records for a given cnid. The problem is that hfs_brec_remove() assumes it is being called with the result of a search by key, not by cnid. The value of search_key may be used to update the parent nodes. When no appropriate parent record is found, the result is an out of bounds access. To fix this, set the value of fd->search_key to the key of the first record in the node, which is also the key of the corresponding parent record. Signed-off-by: Ernesto A. Fernández --- fs/hfsplus/brec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c index 754fdf8..dfa60cf 100644 --- a/fs/hfsplus/brec.c +++ b/fs/hfsplus/brec.c @@ -182,6 +182,9 @@ int hfs_brec_remove(struct hfs_find_data *fd) tree = fd->tree; node = fd->bnode; + + /* in case we need to search the parent node */ + hfs_bnode_read_key(node, fd->search_key, 14); again: rec_off = tree->node_size - (fd->record + 2) * 2; end_off = tree->node_size - (node->num_recs + 1) * 2; -- 2.1.4