Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: correct upper bounds check for mtd_*() APIs

When checking the upper boundary (i.e., whether an address is higher
than the maximum size of the MTD), we should be doing an inclusive check
(greater or equal). For instance, an address of 16MB (0x1000000) on a
16MB device is invalid.

The strengthening of this bounds check is redundant for those which
already have a address+length check and ensure that the length is
non-zero, but let's just fix them all, for completeness.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>

+13 -13
+13 -13
drivers/mtd/mtdcore.c
··· 778 778 */ 779 779 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) 780 780 { 781 - if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr) 781 + if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr) 782 782 return -EINVAL; 783 783 if (!(mtd->flags & MTD_WRITEABLE)) 784 784 return -EROFS; ··· 804 804 *phys = 0; 805 805 if (!mtd->_point) 806 806 return -EOPNOTSUPP; 807 - if (from < 0 || from > mtd->size || len > mtd->size - from) 807 + if (from < 0 || from >= mtd->size || len > mtd->size - from) 808 808 return -EINVAL; 809 809 if (!len) 810 810 return 0; ··· 817 817 { 818 818 if (!mtd->_point) 819 819 return -EOPNOTSUPP; 820 - if (from < 0 || from > mtd->size || len > mtd->size - from) 820 + if (from < 0 || from >= mtd->size || len > mtd->size - from) 821 821 return -EINVAL; 822 822 if (!len) 823 823 return 0; ··· 835 835 { 836 836 if (!mtd->_get_unmapped_area) 837 837 return -EOPNOTSUPP; 838 - if (offset > mtd->size || len > mtd->size - offset) 838 + if (offset >= mtd->size || len > mtd->size - offset) 839 839 return -EINVAL; 840 840 return mtd->_get_unmapped_area(mtd, len, offset, flags); 841 841 } ··· 846 846 { 847 847 int ret_code; 848 848 *retlen = 0; 849 - if (from < 0 || from > mtd->size || len > mtd->size - from) 849 + if (from < 0 || from >= mtd->size || len > mtd->size - from) 850 850 return -EINVAL; 851 851 if (!len) 852 852 return 0; ··· 869 869 const u_char *buf) 870 870 { 871 871 *retlen = 0; 872 - if (to < 0 || to > mtd->size || len > mtd->size - to) 872 + if (to < 0 || to >= mtd->size || len > mtd->size - to) 873 873 return -EINVAL; 874 874 if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE)) 875 875 return -EROFS; ··· 892 892 *retlen = 0; 893 893 if (!mtd->_panic_write) 894 894 return -EOPNOTSUPP; 895 - if (to < 0 || to > mtd->size || len > mtd->size - to) 895 + if (to < 0 || to >= mtd->size || len > mtd->size - to) 896 896 return -EINVAL; 897 897 if (!(mtd->flags & MTD_WRITEABLE)) 898 898 return -EROFS; ··· 1011 1011 { 1012 1012 if (!mtd->_lock) 1013 1013 return -EOPNOTSUPP; 1014 - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) 1014 + if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) 1015 1015 return -EINVAL; 1016 1016 if (!len) 1017 1017 return 0; ··· 1023 1023 { 1024 1024 if (!mtd->_unlock) 1025 1025 return -EOPNOTSUPP; 1026 - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) 1026 + if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) 1027 1027 return -EINVAL; 1028 1028 if (!len) 1029 1029 return 0; ··· 1035 1035 { 1036 1036 if (!mtd->_is_locked) 1037 1037 return -EOPNOTSUPP; 1038 - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) 1038 + if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) 1039 1039 return -EINVAL; 1040 1040 if (!len) 1041 1041 return 0; ··· 1045 1045 1046 1046 int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs) 1047 1047 { 1048 - if (ofs < 0 || ofs > mtd->size) 1048 + if (ofs < 0 || ofs >= mtd->size) 1049 1049 return -EINVAL; 1050 1050 if (!mtd->_block_isreserved) 1051 1051 return 0; ··· 1055 1055 1056 1056 int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) 1057 1057 { 1058 - if (ofs < 0 || ofs > mtd->size) 1058 + if (ofs < 0 || ofs >= mtd->size) 1059 1059 return -EINVAL; 1060 1060 if (!mtd->_block_isbad) 1061 1061 return 0; ··· 1067 1067 { 1068 1068 if (!mtd->_block_markbad) 1069 1069 return -EOPNOTSUPP; 1070 - if (ofs < 0 || ofs > mtd->size) 1070 + if (ofs < 0 || ofs >= mtd->size) 1071 1071 return -EINVAL; 1072 1072 if (!(mtd->flags & MTD_WRITEABLE)) 1073 1073 return -EROFS;