From patchwork Sat Mar 3 00:59:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 880972 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZnLPXoiB"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ztSWL38Gyz9s9F for ; Sat, 3 Mar 2018 11:59:58 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964850AbeCCA75 (ORCPT ); Fri, 2 Mar 2018 19:59:57 -0500 Received: from mail-io0-f195.google.com ([209.85.223.195]:46639 "EHLO mail-io0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964828AbeCCA74 (ORCPT ); Fri, 2 Mar 2018 19:59:56 -0500 Received: by mail-io0-f195.google.com with SMTP id p78so12436570iod.13 for ; Fri, 02 Mar 2018 16:59:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=MT5R1e8gK0d10lA4G9f3iocGehoodrw+rhLgwd6YEj4=; b=ZnLPXoiBXwSQgqwAJ5RiXj5uL2As+ocrdahdPRwWTcgwp6yZxIP6Pmbli+uRJ+UTqL v9XEV3O9efOFAMCgy460tKlQ1n/lReJU7aewDuOOqV8kAVpHYxCnpQeuDD4DSqvV4JWZ LZX8ZAGxEd+UlA2SYI/a7chXFhB3q5jZxaGhvf4Yd9khpzbP64qth/9E42pC89I20Zmb aBG2xZNwjqIPZ6ht/gBbF+FMuAXoPkyiWFS8yjzgM6t8rfT09gs7pWgWAxIdld+XpZH6 UXDwkqycAk9WpzXhYg4H56n0EiqQErX5tsmZ0gAZwutuDLmcgVHpQW1rZlTJz5R9goMT hyMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=MT5R1e8gK0d10lA4G9f3iocGehoodrw+rhLgwd6YEj4=; b=Yx7FP/dxogFMq2myJ09gP1wYM4SYOVHcrnNyl89keloWzIUu2DqZ6s7z+zifL2THKO 4OwozeKKQPY5oHb2yuh4wfaOqcyXmsZrmzkep49NmRjpEaLKZthv1a+24aV8KwKo6p16 KF0fdA3IEzxZIgNJvaU8Pq3VWtLN5qCIvDa0KlxFpjc1k0+3YR2rzXBjr6zxGgALVa7M 19WB4GUphZSoJllc7jT1+eI2ihCXdh1fwMJZQ/KwtYDCXS0h18JueiILCTNq6wkxMxNG papmvkgCvlwZCjYdLOy6jKN6qrsvkfSAj/Bpg7CcoVpM1XK98oSwzfb23aT21vnAQWcM n7mg== X-Gm-Message-State: APf1xPDGKVfbZWSzvEQZXCAf9W4VII7WE4nMeYeEE8pYj1e9Uh9CDIV8 IsnskLau+PC4jQTtyRwAXYsrYdoQ X-Google-Smtp-Source: AG47ELsjJZaslGhTu8pEf1peYYxr9WsF+vZPdcnbZFWosyE8MTK1zIFUMRe11/xVUR7LkOeuReuaJg== X-Received: by 10.107.132.18 with SMTP id g18mr9016044iod.46.1520038795369; Fri, 02 Mar 2018 16:59:55 -0800 (PST) Received: from ebiggers-linuxstation.kir.corp.google.com ([2620:15c:17:3:dc28:5c82:b905:e8a8]) by smtp.gmail.com with ESMTPSA id p135sm1382972itg.44.2018.03.02.16.59.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Mar 2018 16:59:54 -0800 (PST) From: Eric Biggers To: linux-ext4@vger.kernel.org Cc: Eric Biggers Subject: [PATCH 08/10] e2fsck: validate the targets of extent-based symlinks Date: Fri, 2 Mar 2018 16:59:21 -0800 Message-Id: <20180303005923.152761-9-ebiggers3@gmail.com> X-Mailer: git-send-email 2.16.2.395.g2e18187dfd-goog In-Reply-To: <20180303005923.152761-1-ebiggers3@gmail.com> References: <20180303005923.152761-1-ebiggers3@gmail.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Eric Biggers e2fsck is validating the target (requiring that it be NUL-terminated at i_size, or something a bit different for encrypted symlinks) of slow symlinks that use a traditional block list but not ones that use an extent tree. As far as I can tell this is simply a bug: there's no reason for the representation of the block list to affect how the symlink target is validated. And either way the kernel won't create symlinks with embedded NULs and will always add a terminating NUL. Thus, make e2fsck_pass1_check_symlink() start validating the targets of extent-based symlinks. Fixes: 7cadc57780f3 ("e2fsck: Support long symlinks which use extents") Signed-off-by: Eric Biggers --- e2fsck/pass1.c | 74 ++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 3a49e020..46d70d14 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -185,42 +185,16 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino, { unsigned int buflen; unsigned int len; - int i; - ext2_extent_handle_t handle; - struct ext2_extent_info info; - struct ext2fs_extent extent; if ((inode->i_size_high || inode->i_size == 0) || (inode->i_flags & EXT2_INDEX_FL)) return 0; - if (inode->i_flags & EXT4_EXTENTS_FL) { - if (inode->i_flags & EXT4_INLINE_DATA_FL) - return 0; - if (inode->i_size > fs->blocksize) - return 0; - if (ext2fs_extent_open2(fs, ino, inode, &handle)) - return 0; - i = 0; - if (ext2fs_extent_get_info(handle, &info) || - (info.num_entries != 1) || - (info.max_depth != 0)) - goto exit_extent; - if (ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent) || - (extent.e_lblk != 0) || - (extent.e_len != 1) || - (extent.e_pblk < fs->super->s_first_data_block) || - (extent.e_pblk >= ext2fs_blocks_count(fs->super))) - goto exit_extent; - i = 1; - exit_extent: - ext2fs_extent_free(handle); - return i; - } - if (inode->i_flags & EXT4_INLINE_DATA_FL) { size_t inline_size; + if (inode->i_flags & EXT4_EXTENTS_FL) + return 0; if (ext2fs_inline_data_size(fs, ino, &inline_size)) return 0; if (inode->i_size != inline_size) @@ -229,19 +203,49 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino, return 1; } - if (ext2fs_is_fast_symlink(inode)) { + if (ext2fs_is_fast_symlink(inode) && + !(inode->i_flags & EXT4_EXTENTS_FL)) { + buf = (char *)inode->i_block; buflen = sizeof(inode->i_block); } else { - if ((inode->i_block[0] < fs->super->s_first_data_block) || - (inode->i_block[0] >= ext2fs_blocks_count(fs->super))) - return 0; + ext2_extent_handle_t handle; + struct ext2_extent_info info; + struct ext2fs_extent extent; + blk64_t blk; + int i; - for (i = 1; i < EXT2_N_BLOCKS; i++) - if (inode->i_block[i]) + if (inode->i_flags & EXT4_EXTENTS_FL) { + if (ext2fs_extent_open2(fs, ino, inode, &handle)) + return 0; + if (ext2fs_extent_get_info(handle, &info) || + (info.num_entries != 1) || + (info.max_depth != 0)) { + ext2fs_extent_free(handle); + return 0; + } + if (ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, + &extent) || + (extent.e_lblk != 0) || + (extent.e_len != 1)) { + ext2fs_extent_free(handle); return 0; + } + blk = extent.e_pblk; + ext2fs_extent_free(handle); + } else { + blk = inode->i_block[0]; + + for (i = 1; i < EXT2_N_BLOCKS; i++) + if (inode->i_block[i]) + return 0; + } + + if (blk < fs->super->s_first_data_block || + blk >= ext2fs_blocks_count(fs->super)) + return 0; - if (io_channel_read_blk64(fs->io, inode->i_block[0], 1, buf)) + if (io_channel_read_blk64(fs->io, blk, 1, buf)) return 0; buflen = fs->blocksize;