aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/io.c11
-rw-r--r--fs/ubifs/scan.c2
-rw-r--r--fs/ubifs/super.c34
-rw-r--r--fs/ubifs/tnc.c6
-rw-r--r--fs/ubifs/ubifs.h11
5 files changed, 55 insertions, 9 deletions
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 054363f2b207..40e2790b62ce 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -74,6 +74,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
74 * @lnum: logical eraseblock number 74 * @lnum: logical eraseblock number
75 * @offs: offset within the logical eraseblock 75 * @offs: offset within the logical eraseblock
76 * @quiet: print no messages 76 * @quiet: print no messages
77 * @chk_crc: indicates whether to always check the CRC
77 * 78 *
78 * This function checks node magic number and CRC checksum. This function also 79 * This function checks node magic number and CRC checksum. This function also
79 * validates node length to prevent UBIFS from becoming crazy when an attacker 80 * validates node length to prevent UBIFS from becoming crazy when an attacker
@@ -85,7 +86,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
85 * or magic. 86 * or magic.
86 */ 87 */
87int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, 88int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
88 int offs, int quiet) 89 int offs, int quiet, int chk_crc)
89{ 90{
90 int err = -EINVAL, type, node_len; 91 int err = -EINVAL, type, node_len;
91 uint32_t crc, node_crc, magic; 92 uint32_t crc, node_crc, magic;
@@ -121,6 +122,10 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
121 node_len > c->ranges[type].max_len) 122 node_len > c->ranges[type].max_len)
122 goto out_len; 123 goto out_len;
123 124
125 if (!chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc)
126 if (c->no_chk_data_crc)
127 return 0;
128
124 crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); 129 crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);
125 node_crc = le32_to_cpu(ch->crc); 130 node_crc = le32_to_cpu(ch->crc);
126 if (crc != node_crc) { 131 if (crc != node_crc) {
@@ -722,7 +727,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
722 goto out; 727 goto out;
723 } 728 }
724 729
725 err = ubifs_check_node(c, buf, lnum, offs, 0); 730 err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
726 if (err) { 731 if (err) {
727 ubifs_err("expected node type %d", type); 732 ubifs_err("expected node type %d", type);
728 return err; 733 return err;
@@ -781,7 +786,7 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
781 goto out; 786 goto out;
782 } 787 }
783 788
784 err = ubifs_check_node(c, buf, lnum, offs, 0); 789 err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
785 if (err) { 790 if (err) {
786 ubifs_err("expected node type %d", type); 791 ubifs_err("expected node type %d", type);
787 return err; 792 return err;
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c
index acf5c5fffc60..0ed82479b44b 100644
--- a/fs/ubifs/scan.c
+++ b/fs/ubifs/scan.c
@@ -87,7 +87,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
87 87
88 dbg_scan("scanning %s", dbg_ntype(ch->node_type)); 88 dbg_scan("scanning %s", dbg_ntype(ch->node_type));
89 89
90 if (ubifs_check_node(c, buf, lnum, offs, quiet)) 90 if (ubifs_check_node(c, buf, lnum, offs, quiet, 1))
91 return SCANNED_A_CORRUPT_NODE; 91 return SCANNED_A_CORRUPT_NODE;
92 92
93 if (ch->node_type == UBIFS_PAD_NODE) { 93 if (ch->node_type == UBIFS_PAD_NODE) {
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index b1c57e8ee855..cf078b5cc88c 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -406,6 +406,11 @@ static int ubifs_show_options(struct seq_file *s, struct vfsmount *mnt)
406 else if (c->mount_opts.bulk_read == 1) 406 else if (c->mount_opts.bulk_read == 1)
407 seq_printf(s, ",no_bulk_read"); 407 seq_printf(s, ",no_bulk_read");
408 408
409 if (c->mount_opts.chk_data_crc == 2)
410 seq_printf(s, ",chk_data_crc");
411 else if (c->mount_opts.chk_data_crc == 1)
412 seq_printf(s, ",no_chk_data_crc");
413
409 return 0; 414 return 0;
410} 415}
411 416
@@ -859,6 +864,8 @@ static int check_volume_empty(struct ubifs_info *c)
859 * Opt_norm_unmount: run a journal commit before un-mounting 864 * Opt_norm_unmount: run a journal commit before un-mounting
860 * Opt_bulk_read: enable bulk-reads 865 * Opt_bulk_read: enable bulk-reads
861 * Opt_no_bulk_read: disable bulk-reads 866 * Opt_no_bulk_read: disable bulk-reads
867 * Opt_chk_data_crc: check CRCs when reading data nodes
868 * Opt_no_chk_data_crc: do not check CRCs when reading data nodes
862 * Opt_err: just end of array marker 869 * Opt_err: just end of array marker
863 */ 870 */
864enum { 871enum {
@@ -866,6 +873,8 @@ enum {
866 Opt_norm_unmount, 873 Opt_norm_unmount,
867 Opt_bulk_read, 874 Opt_bulk_read,
868 Opt_no_bulk_read, 875 Opt_no_bulk_read,
876 Opt_chk_data_crc,
877 Opt_no_chk_data_crc,
869 Opt_err, 878 Opt_err,
870}; 879};
871 880
@@ -874,6 +883,8 @@ static match_table_t tokens = {
874 {Opt_norm_unmount, "norm_unmount"}, 883 {Opt_norm_unmount, "norm_unmount"},
875 {Opt_bulk_read, "bulk_read"}, 884 {Opt_bulk_read, "bulk_read"},
876 {Opt_no_bulk_read, "no_bulk_read"}, 885 {Opt_no_bulk_read, "no_bulk_read"},
886 {Opt_chk_data_crc, "chk_data_crc"},
887 {Opt_no_chk_data_crc, "no_chk_data_crc"},
877 {Opt_err, NULL}, 888 {Opt_err, NULL},
878}; 889};
879 890
@@ -919,6 +930,14 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
919 c->mount_opts.bulk_read = 1; 930 c->mount_opts.bulk_read = 1;
920 c->bulk_read = 0; 931 c->bulk_read = 0;
921 break; 932 break;
933 case Opt_chk_data_crc:
934 c->mount_opts.chk_data_crc = 2;
935 c->no_chk_data_crc = 0;
936 break;
937 case Opt_no_chk_data_crc:
938 c->mount_opts.chk_data_crc = 1;
939 c->no_chk_data_crc = 1;
940 break;
922 default: 941 default:
923 ubifs_err("unrecognized mount option \"%s\" " 942 ubifs_err("unrecognized mount option \"%s\" "
924 "or missing value", p); 943 "or missing value", p);
@@ -1027,6 +1046,8 @@ static int mount_ubifs(struct ubifs_info *c)
1027 goto out_free; 1046 goto out_free;
1028 } 1047 }
1029 1048
1049 c->always_chk_crc = 1;
1050
1030 err = ubifs_read_superblock(c); 1051 err = ubifs_read_superblock(c);
1031 if (err) 1052 if (err)
1032 goto out_free; 1053 goto out_free;
@@ -1168,6 +1189,8 @@ static int mount_ubifs(struct ubifs_info *c)
1168 if (err) 1189 if (err)
1169 goto out_infos; 1190 goto out_infos;
1170 1191
1192 c->always_chk_crc = 0;
1193
1171 ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"", 1194 ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"",
1172 c->vi.ubi_num, c->vi.vol_id, c->vi.name); 1195 c->vi.ubi_num, c->vi.vol_id, c->vi.name);
1173 if (mounted_read_only) 1196 if (mounted_read_only)
@@ -1313,6 +1336,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
1313 1336
1314 mutex_lock(&c->umount_mutex); 1337 mutex_lock(&c->umount_mutex);
1315 c->remounting_rw = 1; 1338 c->remounting_rw = 1;
1339 c->always_chk_crc = 1;
1316 1340
1317 /* Check for enough free space */ 1341 /* Check for enough free space */
1318 if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) { 1342 if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) {
@@ -1381,13 +1405,15 @@ static int ubifs_remount_rw(struct ubifs_info *c)
1381 c->bgt = NULL; 1405 c->bgt = NULL;
1382 ubifs_err("cannot spawn \"%s\", error %d", 1406 ubifs_err("cannot spawn \"%s\", error %d",
1383 c->bgt_name, err); 1407 c->bgt_name, err);
1384 return err; 1408 goto out;
1385 } 1409 }
1386 wake_up_process(c->bgt); 1410 wake_up_process(c->bgt);
1387 1411
1388 c->orph_buf = vmalloc(c->leb_size); 1412 c->orph_buf = vmalloc(c->leb_size);
1389 if (!c->orph_buf) 1413 if (!c->orph_buf) {
1390 return -ENOMEM; 1414 err = -ENOMEM;
1415 goto out;
1416 }
1391 1417
1392 /* Check for enough log space */ 1418 /* Check for enough log space */
1393 lnum = c->lhead_lnum + 1; 1419 lnum = c->lhead_lnum + 1;
@@ -1414,6 +1440,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
1414 dbg_gen("re-mounted read-write"); 1440 dbg_gen("re-mounted read-write");
1415 c->vfs_sb->s_flags &= ~MS_RDONLY; 1441 c->vfs_sb->s_flags &= ~MS_RDONLY;
1416 c->remounting_rw = 0; 1442 c->remounting_rw = 0;
1443 c->always_chk_crc = 0;
1417 mutex_unlock(&c->umount_mutex); 1444 mutex_unlock(&c->umount_mutex);
1418 return 0; 1445 return 0;
1419 1446
@@ -1429,6 +1456,7 @@ out:
1429 c->ileb_buf = NULL; 1456 c->ileb_buf = NULL;
1430 ubifs_lpt_free(c, 1); 1457 ubifs_lpt_free(c, 1);
1431 c->remounting_rw = 0; 1458 c->remounting_rw = 0;
1459 c->always_chk_crc = 0;
1432 mutex_unlock(&c->umount_mutex); 1460 mutex_unlock(&c->umount_mutex);
1433 return err; 1461 return err;
1434} 1462}
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index d279012d8dd5..66dc57100bdf 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -470,6 +470,10 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type,
470 if (node_len != len) 470 if (node_len != len)
471 return 0; 471 return 0;
472 472
473 if (type == UBIFS_DATA_NODE && !c->always_chk_crc)
474 if (c->no_chk_data_crc)
475 return 0;
476
473 crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); 477 crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);
474 node_crc = le32_to_cpu(ch->crc); 478 node_crc = le32_to_cpu(ch->crc);
475 if (crc != node_crc) 479 if (crc != node_crc)
@@ -1687,7 +1691,7 @@ static int validate_data_node(struct ubifs_info *c, void *buf,
1687 goto out_err; 1691 goto out_err;
1688 } 1692 }
1689 1693
1690 err = ubifs_check_node(c, buf, zbr->lnum, zbr->offs, 0); 1694 err = ubifs_check_node(c, buf, zbr->lnum, zbr->offs, 0, 0);
1691 if (err) { 1695 if (err) {
1692 ubifs_err("expected node type %d", UBIFS_DATA_NODE); 1696 ubifs_err("expected node type %d", UBIFS_DATA_NODE);
1693 goto out; 1697 goto out;
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 8513239ea8a0..d6ae3f7b2b05 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -894,10 +894,12 @@ struct ubifs_orphan {
894 * struct ubifs_mount_opts - UBIFS-specific mount options information. 894 * struct ubifs_mount_opts - UBIFS-specific mount options information.
895 * @unmount_mode: selected unmount mode (%0 default, %1 normal, %2 fast) 895 * @unmount_mode: selected unmount mode (%0 default, %1 normal, %2 fast)
896 * @bulk_read: enable bulk-reads 896 * @bulk_read: enable bulk-reads
897 * @chk_data_crc: check CRCs when reading data nodes
897 */ 898 */
898struct ubifs_mount_opts { 899struct ubifs_mount_opts {
899 unsigned int unmount_mode:2; 900 unsigned int unmount_mode:2;
900 unsigned int bulk_read:2; 901 unsigned int bulk_read:2;
902 unsigned int chk_data_crc:2;
901}; 903};
902 904
903/** 905/**
@@ -1001,6 +1003,9 @@ struct ubifs_mount_opts {
1001 * @bulk_read: enable bulk-reads 1003 * @bulk_read: enable bulk-reads
1002 * @bulk_read_buf_size: buffer size for bulk-reads 1004 * @bulk_read_buf_size: buffer size for bulk-reads
1003 * 1005 *
1006 * @no_chk_data_crc: do not check CRCs when reading data nodes (except during
1007 * recovery)
1008 *
1004 * @dirty_pg_cnt: number of dirty pages (not used) 1009 * @dirty_pg_cnt: number of dirty pages (not used)
1005 * @dirty_zn_cnt: number of dirty znodes 1010 * @dirty_zn_cnt: number of dirty znodes
1006 * @clean_zn_cnt: number of clean znodes 1011 * @clean_zn_cnt: number of clean znodes
@@ -1138,6 +1143,7 @@ struct ubifs_mount_opts {
1138 * @rcvrd_mst_node: recovered master node to write when mounting ro to rw 1143 * @rcvrd_mst_node: recovered master node to write when mounting ro to rw
1139 * @size_tree: inode size information for recovery 1144 * @size_tree: inode size information for recovery
1140 * @remounting_rw: set while remounting from ro to rw (sb flags have MS_RDONLY) 1145 * @remounting_rw: set while remounting from ro to rw (sb flags have MS_RDONLY)
1146 * @always_chk_crc: always check CRCs (while mounting and remounting rw)
1141 * @mount_opts: UBIFS-specific mount options 1147 * @mount_opts: UBIFS-specific mount options
1142 * 1148 *
1143 * @dbg_buf: a buffer of LEB size used for debugging purposes 1149 * @dbg_buf: a buffer of LEB size used for debugging purposes
@@ -1244,6 +1250,8 @@ struct ubifs_info {
1244 int bulk_read; 1250 int bulk_read;
1245 int bulk_read_buf_size; 1251 int bulk_read_buf_size;
1246 1252
1253 int no_chk_data_crc;
1254
1247 atomic_long_t dirty_pg_cnt; 1255 atomic_long_t dirty_pg_cnt;
1248 atomic_long_t dirty_zn_cnt; 1256 atomic_long_t dirty_zn_cnt;
1249 atomic_long_t clean_zn_cnt; 1257 atomic_long_t clean_zn_cnt;
@@ -1374,6 +1382,7 @@ struct ubifs_info {
1374 struct ubifs_mst_node *rcvrd_mst_node; 1382 struct ubifs_mst_node *rcvrd_mst_node;
1375 struct rb_root size_tree; 1383 struct rb_root size_tree;
1376 int remounting_rw; 1384 int remounting_rw;
1385 int always_chk_crc;
1377 struct ubifs_mount_opts mount_opts; 1386 struct ubifs_mount_opts mount_opts;
1378 1387
1379#ifdef CONFIG_UBIFS_FS_DEBUG 1388#ifdef CONFIG_UBIFS_FS_DEBUG
@@ -1416,7 +1425,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
1416int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum, 1425int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum,
1417 int offs, int dtype); 1426 int offs, int dtype);
1418int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, 1427int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
1419 int offs, int quiet); 1428 int offs, int quiet, int chk_crc);
1420void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad); 1429void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad);
1421void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last); 1430void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last);
1422int ubifs_io_init(struct ubifs_info *c); 1431int ubifs_io_init(struct ubifs_info *c);