summaryrefslogtreecommitdiffstats
path: root/fs/ubifs/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs/io.c')
-rw-r--r--fs/ubifs/io.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 3374f91b6709..01682713af69 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -54,12 +54,28 @@
#include "ubifs.h"
/**
+ * ubifs_ro_mode - switch UBIFS to read read-only mode.
+ * @c: UBIFS file-system description object
+ * @err: error code which is the reason of switching to R/O mode
+ */
+void ubifs_ro_mode(struct ubifs_info *c, int err)
+{
+ if (!c->ro_media) {
+ c->ro_media = 1;
+ c->no_chk_data_crc = 0;
+ ubifs_warn("switched to read-only mode, error %d", err);
+ dbg_dump_stack();
+ }
+}
+
+/**
* ubifs_check_node - check node.
* @c: UBIFS file-system description object
* @buf: node to check
* @lnum: logical eraseblock number
* @offs: offset within the logical eraseblock
* @quiet: print no messages
+ * @chk_crc: indicates whether to always check the CRC
*
* This function checks node magic number and CRC checksum. This function also
* validates node length to prevent UBIFS from becoming crazy when an attacker
@@ -71,7 +87,7 @@
* or magic.
*/
int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
- int offs, int quiet)
+ int offs, int quiet, int chk_crc)
{
int err = -EINVAL, type, node_len;
uint32_t crc, node_crc, magic;
@@ -107,6 +123,10 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
node_len > c->ranges[type].max_len)
goto out_len;
+ if (!chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc)
+ if (c->no_chk_data_crc)
+ return 0;
+
crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);
node_crc = le32_to_cpu(ch->crc);
if (crc != node_crc) {
@@ -708,7 +728,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
goto out;
}
- err = ubifs_check_node(c, buf, lnum, offs, 0);
+ err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
if (err) {
ubifs_err("expected node type %d", type);
return err;
@@ -767,7 +787,7 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
goto out;
}
- err = ubifs_check_node(c, buf, lnum, offs, 0);
+ err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
if (err) {
ubifs_err("expected node type %d", type);
return err;