From a5969cabbb4660eab42b6ef0412cbbd1200cf14d Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Sat, 12 Oct 2024 07:10:09 +0000 Subject: [PATCH] 修改led为gpio --- kernel/fs/ubifs/master.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 97 insertions(+), 19 deletions(-) diff --git a/kernel/fs/ubifs/master.c b/kernel/fs/ubifs/master.c index 9df4a41..911d055 100644 --- a/kernel/fs/ubifs/master.c +++ b/kernel/fs/ubifs/master.c @@ -1,20 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * This file is part of UBIFS. * * Copyright (C) 2006-2008 Nokia Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -23,6 +11,72 @@ /* This file implements reading and writing the master node */ #include "ubifs.h" + +/** + * ubifs_compare_master_node - compare two UBIFS master nodes + * @c: UBIFS file-system description object + * @m1: the first node + * @m2: the second node + * + * This function compares two UBIFS master nodes. Returns 0 if they are equal + * and nonzero if not. + */ +int ubifs_compare_master_node(struct ubifs_info *c, void *m1, void *m2) +{ + int ret; + int behind; + int hmac_offs = offsetof(struct ubifs_mst_node, hmac); + + /* + * Do not compare the common node header since the sequence number and + * hence the CRC are different. + */ + ret = memcmp(m1 + UBIFS_CH_SZ, m2 + UBIFS_CH_SZ, + hmac_offs - UBIFS_CH_SZ); + if (ret) + return ret; + + /* + * Do not compare the embedded HMAC aswell which also must be different + * due to the different common node header. + */ + behind = hmac_offs + UBIFS_MAX_HMAC_LEN; + + if (UBIFS_MST_NODE_SZ > behind) + return memcmp(m1 + behind, m2 + behind, UBIFS_MST_NODE_SZ - behind); + + return 0; +} + +/* mst_node_check_hash - Check hash of a master node + * @c: UBIFS file-system description object + * @mst: The master node + * @expected: The expected hash of the master node + * + * This checks the hash of a master node against a given expected hash. + * Note that we have two master nodes on a UBIFS image which have different + * sequence numbers and consequently different CRCs. To be able to match + * both master nodes we exclude the common node header containing the sequence + * number and CRC from the hash. + * + * Returns 0 if the hashes are equal, a negative error code otherwise. + */ +static int mst_node_check_hash(const struct ubifs_info *c, + const struct ubifs_mst_node *mst, + const u8 *expected) +{ + u8 calc[UBIFS_MAX_HASH_LEN]; + const void *node = mst; + + crypto_shash_tfm_digest(c->hash_tfm, node + sizeof(struct ubifs_ch), + UBIFS_MST_NODE_SZ - sizeof(struct ubifs_ch), + calc); + + if (ubifs_check_hash(c, expected, calc)) + return -EPERM; + + return 0; +} /** * scan_for_master - search the valid master node. @@ -37,7 +91,7 @@ { struct ubifs_scan_leb *sleb; struct ubifs_scan_node *snod; - int lnum, offs = 0, nodes_cnt; + int lnum, offs = 0, nodes_cnt, err; lnum = UBIFS_MST_LNUM; @@ -69,12 +123,31 @@ goto out_dump; if (snod->offs != offs) goto out; - if (memcmp((void *)c->mst_node + UBIFS_CH_SZ, - (void *)snod->node + UBIFS_CH_SZ, - UBIFS_MST_NODE_SZ - UBIFS_CH_SZ)) + if (ubifs_compare_master_node(c, c->mst_node, snod->node)) goto out; + c->mst_offs = offs; ubifs_scan_destroy(sleb); + + if (!ubifs_authenticated(c)) + return 0; + + if (ubifs_hmac_zero(c, c->mst_node->hmac)) { + err = mst_node_check_hash(c, c->mst_node, + c->sup_node->hash_mst); + if (err) + ubifs_err(c, "Failed to verify master node hash"); + } else { + err = ubifs_node_verify_hmac(c, c->mst_node, + sizeof(struct ubifs_mst_node), + offsetof(struct ubifs_mst_node, hmac)); + if (err) + ubifs_err(c, "Failed to verify master node HMAC"); + } + + if (err) + return -EPERM; + return 0; out: @@ -305,6 +378,8 @@ c->lst.total_dead = le64_to_cpu(c->mst_node->total_dead); c->lst.total_dark = le64_to_cpu(c->mst_node->total_dark); + ubifs_copy_hash(c, c->mst_node->hash_root_idx, c->zroot.hash); + c->calc_idx_sz = c->bi.old_idx_sz; if (c->mst_node->flags & cpu_to_le32(UBIFS_MST_NO_ORPHS)) @@ -378,7 +453,9 @@ c->mst_offs = offs; c->mst_node->highest_inum = cpu_to_le64(c->highest_inum); - err = ubifs_write_node(c, c->mst_node, len, lnum, offs); + ubifs_copy_hash(c, c->zroot.hash, c->mst_node->hash_root_idx); + err = ubifs_write_node_hmac(c, c->mst_node, len, lnum, offs, + offsetof(struct ubifs_mst_node, hmac)); if (err) return err; @@ -389,7 +466,8 @@ if (err) return err; } - err = ubifs_write_node(c, c->mst_node, len, lnum, offs); + err = ubifs_write_node_hmac(c, c->mst_node, len, lnum, offs, + offsetof(struct ubifs_mst_node, hmac)); return err; } -- Gitblit v1.6.2