fs/ubifs/master.c

Source file repositories/reference/linux-study-clean/fs/ubifs/master.c

File Facts

System
Linux kernel
Corpus path
fs/ubifs/master.c
Extension
.c
Size
12671 bytes
Lines
477
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * This file is part of UBIFS.
 *
 * Copyright (C) 2006-2008 Nokia Corporation.
 *
 * Authors: Artem Bityutskiy (Битюцкий Артём)
 *          Adrian Hunter
 */

/* 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 as well 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;
	int ret;

	ret = crypto_shash_tfm_digest(c->hash_tfm, node + sizeof(struct ubifs_ch),
				UBIFS_MST_NODE_SZ - sizeof(struct ubifs_ch),
				calc);
	if (ret)
		return ret;

	if (ubifs_check_hash(c, expected, calc))
		return -EPERM;

	return 0;
}

/**
 * scan_for_master - search the valid master node.
 * @c: UBIFS file-system description object
 *
 * This function scans the master node LEBs and search for the latest master
 * node. Returns zero in case of success, %-EUCLEAN if there master area is
 * corrupted and requires recovery, and a negative error code in case of

Annotation

Implementation Notes