Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp4864973pxu; Thu, 10 Dec 2020 07:18:59 -0800 (PST) X-Google-Smtp-Source: ABdhPJy+iNWtD38vfJNR7m0o12VnxGbRCg+7Q6EvOCvtJ3ZEa6fPyAxC8Qo/BkCS6r6lIwhDoN26 X-Received: by 2002:a50:b264:: with SMTP id o91mr7269602edd.7.1607613539505; Thu, 10 Dec 2020 07:18:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1607613539; cv=none; d=google.com; s=arc-20160816; b=ZwYu+Rf8HRFwSKN4BaMSuf0d5KSDOCvsqnaR+NRxDv576Te+Ih1sYbZPpmMVXGqfvY JiZDgf6ONHOXAw7msbxIBJp7XlcOj4SNuSTJje6gaSB2mAFRiZusxLuL5e3XGQYDLueP 37K6m61CsAd83OFMLyiC+sHL6Sb1uZqCZ1S5zi5nUnYMfGrFdjp4Aea+2H8w3UpQICwT nW5Q61QZIpcefvOLXcZmqK986ubkDl9lStoP7DP9+sqnO+LOI3JHpL5Z9V9Z8+Am6xI5 cKUo+MWvrmFFMYRilZbgBrZy052IAFe8JziskLgzh40PKQ5SLbjqi4YuEiojoVjMb8tj 7UKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=vDksITqet6xSjetWwUwp3cPA+5zAH5P4/2VxwWW6hGA=; b=Y8JNeCS+HY9G/SuQLF84N/n7Qy/LXziGDlVCEf8KxlqEnxYsvyIlnFTVhpjfY18YHQ hCLmuG+IwSk0hOAfjFM0XYT7F9aL7eVYvwzrwD75s+Hw8I/WSqOmVzzDm3lbJ35iw1FV LjvSrn797/ayBG7obFOAeCikLpw55sScg+IfRJkezZFsFjKHF6LJiGkjC8QnK2mFdHSY E8D/JMXYoZcZwrcOIRVJzKUdht4vvdQy2IrTAGNSIZkGEhQje/97wLA256IgCP1xD7ap GID5Cc8GpkYwlvC4NkgpbWenkGpeaDMtFk9AdkTKWMMBKj/CN6y6OwbVhVrmmHDQP5Qi BCqQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id hs8si2792310ejc.113.2020.12.10.07.18.34; Thu, 10 Dec 2020 07:18:59 -0800 (PST) Received-SPF: pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389126AbgLJPFk (ORCPT + 99 others); Thu, 10 Dec 2020 10:05:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37920 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389475AbgLJPFe (ORCPT ); Thu, 10 Dec 2020 10:05:34 -0500 Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF5F1C0617A6 for ; Thu, 10 Dec 2020 07:04:05 -0800 (PST) Received: from xps.home (unknown [IPv6:2a01:e35:2fb5:1510:1626:c942:e0f1:c77c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: aferraris) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id AA2991F458FA; Thu, 10 Dec 2020 15:04:03 +0000 (GMT) From: Arnaud Ferraris To: linux-ext4@vger.kernel.org Cc: drosen@google.com, krisman@collabora.com, ebiggers@kernel.org, tytso@mit.edu, Arnaud Ferraris Subject: [PATCH RESEND v2 06/12] e2fsck: Fix entries with invalid encoded characters Date: Thu, 10 Dec 2020 16:03:47 +0100 Message-Id: <20201210150353.91843-7-arnaud.ferraris@collabora.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201210150353.91843-1-arnaud.ferraris@collabora.com> References: <20201210150353.91843-1-arnaud.ferraris@collabora.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Gabriel Krisman Bertazi On strict mode, invalid Unicode sequences are not permited. This patch adds a verification step to pass2 to detect and modify the entries with the same replacement char used for non-encoding directories '.'. After the encoding test, we still want to check the name for usual problems, '\0', '/' in the middle of the sequence. Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Arnaud Ferraris --- Changes in v2: - added missing comment - uses the problem code introduced by the previous patch - reworked a test to ease future support of encrypted+casefolded directories e2fsck/e2fsck.c | 4 ++++ e2fsck/e2fsck.h | 1 + e2fsck/pass1.c | 18 +++++++++++++++++ e2fsck/pass2.c | 51 ++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c index d8be566f..dc4b45e2 100644 --- a/e2fsck/e2fsck.c +++ b/e2fsck/e2fsck.c @@ -75,6 +75,10 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx) ext2fs_free_block_bitmap(ctx->block_found_map); ctx->block_found_map = 0; } + if (ctx->inode_casefold_map) { + ext2fs_free_block_bitmap(ctx->inode_casefold_map); + ctx->inode_casefold_map = 0; + } if (ctx->inode_link_info) { ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0; diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 85f953b2..dcaab0a1 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -262,6 +262,7 @@ struct e2fsck_struct { ext2fs_inode_bitmap inode_bb_map; /* Inodes which are in bad blocks */ ext2fs_inode_bitmap inode_imagic_map; /* AFS inodes */ ext2fs_inode_bitmap inode_reg_map; /* Inodes which are regular files*/ + ext2fs_inode_bitmap inode_casefold_map; /* Inodes which are casefolded */ ext2fs_block_bitmap block_found_map; /* Blocks which are in use */ ext2fs_block_bitmap block_dup_map; /* Blks referenced more than once */ diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 8eecd958..6909fed5 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -23,6 +23,7 @@ * - A bitmap of which inodes have bad fields. (inode_bad_map) * - A bitmap of which inodes are in bad blocks. (inode_bb_map) * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) + * - A bitmap of which inodes are casefolded. (inode_casefold_map) * - A bitmap of which blocks are in use. (block_found_map) * - A bitmap of which blocks are in use by two inodes (block_dup_map) * - The data blocks of the directory inodes. (dir_map) @@ -1260,6 +1261,20 @@ void e2fsck_pass1(e2fsck_t ctx) ctx->flags |= E2F_FLAG_ABORT; return; } + if (casefold_fs) { + pctx.errcode = + e2fsck_allocate_inode_bitmap(fs, + _("inode casefold map"), + EXT2FS_BMAP64_RBTREE, + "inode_casefold_map", + &ctx->inode_casefold_map); + if (pctx.errcode) { + pctx.num = 1; + fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); + ctx->flags |= E2F_FLAG_ABORT; + return; + } + } pctx.errcode = e2fsck_setup_icount(ctx, "inode_link_info", 0, NULL, &ctx->inode_link_info); if (pctx.errcode) { @@ -1870,6 +1885,9 @@ void e2fsck_pass1(e2fsck_t ctx) add_encrypted_file(ctx, &pctx) < 0) goto clear_inode; + if (casefold_fs && inode->i_flags & EXT4_CASEFOLD_FL) + ext2fs_mark_inode_bitmap2(ctx->inode_casefold_map, ino); + if (LINUX_S_ISDIR(inode->i_mode)) { ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino); e2fsck_add_dir_info(ctx, ino, 0); diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 4dbc44ea..b9402b24 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -36,11 +36,13 @@ * - The inode_bad_map bitmap * - The inode_dir_map bitmap * - The encrypted_file_info + * - The inode_casefold_map bitmap * * Pass 2 frees the following data structures * - The inode_bad_map bitmap * - The inode_reg_map bitmap * - The encrypted_file_info + * - The inode_casefold_map bitmap */ #define _GNU_SOURCE 1 /* get strnlen() */ @@ -287,6 +289,10 @@ void e2fsck_pass2(e2fsck_t ctx) ext2fs_free_inode_bitmap(ctx->inode_reg_map); ctx->inode_reg_map = 0; } + if (ctx->inode_casefold_map) { + ext2fs_free_inode_bitmap(ctx->inode_casefold_map); + ctx->inode_casefold_map = 0; + } destroy_encrypted_file_info(ctx); clear_problem_context(&pctx); @@ -515,6 +521,30 @@ static int encrypted_check_name(e2fsck_t ctx, return 0; } +static int encoded_check_name(e2fsck_t ctx, + struct ext2_dir_entry *dirent, + struct problem_context *pctx) +{ + const struct ext2fs_nls_table *tbl = ctx->fs->encoding; + int ret; + int len = ext2fs_dirent_name_len(dirent); + char *pos, *end; + + ret = ext2fs_check_encoded_name(tbl, dirent->name, len, &pos); + if (ret < 0) { + fatal_error(ctx, _("NLS is broken.")); + } else if(ret > 0) { + ret = fix_problem(ctx, PR_2_BAD_CASEFOLDED_NAME, pctx); + if (ret) { + end = &dirent->name[len]; + for (; *pos && pos != end; pos++) + *pos = '.'; + } + } + + return (ret || check_name(ctx, dirent, pctx)); +} + /* * Check the directory filetype (if present) */ @@ -998,11 +1028,18 @@ static int check_dir_block(ext2_filsys fs, size_t max_block_size; int hash_flags = 0; static char *eop_read_dirblock = NULL; + int cf_dir = 0; cd = (struct check_dir_struct *) priv_data; ibuf = buf = cd->buf; ctx = cd->ctx; + /* We only want filename encoding verification on strict + * mode. */ + if (ext2fs_test_inode_bitmap2(ctx->inode_casefold_map, ino) && + (ctx->fs->super->s_encoding_flags & EXT4_ENC_STRICT_MODE_FL)) + cf_dir = 1; + if (ctx->flags & E2F_FLAG_RUN_RETURN) return DIRENT_ABORT; @@ -1483,11 +1520,7 @@ skip_checksum: if (check_filetype(ctx, dirent, ino, &cd->pctx)) dir_modified++; - if (dir_encpolicy_id == NO_ENCRYPTION_POLICY) { - /* Unencrypted directory */ - if (check_name(ctx, dirent, &cd->pctx)) - dir_modified++; - } else { + if (dir_encpolicy_id != NO_ENCRYPTION_POLICY) { /* Encrypted directory */ if (dot_state > 1 && check_encrypted_dirent(ctx, dirent, @@ -1497,6 +1530,14 @@ skip_checksum: dir_modified++; goto next; } + } else if (cf_dir) { + /* Casefolded directory */ + if (encoded_check_name(ctx, dirent, &cd->pctx)) + dir_modified++; + } else { + /* Unencrypted and uncasefolded directory */ + if (check_name(ctx, dirent, &cd->pctx)) + dir_modified++; } if (dx_db) { -- 2.29.2