From patchwork Wed Mar 1 16:05:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13156206 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 83C14C6FA9D for ; Wed, 1 Mar 2023 16:05:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229905AbjCAQFq (ORCPT ); Wed, 1 Mar 2023 11:05:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57198 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229568AbjCAQFq (ORCPT ); Wed, 1 Mar 2023 11:05:46 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F3D6D3B0E0 for ; Wed, 1 Mar 2023 08:05:37 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id 5E9C7CE1D53 for ; Wed, 1 Mar 2023 16:05:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8DE06C433EF; Wed, 1 Mar 2023 16:05:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1677686734; bh=0HMDhhkhJugUhFUbXgV/Hh1tTHmLnWIsAxmqV5nsMFk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=DVxDnAPUNc63XVXtQzE6ieKy2EJO9n57BTcz3tcpUnYw3jzCBPhZGnKnHcjrSakKf XPeoHL3dHjhFCoF2Kw/CFsdslbP1q4ReXboH+l+89mi1/JAs1j4ucgolSfDwr1KnDj snIhp4nVaXIWFy2iSSfe4xMrN/f9mx0FGrbr3MhqHcBWZbT5XSMREbBpMwNekcSc4H Z+smYQPJLFtiEw/4sAVfGBiXGJ7HZllouO4u9XJVwVQv04mo8csyFHe6CAL40qKQNy lErGyNFfFZtdSKlKmiRqGPbokTuSOBQq5/FHmEnaqDuhAzunKrq2eelFqVwOrzon6H EqETEygQnOUmg== Subject: [PATCH 1/3] mkfs: check dirent names when reading protofile From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org, daan.j.demeyer@gmail.com Date: Wed, 01 Mar 2023 08:05:34 -0800 Message-ID: <167768673411.4130726.18042131075742150245.stgit@magnolia> In-Reply-To: <167768672841.4130726.1758921319115777334.stgit@magnolia> References: <167768672841.4130726.1758921319115777334.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong The protofile parser in mkfs does not check directory entry names when populating the filesystem. The libxfs directory code doesn't check them either, since they depend on the Linux VFS to sanitize incoming names. If someone puts a slash in the first (name) column in the protofile, this results in a successful format and xfs_repair -n immediately complains. Screen the names that are being read from the protofile. Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino --- mkfs/proto.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mkfs/proto.c b/mkfs/proto.c index 68ecdbf3632..7e3fc1b8134 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -326,6 +326,12 @@ newdirent( int error; int rsv; + if (!libxfs_dir2_namecheck(name->name, name->len)) { + fprintf(stderr, _("%.*s: invalid directory entry name\n"), + name->len, name->name); + exit(1); + } + rsv = XFS_DIRENTER_SPACE_RES(mp, name->len); error = -libxfs_dir_createname(tp, pip, name, inum, rsv); From patchwork Wed Mar 1 16:05:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13156207 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 007A2C64ED6 for ; Wed, 1 Mar 2023 16:05:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229921AbjCAQFr (ORCPT ); Wed, 1 Mar 2023 11:05:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229884AbjCAQFr (ORCPT ); Wed, 1 Mar 2023 11:05:47 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E5F7039B95 for ; Wed, 1 Mar 2023 08:05:42 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 98787B8103F for ; Wed, 1 Mar 2023 16:05:41 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 408F5C4339B; Wed, 1 Mar 2023 16:05:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1677686740; bh=2cXpXJprlynpsT0EIYmiBV/+8ECDSj/cXnPU+3eRE7c=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=TxKqsRbv4GBe56fEtnt1AauLuApUSFpa7Jsa7HBZ1UCm5fDq0visYoAUDwaKg8DbF AAv5Jcw58QSCQn6loGDos/Owh7efRroUbu4rmeeobn0KawKhpDOYuopQNCD5HOZqOg mv6LaGggLvG/Tlp9VM6noV3/1fT/fEwS4CYYCuonJ0pUCV3ET5+jUoc/twJwU/ft0y L/kRtIIx8irzIybTRwhdI51uXUmpI1LdNWVWeVDFcraCQe/7RC6gY7p6Uc/7a9Y3Rq YSzzLFA/oiBTUv+gSgCwFfwJnnajfhxHx/jRlMEfP4cbnuzZqbTS4jbIKFpjAaFOnp IV6R64p+imHFg== Subject: [PATCH 2/3] mkfs: use suboption processing for -p From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org, daan.j.demeyer@gmail.com Date: Wed, 01 Mar 2023 08:05:39 -0800 Message-ID: <167768673971.4130726.11629972047221894699.stgit@magnolia> In-Reply-To: <167768672841.4130726.1758921319115777334.stgit@magnolia> References: <167768672841.4130726.1758921319115777334.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Use suboption processing for -p so that we can add a few behavioral variants to protofiles in the next patch. As a side effect of this change, one can now provide the path to a protofile in the config file: [proto] file=/tmp/protofile Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino --- man/man8/mkfs.xfs.8.in | 26 ++++++++++++++++++---- mkfs/xfs_mkfs.c | 58 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in index 211e7b0c7b8..e1ca40e5da6 100644 --- a/man/man8/mkfs.xfs.8.in +++ b/man/man8/mkfs.xfs.8.in @@ -28,7 +28,7 @@ mkfs.xfs \- construct an XFS filesystem .I naming_options ] [ .B \-p -.I protofile +.I protofile_options ] [ .B \-q ] [ @@ -834,12 +834,29 @@ When CRCs are enabled (the default), the ftype functionality is always enabled, and cannot be turned off. .IP In other words, this option is only tunable on the deprecated V4 format. -.IP .RE +.PP +.PD 0 .TP -.BI \-p " protofile" +.BI \-p " protofile_options" +.TP +.BI "Section Name: " [proto] +.PD +These options specify the protofile parameters for populating the filesystem. +The valid +.I protofile_options +are: +.RS 1.2i +.TP +.BI [file=] protofile +The +.B file= +prefix is not required for this CLI argument for legacy reasons. +If specified as a config file directive, the prefix is required. + If the optional -.BI \-p " protofile" +.PD +.I protofile argument is given, .B mkfs.xfs uses @@ -979,6 +996,7 @@ in the directory. A scan of the protofile is always terminated with the dollar ( .B $ ) token. +.RE .TP .B \-q Quiet option. Normally diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index e219ec166da..4248e6ec344 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -113,6 +113,11 @@ enum { N_MAX_OPTS, }; +enum { + P_FILE = 0, + P_MAX_OPTS, +}; + enum { R_EXTSIZE = 0, R_SIZE, @@ -641,6 +646,21 @@ static struct opt_params nopts = { }, }; +static struct opt_params popts = { + .name = 'p', + .ini_section = "proto", + .subopts = { + [P_FILE] = "file", + [P_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = P_FILE, + .conflicts = { { NULL, LAST_CONFLICT } }, + .defaultval = SUBOPT_NEEDS_VAL, + }, + }, +}; + static struct opt_params ropts = { .name = 'r', .ini_section = "realtime", @@ -841,6 +861,7 @@ struct cli_params { int blocksize; char *cfgfile; + char *protofile; /* parameters that depend on sector/block size being validated. */ char *dsize; @@ -1750,6 +1771,33 @@ naming_opts_parser( return 0; } +static int +proto_opts_parser( + struct opt_params *opts, + int subopt, + const char *value, + struct cli_params *cli) +{ + switch (subopt) { + case P_FILE: + fallthrough; + default: + if (cli->protofile) { + if (subopt < 0) + subopt = P_FILE; + respec(opts->name, opts->subopts, subopt); + } + cli->protofile = strdup(value); + if (!cli->protofile) { + fprintf(stderr, + _("Out of memory while saving protofile option.\n")); + exit(1); + } + break; + } + return 0; +} + static int rtdev_opts_parser( struct opt_params *opts, @@ -1813,6 +1861,7 @@ static struct subopts { { &lopts, log_opts_parser }, { &mopts, meta_opts_parser }, { &nopts, naming_opts_parser }, + { &popts, proto_opts_parser }, { &ropts, rtdev_opts_parser }, { &sopts, sector_opts_parser }, { NULL, NULL }, @@ -4013,7 +4062,6 @@ main( int discard = 1; int force_overwrite = 0; int quiet = 0; - char *protofile = NULL; char *protostring = NULL; int worst_freelist = 0; @@ -4119,6 +4167,7 @@ main( case 'l': case 'm': case 'n': + case 'p': case 'r': case 's': parse_subopts(c, optarg, &cli); @@ -4134,11 +4183,6 @@ main( case 'K': discard = 0; break; - case 'p': - if (protofile) - respec('p', NULL, 0); - protofile = optarg; - break; case 'q': quiet = 1; break; @@ -4165,7 +4209,7 @@ main( */ cfgfile_parse(&cli); - protostring = setup_proto(protofile); + protostring = setup_proto(cli.protofile); /* * Extract as much of the valid config as we can from the CLI input From patchwork Wed Mar 1 16:05:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13156208 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A0D1C6FA9D for ; Wed, 1 Mar 2023 16:05:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229885AbjCAQFw (ORCPT ); Wed, 1 Mar 2023 11:05:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229943AbjCAQFu (ORCPT ); Wed, 1 Mar 2023 11:05:50 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 783E143909 for ; Wed, 1 Mar 2023 08:05:48 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 0654FB8109B for ; Wed, 1 Mar 2023 16:05:47 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C1108C433D2; Wed, 1 Mar 2023 16:05:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1677686745; bh=jn7kHBz2nE5sqssqVR/13KgMbPWL3Nme2mU7gvjzgto=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=qSu2Q+xauCb12bu+x1OCipJkvHfoxjExvFMGY9KmksqS03m+ecxKzZ9MkaXLl2AGR AF1ktlvf0/sHDmJ61EAy75jq7ayW4Vdxvy7vyw2yw75mqeIWAHS/WUtJnjfkUaTLlL CYKONdmnKFR7ab51WTbGVPcIJzrJ623QLm9mFY74h9/O6ddy/Nw/Vufi77Q5m7bDyR ADyz9l45C2aBa8bbRqB5Pk5HX4ys+I9/8HwALJGvSOitrMITjMvMOMMXbqn4tDiQKn imU9s/c6x9UqCWUmWWdgA/VZjDIRFg62D1BhUZcwFO/SYzcXJAxVXcQJbadzpR1M0W +s7IWldiUWB2A== Subject: [PATCH 3/3] mkfs: substitute slashes with spaces in protofiles From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org, daan.j.demeyer@gmail.com Date: Wed, 01 Mar 2023 08:05:45 -0800 Message-ID: <167768674540.4130726.6736563945489484289.stgit@magnolia> In-Reply-To: <167768672841.4130726.1758921319115777334.stgit@magnolia> References: <167768672841.4130726.1758921319115777334.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong A user requested the ability to specify directory entry names in a protofile that have spaces in them. The protofile format itself does not allow spaces (yay 1973-era protofiles!) but it does allow slashes. Slashes aren't allowed in directory entry names, so we'll permit this one gross hack. After this, the protofile: / 0 0 d--775 1000 1000 : Descending path /code/t/fstests get/isk.sh ---775 1000 1000 /code/t/fstests/getdisk.sh $ Will produce "get isk.h" in the root directory when used thusly: # mkfs.xfs -p slashes_are_spaces=1,/tmp/protofile -f /dev/sda Requested-by: Daan De Meyer Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino --- man/man8/mkfs.xfs.8.in | 6 ++++++ mkfs/proto.c | 31 +++++++++++++++++++++++++++++-- mkfs/proto.h | 3 ++- mkfs/xfs_mkfs.c | 14 +++++++++++++- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in index e1ca40e5da6..49e64d47ae4 100644 --- a/man/man8/mkfs.xfs.8.in +++ b/man/man8/mkfs.xfs.8.in @@ -996,6 +996,12 @@ in the directory. A scan of the protofile is always terminated with the dollar ( .B $ ) token. +.TP +.BI slashes_are_spaces= value +If set to 1, slashes ("/") in the first token of each line of the protofile +are converted to spaces. +This enables the creation of a filesystem containing filenames with spaces. +By default, this is set to 0. .RE .TP .B \-q diff --git a/mkfs/proto.c b/mkfs/proto.c index 7e3fc1b8134..ea31cfe5cfc 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -21,6 +21,7 @@ static int newfile(xfs_trans_t *tp, xfs_inode_t *ip, int symlink, int logit, static char *newregfile(char **pp, int *len); static void rtinit(xfs_mount_t *mp); static long filesize(int fd); +static int slashes_are_spaces; /* * Use this for block reservations needed for mkfs's conditions @@ -171,6 +172,30 @@ getstr( return NULL; } +/* Extract directory entry name from a protofile. */ +static char * +getdirentname( + char **pp) +{ + char *p = getstr(pp); + char *c = p; + + if (!p) + return NULL; + + if (!slashes_are_spaces) + return p; + + /* Replace slash with space because slashes aren't allowed. */ + while (*c) { + if (*c == '/') + *c = ' '; + c++; + } + + return p; +} + static void rsvfile( xfs_mount_t *mp, @@ -586,7 +611,7 @@ parseproto( rtinit(mp); tp = NULL; for (;;) { - name = getstr(pp); + name = getdirentname(pp); if (!name) break; if (strcmp(name, "$") == 0) @@ -612,8 +637,10 @@ void parse_proto( xfs_mount_t *mp, struct fsxattr *fsx, - char **pp) + char **pp, + int proto_slashes_are_spaces) { + slashes_are_spaces = proto_slashes_are_spaces; parseproto(mp, NULL, fsx, pp, NULL); } diff --git a/mkfs/proto.h b/mkfs/proto.h index 3c4010afd19..be1ceb45421 100644 --- a/mkfs/proto.h +++ b/mkfs/proto.h @@ -7,7 +7,8 @@ #define MKFS_PROTO_H_ char *setup_proto(char *fname); -void parse_proto(struct xfs_mount *mp, struct fsxattr *fsx, char **pp); +void parse_proto(struct xfs_mount *mp, struct fsxattr *fsx, char **pp, + int proto_slashes_are_spaces); void res_failed(int err); #endif /* MKFS_PROTO_H_ */ diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 4248e6ec344..4399bf3792f 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -115,6 +115,7 @@ enum { enum { P_FILE = 0, + P_SLASHES, P_MAX_OPTS, }; @@ -651,6 +652,7 @@ static struct opt_params popts = { .ini_section = "proto", .subopts = { [P_FILE] = "file", + [P_SLASHES] = "slashes_are_spaces", [P_MAX_OPTS] = NULL, }, .subopt_params = { @@ -658,6 +660,12 @@ static struct opt_params popts = { .conflicts = { { NULL, LAST_CONFLICT } }, .defaultval = SUBOPT_NEEDS_VAL, }, + { .index = P_SLASHES, + .conflicts = { { NULL, LAST_CONFLICT } }, + .minval = 0, + .maxval = 1, + .defaultval = 1, + }, }, }; @@ -881,6 +889,7 @@ struct cli_params { int loginternal; int lsunit; int is_supported; + int proto_slashes_are_spaces; /* parameters where 0 is not a valid value */ int64_t agcount; @@ -1779,6 +1788,9 @@ proto_opts_parser( struct cli_params *cli) { switch (subopt) { + case P_SLASHES: + cli->proto_slashes_are_spaces = getnum(value, opts, subopt); + break; case P_FILE: fallthrough; default: @@ -4368,7 +4380,7 @@ main( /* * Allocate the root inode and anything else in the proto file. */ - parse_proto(mp, &cli.fsx, &protostring); + parse_proto(mp, &cli.fsx, &protostring, cli.proto_slashes_are_spaces); /* * Protect ourselves against possible stupidity