diff options
Diffstat (limited to 'fs/ubifs/io.c')
-rw-r--r-- | fs/ubifs/io.c | 11 |
1 files changed, 8 insertions, 3 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 | */ |
87 | int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, | 88 | int 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; |