aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs/tnc_commit.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-09-07 08:36:35 -0400
committerRichard Weinberger <richard@nod.at>2018-10-23 07:48:39 -0400
commit16a26b20d2afd0cf063816725b45b12e78d5bb31 (patch)
tree3537a8eecd5da38204e443a887f4d1ed9f3cbcbe /fs/ubifs/tnc_commit.c
parent823838a486888cf484e739ab37df14cb04dfddb5 (diff)
ubifs: authentication: Add hashes to index nodes
With this patch the hashes over the index nodes stored in the tree node cache are written to flash and are checked when read back from flash. The hash of the root index node is stored in the master node. During journal replay the hashes are regenerated from the read nodes and stored in the tree node cache. This means the nodes must previously be authenticated by other means. This is done in a later patch. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'fs/ubifs/tnc_commit.c')
-rw-r--r--fs/ubifs/tnc_commit.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index dba87d09b989..dbcd2c350b65 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -38,6 +38,7 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
38 struct ubifs_znode *znode, int lnum, int offs, int len) 38 struct ubifs_znode *znode, int lnum, int offs, int len)
39{ 39{
40 struct ubifs_znode *zp; 40 struct ubifs_znode *zp;
41 u8 hash[UBIFS_HASH_ARR_SZ];
41 int i, err; 42 int i, err;
42 43
43 /* Make index node */ 44 /* Make index node */
@@ -52,6 +53,7 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
52 br->lnum = cpu_to_le32(zbr->lnum); 53 br->lnum = cpu_to_le32(zbr->lnum);
53 br->offs = cpu_to_le32(zbr->offs); 54 br->offs = cpu_to_le32(zbr->offs);
54 br->len = cpu_to_le32(zbr->len); 55 br->len = cpu_to_le32(zbr->len);
56 ubifs_copy_hash(c, zbr->hash, ubifs_branch_hash(c, br));
55 if (!zbr->lnum || !zbr->len) { 57 if (!zbr->lnum || !zbr->len) {
56 ubifs_err(c, "bad ref in znode"); 58 ubifs_err(c, "bad ref in znode");
57 ubifs_dump_znode(c, znode); 59 ubifs_dump_znode(c, znode);
@@ -62,6 +64,7 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
62 } 64 }
63 } 65 }
64 ubifs_prepare_node(c, idx, len, 0); 66 ubifs_prepare_node(c, idx, len, 0);
67 ubifs_node_calc_hash(c, idx, hash);
65 68
66 znode->lnum = lnum; 69 znode->lnum = lnum;
67 znode->offs = offs; 70 znode->offs = offs;
@@ -78,10 +81,12 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
78 zbr->lnum = lnum; 81 zbr->lnum = lnum;
79 zbr->offs = offs; 82 zbr->offs = offs;
80 zbr->len = len; 83 zbr->len = len;
84 ubifs_copy_hash(c, hash, zbr->hash);
81 } else { 85 } else {
82 c->zroot.lnum = lnum; 86 c->zroot.lnum = lnum;
83 c->zroot.offs = offs; 87 c->zroot.offs = offs;
84 c->zroot.len = len; 88 c->zroot.len = len;
89 ubifs_copy_hash(c, hash, c->zroot.hash);
85 } 90 }
86 c->calc_idx_sz += ALIGN(len, 8); 91 c->calc_idx_sz += ALIGN(len, 8);
87 92
@@ -647,6 +652,8 @@ static int get_znodes_to_commit(struct ubifs_info *c)
647 znode->cnext = c->cnext; 652 znode->cnext = c->cnext;
648 break; 653 break;
649 } 654 }
655 znode->cparent = znode->parent;
656 znode->ciip = znode->iip;
650 znode->cnext = cnext; 657 znode->cnext = cnext;
651 znode = cnext; 658 znode = cnext;
652 cnt += 1; 659 cnt += 1;
@@ -840,6 +847,8 @@ static int write_index(struct ubifs_info *c)
840 } 847 }
841 848
842 while (1) { 849 while (1) {
850 u8 hash[UBIFS_HASH_ARR_SZ];
851
843 cond_resched(); 852 cond_resched();
844 853
845 znode = cnext; 854 znode = cnext;
@@ -857,6 +866,7 @@ static int write_index(struct ubifs_info *c)
857 br->lnum = cpu_to_le32(zbr->lnum); 866 br->lnum = cpu_to_le32(zbr->lnum);
858 br->offs = cpu_to_le32(zbr->offs); 867 br->offs = cpu_to_le32(zbr->offs);
859 br->len = cpu_to_le32(zbr->len); 868 br->len = cpu_to_le32(zbr->len);
869 ubifs_copy_hash(c, zbr->hash, ubifs_branch_hash(c, br));
860 if (!zbr->lnum || !zbr->len) { 870 if (!zbr->lnum || !zbr->len) {
861 ubifs_err(c, "bad ref in znode"); 871 ubifs_err(c, "bad ref in znode");
862 ubifs_dump_znode(c, znode); 872 ubifs_dump_znode(c, znode);
@@ -868,6 +878,23 @@ static int write_index(struct ubifs_info *c)
868 } 878 }
869 len = ubifs_idx_node_sz(c, znode->child_cnt); 879 len = ubifs_idx_node_sz(c, znode->child_cnt);
870 ubifs_prepare_node(c, idx, len, 0); 880 ubifs_prepare_node(c, idx, len, 0);
881 ubifs_node_calc_hash(c, idx, hash);
882
883 mutex_lock(&c->tnc_mutex);
884
885 if (znode->cparent)
886 ubifs_copy_hash(c, hash,
887 znode->cparent->zbranch[znode->ciip].hash);
888
889 if (znode->parent) {
890 if (!ubifs_zn_obsolete(znode))
891 ubifs_copy_hash(c, hash,
892 znode->parent->zbranch[znode->iip].hash);
893 } else {
894 ubifs_copy_hash(c, hash, c->zroot.hash);
895 }
896
897 mutex_unlock(&c->tnc_mutex);
871 898
872 /* Determine the index node position */ 899 /* Determine the index node position */
873 if (lnum == -1) { 900 if (lnum == -1) {