From cdf5cfe93ee14942665f3c6ae78a8bf1198e1798 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 13 Jul 2022 20:58:28 -0500 Subject: [PATCH] mkfs: terminate getsubopt arrays properly Having not drank any (or maybe too much) coffee this morning, I typed: $ mkfs.xfs -d agcount=3 -d nrext64=0 Segmentation fault I traced this down to getsubopt walking off the end of the dopts.subopts array. The manpage says you're supposed to terminate the suboptions string array with a NULL entry, but the structure definition uses MAX_SUBOPTS/D_MAX_OPTS directly, which means there is no terminator. Explicitly terminate each suboption array with a NULL entry after making room for it. Signed-off-by: Darrick J. Wong [sandeen: explicitly add NULL terminators & clarify comment] Reviewed-by: Eric Sandeen Signed-off-by: Eric Sandeen --- mkfs/xfs_mkfs.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index fdf6d4a..5cd2f81 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -132,8 +132,11 @@ enum { M_MAX_OPTS, }; -/* Just define the max options array size manually right now */ -#define MAX_SUBOPTS D_MAX_OPTS +/* + * Just define the max options array size manually to the largest + * enum right now, leaving room for a NULL terminator at the end + */ +#define MAX_SUBOPTS (D_MAX_OPTS + 1) #define SUBOPT_NEEDS_VAL (-1LL) #define MAX_CONFLICTS 8 @@ -243,6 +246,7 @@ static struct opt_params bopts = { .ini_section = "block", .subopts = { [B_SIZE] = "size", + [B_MAX_OPTS] = NULL, }, .subopt_params = { { .index = B_SIZE, @@ -269,6 +273,7 @@ static struct opt_params copts = { .name = 'c', .subopts = { [C_OPTFILE] = "options", + [C_MAX_OPTS] = NULL, }, .subopt_params = { { .index = C_OPTFILE, @@ -298,6 +303,7 @@ static struct opt_params dopts = { [D_EXTSZINHERIT] = "extszinherit", [D_COWEXTSIZE] = "cowextsize", [D_DAXINHERIT] = "daxinherit", + [D_MAX_OPTS] = NULL, }, .subopt_params = { { .index = D_AGCOUNT, @@ -434,6 +440,7 @@ static struct opt_params iopts = { [I_ATTR] = "attr", [I_PROJID32BIT] = "projid32bit", [I_SPINODES] = "sparse", + [I_MAX_OPTS] = NULL, }, .subopt_params = { { .index = I_ALIGN, @@ -500,6 +507,7 @@ static struct opt_params lopts = { [L_FILE] = "file", [L_NAME] = "name", [L_LAZYSBCNTR] = "lazy-count", + [L_MAX_OPTS] = NULL, }, .subopt_params = { { .index = L_AGNUM, @@ -592,6 +600,7 @@ static struct opt_params nopts = { [N_SIZE] = "size", [N_VERSION] = "version", [N_FTYPE] = "ftype", + [N_MAX_OPTS] = NULL, }, .subopt_params = { { .index = N_SIZE, @@ -627,6 +636,7 @@ static struct opt_params ropts = { [R_FILE] = "file", [R_NAME] = "name", [R_NOALIGN] = "noalign", + [R_MAX_OPTS] = NULL, }, .subopt_params = { { .index = R_EXTSIZE, @@ -674,6 +684,7 @@ static struct opt_params sopts = { .subopts = { [S_SIZE] = "size", [S_SECTSIZE] = "sectsize", + [S_MAX_OPTS] = NULL, }, .subopt_params = { { .index = S_SIZE, @@ -710,6 +721,7 @@ static struct opt_params mopts = { [M_REFLINK] = "reflink", [M_INOBTCNT] = "inobtcount", [M_BIGTIME] = "bigtime", + [M_MAX_OPTS] = NULL, }, .subopt_params = { { .index = M_CRC, -- 1.8.3.1