24
24
25
25
#include "ubifs.h"
26
26
27
+ /**
28
+ * ubifs_compare_master_node - compare two UBIFS master nodes
29
+ * @c: UBIFS file-system description object
30
+ * @m1: the first node
31
+ * @m2: the second node
32
+ *
33
+ * This function compares two UBIFS master nodes. Returns 0 if they are equal
34
+ * and nonzero if not.
35
+ */
36
+ int ubifs_compare_master_node (struct ubifs_info * c , void * m1 , void * m2 )
37
+ {
38
+ int ret ;
39
+ int behind ;
40
+ int hmac_offs = offsetof(struct ubifs_mst_node , hmac );
41
+
42
+ /*
43
+ * Do not compare the common node header since the sequence number and
44
+ * hence the CRC are different.
45
+ */
46
+ ret = memcmp (m1 + UBIFS_CH_SZ , m2 + UBIFS_CH_SZ ,
47
+ hmac_offs - UBIFS_CH_SZ );
48
+ if (ret )
49
+ return ret ;
50
+
51
+ /*
52
+ * Do not compare the embedded HMAC aswell which also must be different
53
+ * due to the different common node header.
54
+ */
55
+ behind = hmac_offs + UBIFS_MAX_HMAC_LEN ;
56
+
57
+ if (UBIFS_MST_NODE_SZ > behind )
58
+ return memcmp (m1 + behind , m2 + behind , UBIFS_MST_NODE_SZ - behind );
59
+
60
+ return 0 ;
61
+ }
62
+
27
63
/**
28
64
* scan_for_master - search the valid master node.
29
65
* @c: UBIFS file-system description object
@@ -37,7 +73,7 @@ static int scan_for_master(struct ubifs_info *c)
37
73
{
38
74
struct ubifs_scan_leb * sleb ;
39
75
struct ubifs_scan_node * snod ;
40
- int lnum , offs = 0 , nodes_cnt ;
76
+ int lnum , offs = 0 , nodes_cnt , err ;
41
77
42
78
lnum = UBIFS_MST_LNUM ;
43
79
@@ -69,12 +105,23 @@ static int scan_for_master(struct ubifs_info *c)
69
105
goto out_dump ;
70
106
if (snod -> offs != offs )
71
107
goto out ;
72
- if (memcmp ((void * )c -> mst_node + UBIFS_CH_SZ ,
73
- (void * )snod -> node + UBIFS_CH_SZ ,
74
- UBIFS_MST_NODE_SZ - UBIFS_CH_SZ ))
108
+ if (ubifs_compare_master_node (c , c -> mst_node , snod -> node ))
75
109
goto out ;
110
+
76
111
c -> mst_offs = offs ;
77
112
ubifs_scan_destroy (sleb );
113
+
114
+ if (!ubifs_authenticated (c ))
115
+ return 0 ;
116
+
117
+ err = ubifs_node_verify_hmac (c , c -> mst_node ,
118
+ sizeof (struct ubifs_mst_node ),
119
+ offsetof(struct ubifs_mst_node , hmac ));
120
+ if (err ) {
121
+ ubifs_err (c , "Failed to verify master node HMAC" );
122
+ return - EPERM ;
123
+ }
124
+
78
125
return 0 ;
79
126
80
127
out :
@@ -381,7 +428,8 @@ int ubifs_write_master(struct ubifs_info *c)
381
428
c -> mst_node -> highest_inum = cpu_to_le64 (c -> highest_inum );
382
429
383
430
ubifs_copy_hash (c , c -> zroot .hash , c -> mst_node -> hash_root_idx );
384
- err = ubifs_write_node (c , c -> mst_node , len , lnum , offs );
431
+ err = ubifs_write_node_hmac (c , c -> mst_node , len , lnum , offs ,
432
+ offsetof(struct ubifs_mst_node , hmac ));
385
433
if (err )
386
434
return err ;
387
435
@@ -392,7 +440,8 @@ int ubifs_write_master(struct ubifs_info *c)
392
440
if (err )
393
441
return err ;
394
442
}
395
- err = ubifs_write_node (c , c -> mst_node , len , lnum , offs );
443
+ err = ubifs_write_node_hmac (c , c -> mst_node , len , lnum , offs ,
444
+ offsetof(struct ubifs_mst_node , hmac ));
396
445
397
446
return err ;
398
447
}
0 commit comments