| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * This file is part of UBIFS. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2006-2008 Nokia Corporation. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 8 | | - * the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 16 | | - * this program; if not, write to the Free Software Foundation, Inc., 51 |
|---|
| 17 | | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 18 | 6 | * |
|---|
| 19 | 7 | * Authors: Adrian Hunter |
|---|
| 20 | 8 | * Artem Bityutskiy (Битюцкий Артём) |
|---|
| .. | .. |
|---|
| 138 | 126 | const struct ubifs_znode *znode, |
|---|
| 139 | 127 | const union ubifs_key *key, int *n) |
|---|
| 140 | 128 | { |
|---|
| 141 | | - int beg = 0, end = znode->child_cnt, uninitialized_var(mid); |
|---|
| 142 | | - int uninitialized_var(cmp); |
|---|
| 129 | + int beg = 0, end = znode->child_cnt, mid; |
|---|
| 130 | + int cmp; |
|---|
| 143 | 131 | const struct ubifs_zbranch *zbr = &znode->zbranch[0]; |
|---|
| 144 | 132 | |
|---|
| 145 | 133 | ubifs_assert(c, end > beg); |
|---|
| .. | .. |
|---|
| 265 | 253 | /** |
|---|
| 266 | 254 | * read_znode - read an indexing node from flash and fill znode. |
|---|
| 267 | 255 | * @c: UBIFS file-system description object |
|---|
| 268 | | - * @lnum: LEB of the indexing node to read |
|---|
| 269 | | - * @offs: node offset |
|---|
| 270 | | - * @len: node length |
|---|
| 256 | + * @zzbr: the zbranch describing the node to read |
|---|
| 271 | 257 | * @znode: znode to read to |
|---|
| 272 | 258 | * |
|---|
| 273 | 259 | * This function reads an indexing node from the flash media and fills znode |
|---|
| .. | .. |
|---|
| 276 | 262 | * is wrong with it, this function prints complaint messages and returns |
|---|
| 277 | 263 | * %-EINVAL. |
|---|
| 278 | 264 | */ |
|---|
| 279 | | -static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, |
|---|
| 265 | +static int read_znode(struct ubifs_info *c, struct ubifs_zbranch *zzbr, |
|---|
| 280 | 266 | struct ubifs_znode *znode) |
|---|
| 281 | 267 | { |
|---|
| 268 | + int lnum = zzbr->lnum; |
|---|
| 269 | + int offs = zzbr->offs; |
|---|
| 270 | + int len = zzbr->len; |
|---|
| 282 | 271 | int i, err, type, cmp; |
|---|
| 283 | 272 | struct ubifs_idx_node *idx; |
|---|
| 284 | 273 | |
|---|
| .. | .. |
|---|
| 288 | 277 | |
|---|
| 289 | 278 | err = ubifs_read_node(c, idx, UBIFS_IDX_NODE, len, lnum, offs); |
|---|
| 290 | 279 | if (err < 0) { |
|---|
| 280 | + kfree(idx); |
|---|
| 281 | + return err; |
|---|
| 282 | + } |
|---|
| 283 | + |
|---|
| 284 | + err = ubifs_node_check_hash(c, idx, zzbr->hash); |
|---|
| 285 | + if (err) { |
|---|
| 286 | + ubifs_bad_hash(c, idx, zzbr->hash, lnum, offs); |
|---|
| 291 | 287 | kfree(idx); |
|---|
| 292 | 288 | return err; |
|---|
| 293 | 289 | } |
|---|
| .. | .. |
|---|
| 308 | 304 | } |
|---|
| 309 | 305 | |
|---|
| 310 | 306 | for (i = 0; i < znode->child_cnt; i++) { |
|---|
| 311 | | - const struct ubifs_branch *br = ubifs_idx_branch(c, idx, i); |
|---|
| 307 | + struct ubifs_branch *br = ubifs_idx_branch(c, idx, i); |
|---|
| 312 | 308 | struct ubifs_zbranch *zbr = &znode->zbranch[i]; |
|---|
| 313 | 309 | |
|---|
| 314 | 310 | key_read(c, &br->key, &zbr->key); |
|---|
| 315 | 311 | zbr->lnum = le32_to_cpu(br->lnum); |
|---|
| 316 | 312 | zbr->offs = le32_to_cpu(br->offs); |
|---|
| 317 | 313 | zbr->len = le32_to_cpu(br->len); |
|---|
| 314 | + ubifs_copy_hash(c, ubifs_branch_hash(c, br), zbr->hash); |
|---|
| 318 | 315 | zbr->znode = NULL; |
|---|
| 319 | 316 | |
|---|
| 320 | 317 | /* Validate branch */ |
|---|
| .. | .. |
|---|
| 425 | 422 | if (!znode) |
|---|
| 426 | 423 | return ERR_PTR(-ENOMEM); |
|---|
| 427 | 424 | |
|---|
| 428 | | - err = read_znode(c, zbr->lnum, zbr->offs, zbr->len, znode); |
|---|
| 425 | + err = read_znode(c, zbr, znode); |
|---|
| 429 | 426 | if (err) |
|---|
| 430 | 427 | goto out; |
|---|
| 431 | 428 | |
|---|
| .. | .. |
|---|
| 496 | 493 | return -EINVAL; |
|---|
| 497 | 494 | } |
|---|
| 498 | 495 | |
|---|
| 496 | + err = ubifs_node_check_hash(c, node, zbr->hash); |
|---|
| 497 | + if (err) { |
|---|
| 498 | + ubifs_bad_hash(c, node, zbr->hash, zbr->lnum, zbr->offs); |
|---|
| 499 | + return err; |
|---|
| 500 | + } |
|---|
| 501 | + |
|---|
| 499 | 502 | return 0; |
|---|
| 500 | 503 | } |
|---|