diff options
Diffstat (limited to 'fs/ubifs/io.c')
-rw-r--r-- | fs/ubifs/io.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 054363f2b207..01682713af69 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -62,6 +62,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err) | |||
62 | { | 62 | { |
63 | if (!c->ro_media) { | 63 | if (!c->ro_media) { |
64 | c->ro_media = 1; | 64 | c->ro_media = 1; |
65 | c->no_chk_data_crc = 0; | ||
65 | ubifs_warn("switched to read-only mode, error %d", err); | 66 | ubifs_warn("switched to read-only mode, error %d", err); |
66 | dbg_dump_stack(); | 67 | dbg_dump_stack(); |
67 | } | 68 | } |
@@ -74,6 +75,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err) | |||
74 | * @lnum: logical eraseblock number | 75 | * @lnum: logical eraseblock number |
75 | * @offs: offset within the logical eraseblock | 76 | * @offs: offset within the logical eraseblock |
76 | * @quiet: print no messages | 77 | * @quiet: print no messages |
78 | * @chk_crc: indicates whether to always check the CRC | ||
77 | * | 79 | * |
78 | * This function checks node magic number and CRC checksum. This function also | 80 | * 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 | 81 | * validates node length to prevent UBIFS from becoming crazy when an attacker |
@@ -85,7 +87,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err) | |||
85 | * or magic. | 87 | * or magic. |
86 | */ | 88 | */ |
87 | int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, | 89 | int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, |
88 | int offs, int quiet) | 90 | int offs, int quiet, int chk_crc) |
89 | { | 91 | { |
90 | int err = -EINVAL, type, node_len; | 92 | int err = -EINVAL, type, node_len; |
91 | uint32_t crc, node_crc, magic; | 93 | uint32_t crc, node_crc, magic; |
@@ -121,6 +123,10 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, | |||
121 | node_len > c->ranges[type].max_len) | 123 | node_len > c->ranges[type].max_len) |
122 | goto out_len; | 124 | goto out_len; |
123 | 125 | ||
126 | if (!chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc) | ||
127 | if (c->no_chk_data_crc) | ||
128 | return 0; | ||
129 | |||
124 | crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); | 130 | crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); |
125 | node_crc = le32_to_cpu(ch->crc); | 131 | node_crc = le32_to_cpu(ch->crc); |
126 | if (crc != node_crc) { | 132 | if (crc != node_crc) { |
@@ -722,7 +728,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, | |||
722 | goto out; | 728 | goto out; |
723 | } | 729 | } |
724 | 730 | ||
725 | err = ubifs_check_node(c, buf, lnum, offs, 0); | 731 | err = ubifs_check_node(c, buf, lnum, offs, 0, 0); |
726 | if (err) { | 732 | if (err) { |
727 | ubifs_err("expected node type %d", type); | 733 | ubifs_err("expected node type %d", type); |
728 | return err; | 734 | return err; |
@@ -781,7 +787,7 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len, | |||
781 | goto out; | 787 | goto out; |
782 | } | 788 | } |
783 | 789 | ||
784 | err = ubifs_check_node(c, buf, lnum, offs, 0); | 790 | err = ubifs_check_node(c, buf, lnum, offs, 0, 0); |
785 | if (err) { | 791 | if (err) { |
786 | ubifs_err("expected node type %d", type); | 792 | ubifs_err("expected node type %d", type); |
787 | return err; | 793 | return err; |