diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/btrfs.c | 15 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/ext4/ext4_common.c | 2 | ||||
-rw-r--r-- | fs/ext4/ext4fs.c | 2 | ||||
-rw-r--r-- | fs/fat/fat.c | 114 | ||||
-rw-r--r-- | fs/fs.c | 6 | ||||
-rw-r--r-- | fs/squashfs/sqfs_decompressor.c | 23 | ||||
-rw-r--r-- | fs/squashfs/sqfs_decompressor.h | 35 | ||||
-rw-r--r-- | fs/squashfs/sqfs_filesystem.h | 2 | ||||
-rw-r--r-- | fs/squashfs/sqfs_utils.h | 21 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 1 | ||||
-rw-r--r-- | fs/yaffs2/ydirectenv.h | 1 |
12 files changed, 121 insertions, 102 deletions
diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c index 4cdbbbe..1149a3b 100644 --- a/fs/btrfs/btrfs.c +++ b/fs/btrfs/btrfs.c @@ -228,7 +228,7 @@ int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len, { struct btrfs_fs_info *fs_info = current_fs_info; struct btrfs_root *root; - loff_t real_size = 0; + loff_t real_size; u64 ino; u8 type; int ret; @@ -246,16 +246,13 @@ int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len, return -EINVAL; } - if (!len) { - ret = btrfs_size(file, &real_size); - if (ret < 0) { - error("Failed to get inode size: %s", file); - return ret; - } - len = real_size; + ret = btrfs_size(file, &real_size); + if (ret < 0) { + error("Failed to get inode size: %s", file); + return ret; } - if (len > real_size - offset) + if (!len || len > real_size - offset) len = real_size - offset; ret = btrfs_file_read(root, ino, offset, len, buf); diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index ffd095f..5943955 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -9,7 +9,6 @@ #ifndef __BTRFS_CTREE_H__ #define __BTRFS_CTREE_H__ -#include <common.h> #include <compiler.h> #include <linux/rbtree.h> #include <linux/bug.h> diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index f50de7c..ea9b922 100644 --- a/fs/ext4/ext4_common.c +++ b/fs/ext4/ext4_common.c @@ -2368,7 +2368,7 @@ fail: return -1; } -int ext4fs_mount(unsigned part_length) +int ext4fs_mount(void) { struct ext2_data *data; int status; diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c index 4c89152..3b12ec5 100644 --- a/fs/ext4/ext4fs.c +++ b/fs/ext4/ext4fs.c @@ -233,7 +233,7 @@ int ext4fs_probe(struct blk_desc *fs_dev_desc, { ext4fs_set_blk_dev(fs_dev_desc, fs_partition); - if (!ext4fs_mount(fs_partition->size)) { + if (!ext4fs_mount()) { ext4fs_close(); return -1; } diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 8ff1fd0..14e53cf 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -18,12 +18,17 @@ #include <fs.h> #include <log.h> #include <asm/byteorder.h> +#include <asm/unaligned.h> #include <part.h> #include <malloc.h> #include <memalign.h> #include <asm/cache.h> #include <linux/compiler.h> #include <linux/ctype.h> +#include <linux/log2.h> + +/* maximum number of clusters for FAT12 */ +#define MAX_FAT12 0xFF4 /* * Convert a string to lowercase. Converts at most 'len' characters, @@ -484,6 +489,73 @@ static __u8 mkcksum(struct nameext *nameext) } /* + * Determine if the FAT type is FAT12 or FAT16 + * + * Based on fat_fill_super() from the Linux kernel's fs/fat/inode.c + */ +static int determine_legacy_fat_bits(const boot_sector *bs) +{ + u16 fat_start = bs->reserved; + u32 dir_start = fat_start + bs->fats * bs->fat_length; + u32 rootdir_sectors = get_unaligned_le16(bs->dir_entries) * + sizeof(dir_entry) / + get_unaligned_le16(bs->sector_size); + u32 data_start = dir_start + rootdir_sectors; + u16 sectors = get_unaligned_le16(bs->sectors); + u32 total_sectors = sectors ? sectors : bs->total_sect; + u32 total_clusters = (total_sectors - data_start) / + bs->cluster_size; + + return (total_clusters > MAX_FAT12) ? 16 : 12; +} + +/* + * Determines if the boot sector's media field is valid + * + * Based on fat_valid_media() from Linux kernel's include/linux/msdos_fs.h + */ +static int fat_valid_media(u8 media) +{ + return media >= 0xf8 || media == 0xf0; +} + +/* + * Determines if the given boot sector is valid + * + * Based on fat_read_bpb() from the Linux kernel's fs/fat/inode.c + */ +static int is_bootsector_valid(const boot_sector *bs) +{ + u16 sector_size = get_unaligned_le16(bs->sector_size); + u16 dir_per_block = sector_size / sizeof(dir_entry); + + if (!bs->reserved) + return 0; + + if (!bs->fats) + return 0; + + if (!fat_valid_media(bs->media)) + return 0; + + if (!is_power_of_2(sector_size) || + sector_size < 512 || + sector_size > 4096) + return 0; + + if (!is_power_of_2(bs->cluster_size)) + return 0; + + if (!bs->fat_length && !bs->fat32_length) + return 0; + + if (get_unaligned_le16(bs->dir_entries) & (dir_per_block - 1)) + return 0; + + return 1; +} + +/* * Read boot sector and volume info from a FAT filesystem */ static int @@ -506,7 +578,8 @@ read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize) if (disk_read(0, 1, block) < 0) { debug("Error: reading block\n"); - goto fail; + ret = -1; + goto out_free; } memcpy(bs, block, sizeof(boot_sector)); @@ -516,8 +589,14 @@ read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize) bs->heads = FAT2CPU16(bs->heads); bs->total_sect = FAT2CPU32(bs->total_sect); + if (!is_bootsector_valid(bs)) { + debug("Error: bootsector is invalid\n"); + ret = -1; + goto out_free; + } + /* FAT32 entries */ - if (bs->fat_length == 0) { + if (!bs->fat_length && bs->fat32_length) { /* Assume FAT32 */ bs->fat32_length = FAT2CPU32(bs->fat32_length); bs->flags = FAT2CPU16(bs->flags); @@ -528,28 +607,11 @@ read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize) *fatsize = 32; } else { vistart = (volume_info *)&(bs->fat32_length); - *fatsize = 0; + *fatsize = determine_legacy_fat_bits(bs); } memcpy(volinfo, vistart, sizeof(volume_info)); - if (*fatsize == 32) { - if (strncmp(FAT32_SIGN, vistart->fs_type, SIGNLEN) == 0) - goto exit; - } else { - if (strncmp(FAT12_SIGN, vistart->fs_type, SIGNLEN) == 0) { - *fatsize = 12; - goto exit; - } - if (strncmp(FAT16_SIGN, vistart->fs_type, SIGNLEN) == 0) { - *fatsize = 16; - goto exit; - } - } - - debug("Error: broken fs_type sign\n"); -fail: - ret = -1; -exit: +out_free: free(block); return ret; } @@ -571,7 +633,7 @@ static int get_fs_info(fsdata *mydata) mydata->total_sect = bs.total_sect; } else { mydata->fatlength = bs.fat_length; - mydata->total_sect = (bs.sectors[1] << 8) + bs.sectors[0]; + mydata->total_sect = get_unaligned_le16(bs.sectors); if (!mydata->total_sect) mydata->total_sect = bs.total_sect; } @@ -583,7 +645,7 @@ static int get_fs_info(fsdata *mydata) mydata->rootdir_sect = mydata->fat_sect + mydata->fatlength * bs.fats; - mydata->sect_size = (bs.sector_size[1] << 8) + bs.sector_size[0]; + mydata->sect_size = get_unaligned_le16(bs.sector_size); mydata->clust_size = bs.cluster_size; if (mydata->sect_size != cur_part_info.blksz) { log_err("FAT sector size mismatch (fs=%u, dev=%lu)\n", @@ -607,8 +669,7 @@ static int get_fs_info(fsdata *mydata) (mydata->clust_size * 2); mydata->root_cluster = bs.root_cluster; } else { - mydata->rootdir_size = ((bs.dir_entries[1] * (int)256 + - bs.dir_entries[0]) * + mydata->rootdir_size = (get_unaligned_le16(bs.dir_entries) * sizeof(dir_entry)) / mydata->sect_size; mydata->data_begin = mydata->rootdir_sect + @@ -1157,9 +1218,8 @@ int file_fat_detectfs(void) memcpy(vol_label, volinfo.volume_label, 11); vol_label[11] = '\0'; - volinfo.fs_type[5] = '\0'; - printf("Filesystem: %s \"%s\"\n", volinfo.fs_type, vol_label); + printf("Filesystem: FAT%d \"%s\"\n", fatsize, vol_label); return 0; } @@ -256,7 +256,7 @@ static struct fstype_info fstypes[] = { .ln = fs_ln_unsupported, }, #endif -#ifdef CONFIG_SEMIHOSTING +#if CONFIG_IS_ENABLED(SEMIHOSTING) { .fstype = FS_TYPE_SEMIHOSTING, .name = "semihosting", @@ -749,7 +749,7 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], if (argc > 7) return CMD_RET_USAGE; - if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype)) { + if (fs_set_blk_dev(argv[1], cmd_arg2(argc, argv), fstype)) { log_err("Can't set block device\n"); return 1; } @@ -818,7 +818,7 @@ int do_ls(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], if (argc > 4) return CMD_RET_USAGE; - if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype)) + if (fs_set_blk_dev(argv[1], cmd_arg2(argc, argv), fstype)) return 1; if (fs_ls(argc >= 4 ? argv[3] : "/")) diff --git a/fs/squashfs/sqfs_decompressor.c b/fs/squashfs/sqfs_decompressor.c index 6b3e01c..cfd1153 100644 --- a/fs/squashfs/sqfs_decompressor.c +++ b/fs/squashfs/sqfs_decompressor.c @@ -18,6 +18,10 @@ #include <u-boot/zlib.h> #endif +#if IS_ENABLED(CONFIG_LZ4) +#include <u-boot/lz4.h> +#endif + #if IS_ENABLED(CONFIG_ZSTD) #include <linux/zstd.h> #endif @@ -38,6 +42,10 @@ int sqfs_decompressor_init(struct squashfs_ctxt *ctxt) case SQFS_COMP_ZLIB: break; #endif +#if IS_ENABLED(CONFIG_LZ4) + case SQFS_COMP_LZ4: + break; +#endif #if IS_ENABLED(CONFIG_ZSTD) case SQFS_COMP_ZSTD: ctxt->zstd_workspace = malloc(zstd_dctx_workspace_bound()); @@ -66,6 +74,10 @@ void sqfs_decompressor_cleanup(struct squashfs_ctxt *ctxt) case SQFS_COMP_ZLIB: break; #endif +#if IS_ENABLED(CONFIG_LZ4) + case SQFS_COMP_LZ4: + break; +#endif #if IS_ENABLED(CONFIG_ZSTD) case SQFS_COMP_ZSTD: free(ctxt->zstd_workspace); @@ -139,6 +151,17 @@ int sqfs_decompress(struct squashfs_ctxt *ctxt, void *dest, break; #endif +#if IS_ENABLED(CONFIG_LZ4) + case SQFS_COMP_LZ4: + ret = LZ4_decompress_safe(source, dest, src_len, *dest_len); + if (ret < 0) { + printf("LZ4 decompression failed.\n"); + return -EINVAL; + } + + ret = 0; + break; +#endif #if IS_ENABLED(CONFIG_ZSTD) case SQFS_COMP_ZSTD: ret = sqfs_zstd_decompress(ctxt, dest, *dest_len, source, src_len); diff --git a/fs/squashfs/sqfs_decompressor.h b/fs/squashfs/sqfs_decompressor.h index 892cfb6..c48b74f 100644 --- a/fs/squashfs/sqfs_decompressor.h +++ b/fs/squashfs/sqfs_decompressor.h @@ -18,41 +18,6 @@ #define SQFS_COMP_LZ4 5 #define SQFS_COMP_ZSTD 6 -/* LZMA does not support any compression options */ - -struct squashfs_gzip_opts { - u32 compression_level; - u16 window_size; - u16 strategies; -}; - -struct squashfs_xz_opts { - u32 dictionary_size; - u32 executable_filters; -}; - -struct squashfs_lz4_opts { - u32 version; - u32 flags; -}; - -struct squashfs_zstd_opts { - u32 compression_level; -}; - -struct squashfs_lzo_opts { - u32 algorithm; - u32 level; -}; - -union squashfs_compression_opts { - struct squashfs_gzip_opts *gzip; - struct squashfs_xz_opts *xz; - struct squashfs_lz4_opts *lz4; - struct squashfs_zstd_opts *zstd; - struct squashfs_lzo_opts *lzo; -}; - int sqfs_decompress(struct squashfs_ctxt *ctxt, void *dest, unsigned long *dest_len, void *source, u32 src_len); int sqfs_decompressor_init(struct squashfs_ctxt *ctxt); diff --git a/fs/squashfs/sqfs_filesystem.h b/fs/squashfs/sqfs_filesystem.h index 5440b6c..be56498 100644 --- a/fs/squashfs/sqfs_filesystem.h +++ b/fs/squashfs/sqfs_filesystem.h @@ -13,7 +13,6 @@ #include <part.h> #include <stdint.h> -#define SQFS_UNCOMPRESSED_DATA 0x0002 #define SQFS_MAGIC_NUMBER 0x73717368 /* The three first members of squashfs_dir_index make a total of 12 bytes */ #define SQFS_DIR_INDEX_BASE_LENGTH 12 @@ -23,7 +22,6 @@ #define SQFS_MAX_ENTRIES 512 /* Metadata blocks start by a 2-byte length header */ #define SQFS_HEADER_SIZE 2 -#define SQFS_LREG_INODE_MIN_SIZE 56 #define SQFS_DIR_HEADER_SIZE 12 #define SQFS_MISC_ENTRY_TYPE -1 #define SQFS_EMPTY_FILE_SIZE 3 diff --git a/fs/squashfs/sqfs_utils.h b/fs/squashfs/sqfs_utils.h index 1260abe..41f13e8 100644 --- a/fs/squashfs/sqfs_utils.h +++ b/fs/squashfs/sqfs_utils.h @@ -15,11 +15,8 @@ #define SQFS_FRAGMENT_INDEX_OFFSET(A) ((A) % SQFS_MAX_ENTRIES) #define SQFS_FRAGMENT_INDEX(A) ((A) / SQFS_MAX_ENTRIES) #define SQFS_BLOCK_SIZE(A) ((A) & GENMASK(23, 0)) -#define SQFS_CHECK_FLAG(flag, bit) (((flag) >> (bit)) & 1) /* Useful for both fragment and data blocks */ #define SQFS_COMPRESSED_BLOCK(A) (!((A) & BIT(24))) -/* SQFS_COMPRESSED_DATA strictly used with super block's 'flags' member */ -#define SQFS_COMPRESSED_DATA(A) (!((A) & 0x0002)) #define SQFS_IS_FRAGMENTED(A) ((A) != 0xFFFFFFFF) /* * These two macros work as getters for a metada block header, retrieving the @@ -28,22 +25,4 @@ #define SQFS_COMPRESSED_METADATA(A) (!((A) & BIT(15))) #define SQFS_METADATA_SIZE(A) ((A) & GENMASK(14, 0)) -struct squashfs_super_block_flags { - /* check: unused - * uncompressed_ids: not supported - */ - bool uncompressed_inodes; - bool uncompressed_data; - bool check; - bool uncompressed_frags; - bool no_frags; - bool always_frags; - bool duplicates; - bool exportable; - bool uncompressed_xattrs; - bool no_xattrs; - bool compressor_options; - bool uncompressed_ids; -}; - #endif /* SQFS_UTILS_H */ diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 67b13c8..b4e761c 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -68,7 +68,6 @@ struct page { void iput(struct inode *inode); /* linux/include/time.h */ -#define NSEC_PER_SEC 1000000000L #define get_seconds() 0 #define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 }) diff --git a/fs/yaffs2/ydirectenv.h b/fs/yaffs2/ydirectenv.h index d274f22..790f851 100644 --- a/fs/yaffs2/ydirectenv.h +++ b/fs/yaffs2/ydirectenv.h @@ -20,7 +20,6 @@ #ifndef __YDIRECTENV_H__ #define __YDIRECTENV_H__ -#include <common.h> #include <malloc.h> #include <linux/compat.h> |