summaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-09-07 08:36:36 -0400
committerRichard Weinberger <richard@nod.at>2018-10-23 07:48:39 -0400
commit6a98bc4614de8fac8c6d520a6b20b194e23c9936 (patch)
tree768d9f175e5f658f1d38481f3ecdd9fb18ffdbef /fs/ubifs
parent16a26b20d2afd0cf063816725b45b12e78d5bb31 (diff)
ubifs: Add authentication nodes to journal
Nodes that are written to flash can only be authenticated through the index after the next commit. When a journal replay is necessary the nodes are not yet referenced by the index and thus can't be authenticated. This patch overcomes this situation by creating a hash over all nodes beginning from the commit start node over the reference node(s) and the buds themselves. From time to time we insert authentication nodes. Authentication nodes contain a HMAC from the current hash state, so that they can be used to authenticate a journal replay up to the point where the authentication node is. The hash is continued afterwards so that theoretically we would only have to check the HMAC of the last authentication node we find. Overall we get this picture: ,,,,,,,, ,......,........................................... ,. CS , hash1.----. hash2.----. ,. | , . |hmac . |hmac ,. v , . v . v ,.REF#0,-> bud -> bud -> bud.-> auth -> bud -> bud.-> auth ... ,..|...,........................................... , | , , | ,,,,,,,,,,,,,,, . | hash3,----. , | , |hmac , v , v , REF#1 -> bud -> bud,-> auth ... ,,,|,,,,,,,,,,,,,,,,,, v REF#2 -> ... | V ... Note how hash3 covers CS, REF#0 and REF#1 so that it is not possible to exchange or skip any reference nodes. Unlike the picture suggests the auth nodes themselves are not hashed. With this it is possible for an offline attacker to cut each journal head or to drop the last reference node(s), but not to skip any journal heads or to reorder any operations. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/gc.c3
-rw-r--r--fs/ubifs/journal.c124
-rw-r--r--fs/ubifs/log.c24
-rw-r--r--fs/ubifs/replay.c2
-rw-r--r--fs/ubifs/super.c10
-rw-r--r--fs/ubifs/ubifs.h8
6 files changed, 153 insertions, 18 deletions
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index d2680e0b4a36..399d764f83cb 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -254,7 +254,8 @@ static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
254 snod->type == UBIFS_DATA_NODE || 254 snod->type == UBIFS_DATA_NODE ||
255 snod->type == UBIFS_DENT_NODE || 255 snod->type == UBIFS_DENT_NODE ||
256 snod->type == UBIFS_XENT_NODE || 256 snod->type == UBIFS_XENT_NODE ||
257 snod->type == UBIFS_TRUN_NODE); 257 snod->type == UBIFS_TRUN_NODE ||
258 snod->type == UBIFS_AUTH_NODE);
258 259
259 if (snod->type != UBIFS_INO_NODE && 260 if (snod->type != UBIFS_INO_NODE &&
260 snod->type != UBIFS_DATA_NODE && 261 snod->type != UBIFS_DATA_NODE &&
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 7c12bdfa9a7a..729dc76c83df 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -90,6 +90,12 @@ static inline void zero_trun_node_unused(struct ubifs_trun_node *trun)
90 memset(trun->padding, 0, 12); 90 memset(trun->padding, 0, 12);
91} 91}
92 92
93static void ubifs_add_auth_dirt(struct ubifs_info *c, int lnum)
94{
95 if (ubifs_authenticated(c))
96 ubifs_add_dirt(c, lnum, ubifs_auth_node_sz(c));
97}
98
93/** 99/**
94 * reserve_space - reserve space in the journal. 100 * reserve_space - reserve space in the journal.
95 * @c: UBIFS file-system description object 101 * @c: UBIFS file-system description object
@@ -228,6 +234,35 @@ out_return:
228 return err; 234 return err;
229} 235}
230 236
237static int ubifs_hash_nodes(struct ubifs_info *c, void *node,
238 int len, struct shash_desc *hash)
239{
240 int auth_node_size = ubifs_auth_node_sz(c);
241 int err;
242
243 while (1) {
244 const struct ubifs_ch *ch = node;
245 int nodelen = le32_to_cpu(ch->len);
246
247 ubifs_assert(c, len >= auth_node_size);
248
249 if (len == auth_node_size)
250 break;
251
252 ubifs_assert(c, len > nodelen);
253 ubifs_assert(c, ch->magic == cpu_to_le32(UBIFS_NODE_MAGIC));
254
255 err = ubifs_shash_update(c, hash, (void *)node, nodelen);
256 if (err)
257 return err;
258
259 node += ALIGN(nodelen, 8);
260 len -= ALIGN(nodelen, 8);
261 }
262
263 return ubifs_prepare_auth_node(c, node, hash);
264}
265
231/** 266/**
232 * write_head - write data to a journal head. 267 * write_head - write data to a journal head.
233 * @c: UBIFS file-system description object 268 * @c: UBIFS file-system description object
@@ -255,6 +290,12 @@ static int write_head(struct ubifs_info *c, int jhead, void *buf, int len,
255 dbg_jnl("jhead %s, LEB %d:%d, len %d", 290 dbg_jnl("jhead %s, LEB %d:%d, len %d",
256 dbg_jhead(jhead), *lnum, *offs, len); 291 dbg_jhead(jhead), *lnum, *offs, len);
257 292
293 if (ubifs_authenticated(c)) {
294 err = ubifs_hash_nodes(c, buf, len, c->jheads[jhead].log_hash);
295 if (err)
296 return err;
297 }
298
258 err = ubifs_wbuf_write_nolock(wbuf, buf, len); 299 err = ubifs_wbuf_write_nolock(wbuf, buf, len);
259 if (err) 300 if (err)
260 return err; 301 return err;
@@ -543,7 +584,10 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
543 584
544 len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; 585 len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ;
545 /* Make sure to also account for extended attributes */ 586 /* Make sure to also account for extended attributes */
546 len += host_ui->data_len; 587 if (ubifs_authenticated(c))
588 len += ALIGN(host_ui->data_len, 8) + ubifs_auth_node_sz(c);
589 else
590 len += host_ui->data_len;
547 591
548 dent = kzalloc(len, GFP_NOFS); 592 dent = kzalloc(len, GFP_NOFS);
549 if (!dent) 593 if (!dent)
@@ -611,6 +655,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
611 } 655 }
612 release_head(c, BASEHD); 656 release_head(c, BASEHD);
613 kfree(dent); 657 kfree(dent);
658 ubifs_add_auth_dirt(c, lnum);
614 659
615 if (deletion) { 660 if (deletion) {
616 if (nm->hash) 661 if (nm->hash)
@@ -690,8 +735,9 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
690 const union ubifs_key *key, const void *buf, int len) 735 const union ubifs_key *key, const void *buf, int len)
691{ 736{
692 struct ubifs_data_node *data; 737 struct ubifs_data_node *data;
693 int err, lnum, offs, compr_type, out_len, compr_len; 738 int err, lnum, offs, compr_type, out_len, compr_len, auth_len;
694 int dlen = COMPRESSED_DATA_NODE_BUF_SZ, allocated = 1; 739 int dlen = COMPRESSED_DATA_NODE_BUF_SZ, allocated = 1;
740 int write_len;
695 struct ubifs_inode *ui = ubifs_inode(inode); 741 struct ubifs_inode *ui = ubifs_inode(inode);
696 bool encrypted = ubifs_crypt_is_encrypted(inode); 742 bool encrypted = ubifs_crypt_is_encrypted(inode);
697 u8 hash[UBIFS_HASH_ARR_SZ]; 743 u8 hash[UBIFS_HASH_ARR_SZ];
@@ -703,7 +749,9 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
703 if (encrypted) 749 if (encrypted)
704 dlen += UBIFS_CIPHER_BLOCK_SIZE; 750 dlen += UBIFS_CIPHER_BLOCK_SIZE;
705 751
706 data = kmalloc(dlen, GFP_NOFS | __GFP_NOWARN); 752 auth_len = ubifs_auth_node_sz(c);
753
754 data = kmalloc(dlen + auth_len, GFP_NOFS | __GFP_NOWARN);
707 if (!data) { 755 if (!data) {
708 /* 756 /*
709 * Fall-back to the write reserve buffer. Note, we might be 757 * Fall-back to the write reserve buffer. Note, we might be
@@ -742,15 +790,20 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
742 } 790 }
743 791
744 dlen = UBIFS_DATA_NODE_SZ + out_len; 792 dlen = UBIFS_DATA_NODE_SZ + out_len;
793 if (ubifs_authenticated(c))
794 write_len = ALIGN(dlen, 8) + auth_len;
795 else
796 write_len = dlen;
797
745 data->compr_type = cpu_to_le16(compr_type); 798 data->compr_type = cpu_to_le16(compr_type);
746 799
747 /* Make reservation before allocating sequence numbers */ 800 /* Make reservation before allocating sequence numbers */
748 err = make_reservation(c, DATAHD, dlen); 801 err = make_reservation(c, DATAHD, write_len);
749 if (err) 802 if (err)
750 goto out_free; 803 goto out_free;
751 804
752 ubifs_prepare_node(c, data, dlen, 0); 805 ubifs_prepare_node(c, data, dlen, 0);
753 err = write_head(c, DATAHD, data, dlen, &lnum, &offs, 0); 806 err = write_head(c, DATAHD, data, write_len, &lnum, &offs, 0);
754 if (err) 807 if (err)
755 goto out_release; 808 goto out_release;
756 809
@@ -761,6 +814,8 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
761 ubifs_wbuf_add_ino_nolock(&c->jheads[DATAHD].wbuf, key_inum(c, key)); 814 ubifs_wbuf_add_ino_nolock(&c->jheads[DATAHD].wbuf, key_inum(c, key));
762 release_head(c, DATAHD); 815 release_head(c, DATAHD);
763 816
817 ubifs_add_auth_dirt(c, lnum);
818
764 err = ubifs_tnc_add(c, key, lnum, offs, dlen, hash); 819 err = ubifs_tnc_add(c, key, lnum, offs, dlen, hash);
765 if (err) 820 if (err)
766 goto out_ro; 821 goto out_ro;
@@ -799,7 +854,8 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode)
799 int err, lnum, offs; 854 int err, lnum, offs;
800 struct ubifs_ino_node *ino; 855 struct ubifs_ino_node *ino;
801 struct ubifs_inode *ui = ubifs_inode(inode); 856 struct ubifs_inode *ui = ubifs_inode(inode);
802 int sync = 0, len = UBIFS_INO_NODE_SZ, last_reference = !inode->i_nlink; 857 int sync = 0, write_len, ilen = UBIFS_INO_NODE_SZ;
858 int last_reference = !inode->i_nlink;
803 u8 hash[UBIFS_HASH_ARR_SZ]; 859 u8 hash[UBIFS_HASH_ARR_SZ];
804 860
805 dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); 861 dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink);
@@ -809,15 +865,21 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode)
809 * need to synchronize the write-buffer either. 865 * need to synchronize the write-buffer either.
810 */ 866 */
811 if (!last_reference) { 867 if (!last_reference) {
812 len += ui->data_len; 868 ilen += ui->data_len;
813 sync = IS_SYNC(inode); 869 sync = IS_SYNC(inode);
814 } 870 }
815 ino = kmalloc(len, GFP_NOFS); 871
872 if (ubifs_authenticated(c))
873 write_len = ALIGN(ilen, 8) + ubifs_auth_node_sz(c);
874 else
875 write_len = ilen;
876
877 ino = kmalloc(write_len, GFP_NOFS);
816 if (!ino) 878 if (!ino)
817 return -ENOMEM; 879 return -ENOMEM;
818 880
819 /* Make reservation before allocating sequence numbers */ 881 /* Make reservation before allocating sequence numbers */
820 err = make_reservation(c, BASEHD, len); 882 err = make_reservation(c, BASEHD, write_len);
821 if (err) 883 if (err)
822 goto out_free; 884 goto out_free;
823 885
@@ -826,7 +888,7 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode)
826 if (err) 888 if (err)
827 goto out_release; 889 goto out_release;
828 890
829 err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); 891 err = write_head(c, BASEHD, ino, write_len, &lnum, &offs, sync);
830 if (err) 892 if (err)
831 goto out_release; 893 goto out_release;
832 if (!sync) 894 if (!sync)
@@ -834,17 +896,19 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode)
834 inode->i_ino); 896 inode->i_ino);
835 release_head(c, BASEHD); 897 release_head(c, BASEHD);
836 898
899 ubifs_add_auth_dirt(c, lnum);
900
837 if (last_reference) { 901 if (last_reference) {
838 err = ubifs_tnc_remove_ino(c, inode->i_ino); 902 err = ubifs_tnc_remove_ino(c, inode->i_ino);
839 if (err) 903 if (err)
840 goto out_ro; 904 goto out_ro;
841 ubifs_delete_orphan(c, inode->i_ino); 905 ubifs_delete_orphan(c, inode->i_ino);
842 err = ubifs_add_dirt(c, lnum, len); 906 err = ubifs_add_dirt(c, lnum, ilen);
843 } else { 907 } else {
844 union ubifs_key key; 908 union ubifs_key key;
845 909
846 ino_key_init(c, &key, inode->i_ino); 910 ino_key_init(c, &key, inode->i_ino);
847 err = ubifs_tnc_add(c, &key, lnum, offs, len, hash); 911 err = ubifs_tnc_add(c, &key, lnum, offs, ilen, hash);
848 } 912 }
849 if (err) 913 if (err)
850 goto out_ro; 914 goto out_ro;
@@ -973,6 +1037,8 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
973 if (twoparents) 1037 if (twoparents)
974 len += plen; 1038 len += plen;
975 1039
1040 len += ubifs_auth_node_sz(c);
1041
976 dent1 = kzalloc(len, GFP_NOFS); 1042 dent1 = kzalloc(len, GFP_NOFS);
977 if (!dent1) 1043 if (!dent1)
978 return -ENOMEM; 1044 return -ENOMEM;
@@ -1042,6 +1108,8 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
1042 } 1108 }
1043 release_head(c, BASEHD); 1109 release_head(c, BASEHD);
1044 1110
1111 ubifs_add_auth_dirt(c, lnum);
1112
1045 dent_key_init(c, &key, snd_dir->i_ino, snd_nm); 1113 dent_key_init(c, &key, snd_dir->i_ino, snd_nm);
1046 err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, snd_nm); 1114 err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, snd_nm);
1047 if (err) 1115 if (err)
@@ -1143,6 +1211,9 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
1143 len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); 1211 len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8);
1144 if (move) 1212 if (move)
1145 len += plen; 1213 len += plen;
1214
1215 len += ubifs_auth_node_sz(c);
1216
1146 dent = kzalloc(len, GFP_NOFS); 1217 dent = kzalloc(len, GFP_NOFS);
1147 if (!dent) 1218 if (!dent)
1148 return -ENOMEM; 1219 return -ENOMEM;
@@ -1240,6 +1311,8 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
1240 } 1311 }
1241 release_head(c, BASEHD); 1312 release_head(c, BASEHD);
1242 1313
1314 ubifs_add_auth_dirt(c, lnum);
1315
1243 dent_key_init(c, &key, new_dir->i_ino, new_nm); 1316 dent_key_init(c, &key, new_dir->i_ino, new_nm);
1244 err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, new_nm); 1317 err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, new_nm);
1245 if (err) 1318 if (err)
@@ -1411,6 +1484,9 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
1411 1484
1412 sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ + 1485 sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ +
1413 UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR; 1486 UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR;
1487
1488 sz += ubifs_auth_node_sz(c);
1489
1414 ino = kmalloc(sz, GFP_NOFS); 1490 ino = kmalloc(sz, GFP_NOFS);
1415 if (!ino) 1491 if (!ino)
1416 return -ENOMEM; 1492 return -ENOMEM;
@@ -1456,8 +1532,12 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
1456 1532
1457 /* Must make reservation before allocating sequence numbers */ 1533 /* Must make reservation before allocating sequence numbers */
1458 len = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ; 1534 len = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ;
1459 if (dlen) 1535
1536 if (ubifs_authenticated(c))
1537 len += ALIGN(dlen, 8) + ubifs_auth_node_sz(c);
1538 else
1460 len += dlen; 1539 len += dlen;
1540
1461 err = make_reservation(c, BASEHD, len); 1541 err = make_reservation(c, BASEHD, len);
1462 if (err) 1542 if (err)
1463 goto out_free; 1543 goto out_free;
@@ -1482,6 +1562,8 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
1482 ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, inum); 1562 ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, inum);
1483 release_head(c, BASEHD); 1563 release_head(c, BASEHD);
1484 1564
1565 ubifs_add_auth_dirt(c, lnum);
1566
1485 if (dlen) { 1567 if (dlen) {
1486 sz = offs + UBIFS_INO_NODE_SZ + UBIFS_TRUN_NODE_SZ; 1568 sz = offs + UBIFS_INO_NODE_SZ + UBIFS_TRUN_NODE_SZ;
1487 err = ubifs_tnc_add(c, &key, lnum, sz, dlen, hash_dn); 1569 err = ubifs_tnc_add(c, &key, lnum, sz, dlen, hash_dn);
@@ -1545,7 +1627,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
1545 const struct inode *inode, 1627 const struct inode *inode,
1546 const struct fscrypt_name *nm) 1628 const struct fscrypt_name *nm)
1547{ 1629{
1548 int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen; 1630 int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen, write_len;
1549 struct ubifs_dent_node *xent; 1631 struct ubifs_dent_node *xent;
1550 struct ubifs_ino_node *ino; 1632 struct ubifs_ino_node *ino;
1551 union ubifs_key xent_key, key1, key2; 1633 union ubifs_key xent_key, key1, key2;
@@ -1565,12 +1647,14 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
1565 hlen = host_ui->data_len + UBIFS_INO_NODE_SZ; 1647 hlen = host_ui->data_len + UBIFS_INO_NODE_SZ;
1566 len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); 1648 len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8);
1567 1649
1568 xent = kzalloc(len, GFP_NOFS); 1650 write_len = len + ubifs_auth_node_sz(c);
1651
1652 xent = kzalloc(write_len, GFP_NOFS);
1569 if (!xent) 1653 if (!xent)
1570 return -ENOMEM; 1654 return -ENOMEM;
1571 1655
1572 /* Make reservation before allocating sequence numbers */ 1656 /* Make reservation before allocating sequence numbers */
1573 err = make_reservation(c, BASEHD, len); 1657 err = make_reservation(c, BASEHD, write_len);
1574 if (err) { 1658 if (err) {
1575 kfree(xent); 1659 kfree(xent);
1576 return err; 1660 return err;
@@ -1595,10 +1679,12 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
1595 if (err) 1679 if (err)
1596 goto out_release; 1680 goto out_release;
1597 1681
1598 err = write_head(c, BASEHD, xent, len, &lnum, &xent_offs, sync); 1682 err = write_head(c, BASEHD, xent, write_len, &lnum, &xent_offs, sync);
1599 if (!sync && !err) 1683 if (!sync && !err)
1600 ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, host->i_ino); 1684 ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, host->i_ino);
1601 release_head(c, BASEHD); 1685 release_head(c, BASEHD);
1686
1687 ubifs_add_auth_dirt(c, lnum);
1602 kfree(xent); 1688 kfree(xent);
1603 if (err) 1689 if (err)
1604 goto out_ro; 1690 goto out_ro;
@@ -1680,6 +1766,8 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode,
1680 aligned_len1 = ALIGN(len1, 8); 1766 aligned_len1 = ALIGN(len1, 8);
1681 aligned_len = aligned_len1 + ALIGN(len2, 8); 1767 aligned_len = aligned_len1 + ALIGN(len2, 8);
1682 1768
1769 aligned_len += ubifs_auth_node_sz(c);
1770
1683 ino = kzalloc(aligned_len, GFP_NOFS); 1771 ino = kzalloc(aligned_len, GFP_NOFS);
1684 if (!ino) 1772 if (!ino)
1685 return -ENOMEM; 1773 return -ENOMEM;
@@ -1709,6 +1797,8 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode,
1709 if (err) 1797 if (err)
1710 goto out_ro; 1798 goto out_ro;
1711 1799
1800 ubifs_add_auth_dirt(c, lnum);
1801
1712 ino_key_init(c, &key, host->i_ino); 1802 ino_key_init(c, &key, host->i_ino);
1713 err = ubifs_tnc_add(c, &key, lnum, offs, len1, hash_host); 1803 err = ubifs_tnc_add(c, &key, lnum, offs, len1, hash_host);
1714 if (err) 1804 if (err)
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index 86b0828f5499..15fd854149bb 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -236,6 +236,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
236 bud->lnum = lnum; 236 bud->lnum = lnum;
237 bud->start = offs; 237 bud->start = offs;
238 bud->jhead = jhead; 238 bud->jhead = jhead;
239 bud->log_hash = NULL;
239 240
240 ref->ch.node_type = UBIFS_REF_NODE; 241 ref->ch.node_type = UBIFS_REF_NODE;
241 ref->lnum = cpu_to_le32(bud->lnum); 242 ref->lnum = cpu_to_le32(bud->lnum);
@@ -275,6 +276,14 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
275 if (err) 276 if (err)
276 goto out_unlock; 277 goto out_unlock;
277 278
279 err = ubifs_shash_update(c, c->log_hash, ref, UBIFS_REF_NODE_SZ);
280 if (err)
281 goto out_unlock;
282
283 err = ubifs_shash_copy_state(c, c->log_hash, c->jheads[jhead].log_hash);
284 if (err)
285 goto out_unlock;
286
278 c->lhead_offs += c->ref_node_alsz; 287 c->lhead_offs += c->ref_node_alsz;
279 288
280 ubifs_add_bud(c, bud); 289 ubifs_add_bud(c, bud);
@@ -377,6 +386,14 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum)
377 cs->cmt_no = cpu_to_le64(c->cmt_no); 386 cs->cmt_no = cpu_to_le64(c->cmt_no);
378 ubifs_prepare_node(c, cs, UBIFS_CS_NODE_SZ, 0); 387 ubifs_prepare_node(c, cs, UBIFS_CS_NODE_SZ, 0);
379 388
389 err = ubifs_shash_init(c, c->log_hash);
390 if (err)
391 goto out;
392
393 err = ubifs_shash_update(c, c->log_hash, cs, UBIFS_CS_NODE_SZ);
394 if (err < 0)
395 goto out;
396
380 /* 397 /*
381 * Note, we do not lock 'c->log_mutex' because this is the commit start 398 * Note, we do not lock 'c->log_mutex' because this is the commit start
382 * phase and we are exclusively using the log. And we do not lock 399 * phase and we are exclusively using the log. And we do not lock
@@ -402,6 +419,12 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum)
402 419
403 ubifs_prepare_node(c, ref, UBIFS_REF_NODE_SZ, 0); 420 ubifs_prepare_node(c, ref, UBIFS_REF_NODE_SZ, 0);
404 len += UBIFS_REF_NODE_SZ; 421 len += UBIFS_REF_NODE_SZ;
422
423 err = ubifs_shash_update(c, c->log_hash, ref,
424 UBIFS_REF_NODE_SZ);
425 if (err)
426 goto out;
427 ubifs_shash_copy_state(c, c->log_hash, c->jheads[i].log_hash);
405 } 428 }
406 429
407 ubifs_pad(c, buf + len, ALIGN(len, c->min_io_size) - len); 430 ubifs_pad(c, buf + len, ALIGN(len, c->min_io_size) - len);
@@ -516,6 +539,7 @@ int ubifs_log_post_commit(struct ubifs_info *c, int old_ltail_lnum)
516 if (err) 539 if (err)
517 return err; 540 return err;
518 list_del(&bud->list); 541 list_del(&bud->list);
542 kfree(bud->log_hash);
519 kfree(bud); 543 kfree(bud);
520 } 544 }
521 mutex_lock(&c->log_mutex); 545 mutex_lock(&c->log_mutex);
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 1c6ceb6265aa..db489d93439c 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -666,6 +666,8 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
666 old_size, new_size); 666 old_size, new_size);
667 break; 667 break;
668 } 668 }
669 case UBIFS_AUTH_NODE:
670 break;
669 default: 671 default:
670 ubifs_err(c, "unexpected node type %d in bud LEB %d:%d", 672 ubifs_err(c, "unexpected node type %d in bud LEB %d:%d",
671 snod->type, lnum, snod->offs); 673 snod->type, lnum, snod->offs);
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 0194e3c0853f..2722ca077d23 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -817,6 +817,9 @@ static int alloc_wbufs(struct ubifs_info *c)
817 c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback; 817 c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback;
818 c->jheads[i].wbuf.jhead = i; 818 c->jheads[i].wbuf.jhead = i;
819 c->jheads[i].grouped = 1; 819 c->jheads[i].grouped = 1;
820 c->jheads[i].log_hash = ubifs_hash_get_desc(c);
821 if (IS_ERR(c->jheads[i].log_hash))
822 goto out;
820 } 823 }
821 824
822 /* 825 /*
@@ -827,6 +830,12 @@ static int alloc_wbufs(struct ubifs_info *c)
827 c->jheads[GCHD].grouped = 0; 830 c->jheads[GCHD].grouped = 0;
828 831
829 return 0; 832 return 0;
833
834out:
835 while (i--)
836 kfree(c->jheads[i].log_hash);
837
838 return err;
830} 839}
831 840
832/** 841/**
@@ -841,6 +850,7 @@ static void free_wbufs(struct ubifs_info *c)
841 for (i = 0; i < c->jhead_cnt; i++) { 850 for (i = 0; i < c->jhead_cnt; i++) {
842 kfree(c->jheads[i].wbuf.buf); 851 kfree(c->jheads[i].wbuf.buf);
843 kfree(c->jheads[i].wbuf.inodes); 852 kfree(c->jheads[i].wbuf.inodes);
853 kfree(c->jheads[i].log_hash);
844 } 854 }
845 kfree(c->jheads); 855 kfree(c->jheads);
846 c->jheads = NULL; 856 c->jheads = NULL;
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 67bfd58d28d4..600a25b93a80 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -717,6 +717,7 @@ struct ubifs_wbuf {
717 * @jhead: journal head number this bud belongs to 717 * @jhead: journal head number this bud belongs to
718 * @list: link in the list buds belonging to the same journal head 718 * @list: link in the list buds belonging to the same journal head
719 * @rb: link in the tree of all buds 719 * @rb: link in the tree of all buds
720 * @log_hash: the log hash from the commit start node up to this bud
720 */ 721 */
721struct ubifs_bud { 722struct ubifs_bud {
722 int lnum; 723 int lnum;
@@ -724,6 +725,7 @@ struct ubifs_bud {
724 int jhead; 725 int jhead;
725 struct list_head list; 726 struct list_head list;
726 struct rb_node rb; 727 struct rb_node rb;
728 struct shash_desc *log_hash;
727}; 729};
728 730
729/** 731/**
@@ -731,6 +733,7 @@ struct ubifs_bud {
731 * @wbuf: head's write-buffer 733 * @wbuf: head's write-buffer
732 * @buds_list: list of bud LEBs belonging to this journal head 734 * @buds_list: list of bud LEBs belonging to this journal head
733 * @grouped: non-zero if UBIFS groups nodes when writing to this journal head 735 * @grouped: non-zero if UBIFS groups nodes when writing to this journal head
736 * @log_hash: the log hash from the commit start node up to this journal head
734 * 737 *
735 * Note, the @buds list is protected by the @c->buds_lock. 738 * Note, the @buds list is protected by the @c->buds_lock.
736 */ 739 */
@@ -738,6 +741,7 @@ struct ubifs_jhead {
738 struct ubifs_wbuf wbuf; 741 struct ubifs_wbuf wbuf;
739 struct list_head buds_list; 742 struct list_head buds_list;
740 unsigned int grouped:1; 743 unsigned int grouped:1;
744 struct shash_desc *log_hash;
741}; 745};
742 746
743/** 747/**
@@ -1236,6 +1240,8 @@ struct ubifs_debug_info;
1236 * @auth_key_name: the authentication key name 1240 * @auth_key_name: the authentication key name
1237 * @auth_hash_name: the name of the hash algorithm used for authentication 1241 * @auth_hash_name: the name of the hash algorithm used for authentication
1238 * @auth_hash_algo: the authentication hash used for this fs 1242 * @auth_hash_algo: the authentication hash used for this fs
1243 * @log_hash: the log hash from the commit start node up to the latest reference
1244 * node.
1239 * 1245 *
1240 * @empty: %1 if the UBI device is empty 1246 * @empty: %1 if the UBI device is empty
1241 * @need_recovery: %1 if the file-system needs recovery 1247 * @need_recovery: %1 if the file-system needs recovery
@@ -1478,6 +1484,8 @@ struct ubifs_info {
1478 char *auth_hash_name; 1484 char *auth_hash_name;
1479 enum hash_algo auth_hash_algo; 1485 enum hash_algo auth_hash_algo;
1480 1486
1487 struct shash_desc *log_hash;
1488
1481 /* The below fields are used only during mounting and re-mounting */ 1489 /* The below fields are used only during mounting and re-mounting */
1482 unsigned int empty:1; 1490 unsigned int empty:1;
1483 unsigned int need_recovery:1; 1491 unsigned int need_recovery:1;