FAILED: patch "[PATCH] staging: erofs: keep corrupted fs from crashing kernel in" failed to apply to 4.19-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 33bac912840fe64dbc15556302537dc6a17cac63 Mon Sep 17 00:00:00 2001
From: Gao Xiang <[email protected]>
Date: Fri, 29 Mar 2019 04:14:58 +0800
Subject: [PATCH] staging: erofs: keep corrupted fs from crashing kernel in
erofs_readdir()
After commit 419d6efc50e9, kernel cannot be crashed in the namei path. However, corrupted nameoff can do harm in the process of readdir for scenerios without dm-verity as well. Fix it now.
Fixes 3aa8ec716e52 ("staging: erofs: add directory operations")
Cc <[email protected]> # 4.19+
Signed-off-by Gao Xiang <[email protected]>
Reviewed-by Chao Yu <[email protected]>
Signed-off-by Greg Kroah-Hartman <[email protected]>
drivers/staging/erofs/dir.c +25 -20
@@ -23,6 +23,21 @@ static const unsigned char erofs_filetype_table[EROFS_FT_MAX] = { [EROFS_FT_SYMLINK] = DT_LNK, }; +static void debug_one_dentry (unsigned char d_type,const char *de_name, +unsigned int de_namelen) +{ +#ifdef CONFIG_EROFS_FS_DEBUG +/* since the on-disk name could not have the trailing '\0' */ +unsigned char dbg_namebuf[EROFS_NAME_LEN +1 ]; + +memcpy (dbg_namebuf, de_name, de_namelen); + dbg_namebuf[de_namelen] ='\0' ; + +debugln ("found dirent %s de_len %u d_type %d" , dbg_namebuf, + de_namelen, d_type); +#endif +} +static int erofs_fill_dentries (struct dir_context *ctx,void *dentry_blk,unsigned int *ofs,unsigned int nameoff,unsigned int maxsize)
@@ -33,14 +48,10 @@ static int erofs_fill_dentries(struct dir_context *ctx, de = dentry_blk + *ofs;while (de < end) {const char *de_name; -int de_namelen; +unsigned int de_namelen;unsigned char d_type; -#ifdef CONFIG_EROFS_FS_DEBUG -unsigned int dbg_namelen; -unsigned char dbg_namebuf[EROFS_NAME_LEN ]; -#endif -if (unlikely (de->file_type <EROFS_FT_MAX )) +if (de->file_type <EROFS_FT_MAX ) d_type = erofs_filetype_table[de->file_type];else d_type =DT_UNKNOWN ;
@@ -48,26 +59,20 @@ static int erofs_fill_dentries(struct dir_context *ctx, nameoff =le16_to_cpu (de->nameoff); de_name = (char *)dentry_blk + nameoff; - de_namelen =unlikely (de +1 >= end) ? -/* last directory entry */ -strnlen (de_name, maxsize - nameoff) : -le16_to_cpu (de[1 ].nameoff) - nameoff; +/* the last dirent in the block? */ +if (de +1 >= end) + de_namelen =strnlen (de_name, maxsize - nameoff); +else + de_namelen =le16_to_cpu (de[1 ].nameoff) - nameoff;/* a corrupted entry is found */ -if (unlikely (de_namelen <0 )) { +if (unlikely (nameoff + de_namelen > maxsize || + de_namelen >EROFS_NAME_LEN )) {DBG_BUGON (1 );return -EIO ; } -#ifdef CONFIG_EROFS_FS_DEBUG - dbg_namelen =min (EROFS_NAME_LEN -1 , de_namelen); -memcpy (dbg_namebuf, de_name, dbg_namelen); - dbg_namebuf[dbg_namelen] ='\0' ; - -debugln ("%s, found de_name %s de_len %d d_type %d" , __func__, - dbg_namebuf, de_namelen, d_type); -#endif - +debug_one_dentry (d_type, de_name, de_namelen);if (!dir_emit (ctx, de_name, de_namelen,le64_to_cpu (de->nid), d_type))/* stopped by some reason */