diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/staging/erofs/dir.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/drivers/staging/erofs/dir.c b/drivers/staging/erofs/dir.c index 829f7b12e0dc..9bbc68729c11 100644 --- a/drivers/staging/erofs/dir.c +++ b/drivers/staging/erofs/dir.c | |||
| @@ -23,6 +23,21 @@ static const unsigned char erofs_filetype_table[EROFS_FT_MAX] = { | |||
| 23 | [EROFS_FT_SYMLINK] = DT_LNK, | 23 | [EROFS_FT_SYMLINK] = DT_LNK, |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | static void debug_one_dentry(unsigned char d_type, const char *de_name, | ||
| 27 | unsigned int de_namelen) | ||
| 28 | { | ||
| 29 | #ifdef CONFIG_EROFS_FS_DEBUG | ||
| 30 | /* since the on-disk name could not have the trailing '\0' */ | ||
| 31 | unsigned char dbg_namebuf[EROFS_NAME_LEN + 1]; | ||
| 32 | |||
| 33 | memcpy(dbg_namebuf, de_name, de_namelen); | ||
| 34 | dbg_namebuf[de_namelen] = '\0'; | ||
| 35 | |||
| 36 | debugln("found dirent %s de_len %u d_type %d", dbg_namebuf, | ||
| 37 | de_namelen, d_type); | ||
| 38 | #endif | ||
| 39 | } | ||
| 40 | |||
| 26 | static int erofs_fill_dentries(struct dir_context *ctx, | 41 | static int erofs_fill_dentries(struct dir_context *ctx, |
| 27 | void *dentry_blk, unsigned int *ofs, | 42 | void *dentry_blk, unsigned int *ofs, |
| 28 | unsigned int nameoff, unsigned int maxsize) | 43 | unsigned int nameoff, unsigned int maxsize) |
| @@ -33,14 +48,10 @@ static int erofs_fill_dentries(struct dir_context *ctx, | |||
| 33 | de = dentry_blk + *ofs; | 48 | de = dentry_blk + *ofs; |
| 34 | while (de < end) { | 49 | while (de < end) { |
| 35 | const char *de_name; | 50 | const char *de_name; |
| 36 | int de_namelen; | 51 | unsigned int de_namelen; |
| 37 | unsigned char d_type; | 52 | unsigned char d_type; |
| 38 | #ifdef CONFIG_EROFS_FS_DEBUG | ||
| 39 | unsigned int dbg_namelen; | ||
| 40 | unsigned char dbg_namebuf[EROFS_NAME_LEN]; | ||
| 41 | #endif | ||
| 42 | 53 | ||
| 43 | if (unlikely(de->file_type < EROFS_FT_MAX)) | 54 | if (de->file_type < EROFS_FT_MAX) |
| 44 | d_type = erofs_filetype_table[de->file_type]; | 55 | d_type = erofs_filetype_table[de->file_type]; |
| 45 | else | 56 | else |
| 46 | d_type = DT_UNKNOWN; | 57 | d_type = DT_UNKNOWN; |
| @@ -48,26 +59,20 @@ static int erofs_fill_dentries(struct dir_context *ctx, | |||
| 48 | nameoff = le16_to_cpu(de->nameoff); | 59 | nameoff = le16_to_cpu(de->nameoff); |
| 49 | de_name = (char *)dentry_blk + nameoff; | 60 | de_name = (char *)dentry_blk + nameoff; |
| 50 | 61 | ||
| 51 | de_namelen = unlikely(de + 1 >= end) ? | 62 | /* the last dirent in the block? */ |
| 52 | /* last directory entry */ | 63 | if (de + 1 >= end) |
| 53 | strnlen(de_name, maxsize - nameoff) : | 64 | de_namelen = strnlen(de_name, maxsize - nameoff); |
| 54 | le16_to_cpu(de[1].nameoff) - nameoff; | 65 | else |
| 66 | de_namelen = le16_to_cpu(de[1].nameoff) - nameoff; | ||
| 55 | 67 | ||
| 56 | /* a corrupted entry is found */ | 68 | /* a corrupted entry is found */ |
| 57 | if (unlikely(de_namelen < 0)) { | 69 | if (unlikely(nameoff + de_namelen > maxsize || |
| 70 | de_namelen > EROFS_NAME_LEN)) { | ||
| 58 | DBG_BUGON(1); | 71 | DBG_BUGON(1); |
| 59 | return -EIO; | 72 | return -EIO; |
| 60 | } | 73 | } |
| 61 | 74 | ||
| 62 | #ifdef CONFIG_EROFS_FS_DEBUG | 75 | debug_one_dentry(d_type, de_name, de_namelen); |
| 63 | dbg_namelen = min(EROFS_NAME_LEN - 1, de_namelen); | ||
| 64 | memcpy(dbg_namebuf, de_name, dbg_namelen); | ||
| 65 | dbg_namebuf[dbg_namelen] = '\0'; | ||
| 66 | |||
| 67 | debugln("%s, found de_name %s de_len %d d_type %d", __func__, | ||
| 68 | dbg_namebuf, de_namelen, d_type); | ||
| 69 | #endif | ||
| 70 | |||
| 71 | if (!dir_emit(ctx, de_name, de_namelen, | 76 | if (!dir_emit(ctx, de_name, de_namelen, |
| 72 | le64_to_cpu(de->nid), d_type)) | 77 | le64_to_cpu(de->nid), d_type)) |
| 73 | /* stopped by some reason */ | 78 | /* stopped by some reason */ |
