Skip to content

Commit acc5af3

Browse files
Liu Songrichardweinberger
authored andcommitted
ubifs: Fix out-of-bounds memory access caused by abnormal value of node_len
In “ubifs_check_node”, when the value of "node_len" is abnormal, the code will goto label of "out_len" for execution. Then, in the following "ubifs_dump_node", if inode type is "UBIFS_DATA_NODE", in "print_hex_dump", an out-of-bounds access may occur due to the wrong "ch->len". Therefore, when the value of "node_len" is abnormal, data length should to be adjusted to a reasonable safe range. At this time, structured data is not credible, so dump the corrupted data directly for analysis. Signed-off-by: Liu Song <[email protected]> Signed-off-by: Richard Weinberger <[email protected]>
1 parent 294a8db commit acc5af3

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

fs/ubifs/io.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
225225
int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
226226
int offs, int quiet, int must_chk_crc)
227227
{
228-
int err = -EINVAL, type, node_len;
228+
int err = -EINVAL, type, node_len, dump_node = 1;
229229
uint32_t crc, node_crc, magic;
230230
const struct ubifs_ch *ch = buf;
231231

@@ -278,10 +278,22 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
278278
out_len:
279279
if (!quiet)
280280
ubifs_err(c, "bad node length %d", node_len);
281+
if (type == UBIFS_DATA_NODE && node_len > UBIFS_DATA_NODE_SZ)
282+
dump_node = 0;
281283
out:
282284
if (!quiet) {
283285
ubifs_err(c, "bad node at LEB %d:%d", lnum, offs);
284-
ubifs_dump_node(c, buf);
286+
if (dump_node) {
287+
ubifs_dump_node(c, buf);
288+
} else {
289+
int safe_len = min3(node_len, c->leb_size - offs,
290+
(int)UBIFS_MAX_DATA_NODE_SZ);
291+
pr_err("\tprevent out-of-bounds memory access\n");
292+
pr_err("\ttruncated data node length %d\n", safe_len);
293+
pr_err("\tcorrupted data node:\n");
294+
print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_OFFSET, 32, 1,
295+
buf, safe_len, 0);
296+
}
285297
dump_stack();
286298
}
287299
return err;

0 commit comments

Comments
 (0)