Re: [PATCH 15/25] ubifs: Add auth nodes to garbage collector journal head
On Mon, Aug 27, 2018 at 10:51:56PM +0200, Richard Weinberger wrote: > Am Mittwoch, 4. Juli 2018, 14:41:27 CEST schrieb Sascha Hauer: > > To be able to authenticate the garbage collector journal head add > > authentication nodes to the buds the garbage collector creates. > > > > Signed-off-by: Sascha Hauer > > --- > > fs/ubifs/gc.c | 37 ++--- > > 1 file changed, 34 insertions(+), 3 deletions(-) > > > > diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c > > index ac3a3f7c6a6e..8feeeb12b6ed 100644 > > --- a/fs/ubifs/gc.c > > +++ b/fs/ubifs/gc.c > > @@ -365,12 +365,13 @@ static int move_nodes(struct ubifs_info *c, struct > > ubifs_scan_leb *sleb) > > > > /* Write nodes to their new location. Use the first-fit strategy */ > > while (1) { > > - int avail; > > + int avail, moved = 0; > > struct ubifs_scan_node *snod, *tmp; > > > > /* Move data nodes */ > > list_for_each_entry_safe(snod, tmp, >nodes, list) { > > - avail = c->leb_size - wbuf->offs - wbuf->used; > > + avail = c->leb_size - wbuf->offs - wbuf->used - > > + ubifs_auth_node_sz(c); > > if (snod->len > avail) > > /* > > * Do not skip data nodes in order to optimize > > @@ -378,14 +379,19 @@ static int move_nodes(struct ubifs_info *c, struct > > ubifs_scan_leb *sleb) > > */ > > break; > > > > + ubifs_shash_update(c, c->jheads[GCHD].log_hash, > > + snod->node, snod->len); > > + > > err = move_node(c, sleb, snod, wbuf); > > if (err) > > goto out; > > + moved = 1; > > } > > > > /* Move non-data nodes */ > > list_for_each_entry_safe(snod, tmp, , list) { > > - avail = c->leb_size - wbuf->offs - wbuf->used; > > + avail = c->leb_size - wbuf->offs - wbuf->used - > > + ubifs_auth_node_sz(c); > > if (avail < min) > > break; > > > > @@ -403,7 +409,32 @@ static int move_nodes(struct ubifs_info *c, struct > > ubifs_scan_leb *sleb) > > continue; > > } > > > > + ubifs_shash_update(c, c->jheads[GCHD].log_hash, > > + snod->node, snod->len); > > + > > err = move_node(c, sleb, snod, wbuf); > > + if (err) > > + goto out; > > + moved = 1; > > + } > > + > > + if (ubifs_authenticated(c) && moved) { > > + struct ubifs_auth_node *auth; > > + > > + auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS); > > + if (!auth) { > > + err = -ENOMEM; > > + goto out; > > + } > > + > > + ubifs_prepare_auth_node(c, auth, > > + c->jheads[GCHD].log_hash); > > ubifs_prepare_auth_node() does a crypto_shash_final(), check. > But the overall "hash life cycle" is not 100% clear to me. > For example, does move_nodes() assume that the hash is initialized > or is it allowed that an crypto_shash_update() happened before? move_nodes() assumes that the hash is - initialized - updated with the commit start node - updated with all reference nodes before the one that point into the current LEB - updated with the reference node pointing to the current LEB To make that more clear here is the overall life cycle of the auth hashes: Everything starts in ubifs_log_start_commit(). We initialize the global log hash and update it with the commit start node: > ubifs_shash_init(c->log_hash); > ubifs_shash_update(c, c->log_hash, cs, UBIFS_CS_NODE_SZ); Afterwards still in ubifs_log_start_commit() ref nodes are created for each journal head. We update the global log hash with the reference nodes and copy the current state into each journal heads log hash: > for (i = 0; i < c->jhead_cnt; i++) { > ubifs_prepare_node(c, ref, UBIFS_REF_NODE_SZ, 0); > ubifs_shash_update(c, c->log_hash, ref, UBIFS_REF_NODE_SZ); > ubifs_shash_copy_state(c, c->log_hash, c->jheads[i].log_hash); > } >From here on each journal head has its own log hash derived from the global log hash. Whenever something is written to a journal head we update the hash of that journal head. For the garbage collector this happens in gc.c move_nodes(): > for_each_node_in_gc_leb() > ubifs_shash_update(c, c->jheads[GCHD].log_hash, snod->node, > snod->len); For the base head and data head this happens
Re: [PATCH 15/25] ubifs: Add auth nodes to garbage collector journal head
On Mon, Aug 27, 2018 at 10:51:56PM +0200, Richard Weinberger wrote: > Am Mittwoch, 4. Juli 2018, 14:41:27 CEST schrieb Sascha Hauer: > > To be able to authenticate the garbage collector journal head add > > authentication nodes to the buds the garbage collector creates. > > > > Signed-off-by: Sascha Hauer > > --- > > fs/ubifs/gc.c | 37 ++--- > > 1 file changed, 34 insertions(+), 3 deletions(-) > > > > diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c > > index ac3a3f7c6a6e..8feeeb12b6ed 100644 > > --- a/fs/ubifs/gc.c > > +++ b/fs/ubifs/gc.c > > @@ -365,12 +365,13 @@ static int move_nodes(struct ubifs_info *c, struct > > ubifs_scan_leb *sleb) > > > > /* Write nodes to their new location. Use the first-fit strategy */ > > while (1) { > > - int avail; > > + int avail, moved = 0; > > struct ubifs_scan_node *snod, *tmp; > > > > /* Move data nodes */ > > list_for_each_entry_safe(snod, tmp, >nodes, list) { > > - avail = c->leb_size - wbuf->offs - wbuf->used; > > + avail = c->leb_size - wbuf->offs - wbuf->used - > > + ubifs_auth_node_sz(c); > > if (snod->len > avail) > > /* > > * Do not skip data nodes in order to optimize > > @@ -378,14 +379,19 @@ static int move_nodes(struct ubifs_info *c, struct > > ubifs_scan_leb *sleb) > > */ > > break; > > > > + ubifs_shash_update(c, c->jheads[GCHD].log_hash, > > + snod->node, snod->len); > > + > > err = move_node(c, sleb, snod, wbuf); > > if (err) > > goto out; > > + moved = 1; > > } > > > > /* Move non-data nodes */ > > list_for_each_entry_safe(snod, tmp, , list) { > > - avail = c->leb_size - wbuf->offs - wbuf->used; > > + avail = c->leb_size - wbuf->offs - wbuf->used - > > + ubifs_auth_node_sz(c); > > if (avail < min) > > break; > > > > @@ -403,7 +409,32 @@ static int move_nodes(struct ubifs_info *c, struct > > ubifs_scan_leb *sleb) > > continue; > > } > > > > + ubifs_shash_update(c, c->jheads[GCHD].log_hash, > > + snod->node, snod->len); > > + > > err = move_node(c, sleb, snod, wbuf); > > + if (err) > > + goto out; > > + moved = 1; > > + } > > + > > + if (ubifs_authenticated(c) && moved) { > > + struct ubifs_auth_node *auth; > > + > > + auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS); > > + if (!auth) { > > + err = -ENOMEM; > > + goto out; > > + } > > + > > + ubifs_prepare_auth_node(c, auth, > > + c->jheads[GCHD].log_hash); > > ubifs_prepare_auth_node() does a crypto_shash_final(), check. > But the overall "hash life cycle" is not 100% clear to me. > For example, does move_nodes() assume that the hash is initialized > or is it allowed that an crypto_shash_update() happened before? move_nodes() assumes that the hash is - initialized - updated with the commit start node - updated with all reference nodes before the one that point into the current LEB - updated with the reference node pointing to the current LEB To make that more clear here is the overall life cycle of the auth hashes: Everything starts in ubifs_log_start_commit(). We initialize the global log hash and update it with the commit start node: > ubifs_shash_init(c->log_hash); > ubifs_shash_update(c, c->log_hash, cs, UBIFS_CS_NODE_SZ); Afterwards still in ubifs_log_start_commit() ref nodes are created for each journal head. We update the global log hash with the reference nodes and copy the current state into each journal heads log hash: > for (i = 0; i < c->jhead_cnt; i++) { > ubifs_prepare_node(c, ref, UBIFS_REF_NODE_SZ, 0); > ubifs_shash_update(c, c->log_hash, ref, UBIFS_REF_NODE_SZ); > ubifs_shash_copy_state(c, c->log_hash, c->jheads[i].log_hash); > } >From here on each journal head has its own log hash derived from the global log hash. Whenever something is written to a journal head we update the hash of that journal head. For the garbage collector this happens in gc.c move_nodes(): > for_each_node_in_gc_leb() > ubifs_shash_update(c, c->jheads[GCHD].log_hash, snod->node, > snod->len); For the base head and data head this happens
Re: [PATCH 15/25] ubifs: Add auth nodes to garbage collector journal head
Am Mittwoch, 4. Juli 2018, 14:41:27 CEST schrieb Sascha Hauer: > To be able to authenticate the garbage collector journal head add > authentication nodes to the buds the garbage collector creates. > > Signed-off-by: Sascha Hauer > --- > fs/ubifs/gc.c | 37 ++--- > 1 file changed, 34 insertions(+), 3 deletions(-) > > diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c > index ac3a3f7c6a6e..8feeeb12b6ed 100644 > --- a/fs/ubifs/gc.c > +++ b/fs/ubifs/gc.c > @@ -365,12 +365,13 @@ static int move_nodes(struct ubifs_info *c, struct > ubifs_scan_leb *sleb) > > /* Write nodes to their new location. Use the first-fit strategy */ > while (1) { > - int avail; > + int avail, moved = 0; > struct ubifs_scan_node *snod, *tmp; > > /* Move data nodes */ > list_for_each_entry_safe(snod, tmp, >nodes, list) { > - avail = c->leb_size - wbuf->offs - wbuf->used; > + avail = c->leb_size - wbuf->offs - wbuf->used - > + ubifs_auth_node_sz(c); > if (snod->len > avail) > /* >* Do not skip data nodes in order to optimize > @@ -378,14 +379,19 @@ static int move_nodes(struct ubifs_info *c, struct > ubifs_scan_leb *sleb) >*/ > break; > > + ubifs_shash_update(c, c->jheads[GCHD].log_hash, > +snod->node, snod->len); > + > err = move_node(c, sleb, snod, wbuf); > if (err) > goto out; > + moved = 1; > } > > /* Move non-data nodes */ > list_for_each_entry_safe(snod, tmp, , list) { > - avail = c->leb_size - wbuf->offs - wbuf->used; > + avail = c->leb_size - wbuf->offs - wbuf->used - > + ubifs_auth_node_sz(c); > if (avail < min) > break; > > @@ -403,7 +409,32 @@ static int move_nodes(struct ubifs_info *c, struct > ubifs_scan_leb *sleb) > continue; > } > > + ubifs_shash_update(c, c->jheads[GCHD].log_hash, > +snod->node, snod->len); > + > err = move_node(c, sleb, snod, wbuf); > + if (err) > + goto out; > + moved = 1; > + } > + > + if (ubifs_authenticated(c) && moved) { > + struct ubifs_auth_node *auth; > + > + auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS); > + if (!auth) { > + err = -ENOMEM; > + goto out; > + } > + > + ubifs_prepare_auth_node(c, auth, > + c->jheads[GCHD].log_hash); ubifs_prepare_auth_node() does a crypto_shash_final(), check. But the overall "hash life cycle" is not 100% clear to me. For example, does move_nodes() assume that the hash is initialized or is it allowed that an crypto_shash_update() happened before? Thanks, //richard
Re: [PATCH 15/25] ubifs: Add auth nodes to garbage collector journal head
Am Mittwoch, 4. Juli 2018, 14:41:27 CEST schrieb Sascha Hauer: > To be able to authenticate the garbage collector journal head add > authentication nodes to the buds the garbage collector creates. > > Signed-off-by: Sascha Hauer > --- > fs/ubifs/gc.c | 37 ++--- > 1 file changed, 34 insertions(+), 3 deletions(-) > > diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c > index ac3a3f7c6a6e..8feeeb12b6ed 100644 > --- a/fs/ubifs/gc.c > +++ b/fs/ubifs/gc.c > @@ -365,12 +365,13 @@ static int move_nodes(struct ubifs_info *c, struct > ubifs_scan_leb *sleb) > > /* Write nodes to their new location. Use the first-fit strategy */ > while (1) { > - int avail; > + int avail, moved = 0; > struct ubifs_scan_node *snod, *tmp; > > /* Move data nodes */ > list_for_each_entry_safe(snod, tmp, >nodes, list) { > - avail = c->leb_size - wbuf->offs - wbuf->used; > + avail = c->leb_size - wbuf->offs - wbuf->used - > + ubifs_auth_node_sz(c); > if (snod->len > avail) > /* >* Do not skip data nodes in order to optimize > @@ -378,14 +379,19 @@ static int move_nodes(struct ubifs_info *c, struct > ubifs_scan_leb *sleb) >*/ > break; > > + ubifs_shash_update(c, c->jheads[GCHD].log_hash, > +snod->node, snod->len); > + > err = move_node(c, sleb, snod, wbuf); > if (err) > goto out; > + moved = 1; > } > > /* Move non-data nodes */ > list_for_each_entry_safe(snod, tmp, , list) { > - avail = c->leb_size - wbuf->offs - wbuf->used; > + avail = c->leb_size - wbuf->offs - wbuf->used - > + ubifs_auth_node_sz(c); > if (avail < min) > break; > > @@ -403,7 +409,32 @@ static int move_nodes(struct ubifs_info *c, struct > ubifs_scan_leb *sleb) > continue; > } > > + ubifs_shash_update(c, c->jheads[GCHD].log_hash, > +snod->node, snod->len); > + > err = move_node(c, sleb, snod, wbuf); > + if (err) > + goto out; > + moved = 1; > + } > + > + if (ubifs_authenticated(c) && moved) { > + struct ubifs_auth_node *auth; > + > + auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS); > + if (!auth) { > + err = -ENOMEM; > + goto out; > + } > + > + ubifs_prepare_auth_node(c, auth, > + c->jheads[GCHD].log_hash); ubifs_prepare_auth_node() does a crypto_shash_final(), check. But the overall "hash life cycle" is not 100% clear to me. For example, does move_nodes() assume that the hash is initialized or is it allowed that an crypto_shash_update() happened before? Thanks, //richard
[PATCH 15/25] ubifs: Add auth nodes to garbage collector journal head
To be able to authenticate the garbage collector journal head add authentication nodes to the buds the garbage collector creates. Signed-off-by: Sascha Hauer --- fs/ubifs/gc.c | 37 ++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index ac3a3f7c6a6e..8feeeb12b6ed 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c @@ -365,12 +365,13 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) /* Write nodes to their new location. Use the first-fit strategy */ while (1) { - int avail; + int avail, moved = 0; struct ubifs_scan_node *snod, *tmp; /* Move data nodes */ list_for_each_entry_safe(snod, tmp, >nodes, list) { - avail = c->leb_size - wbuf->offs - wbuf->used; + avail = c->leb_size - wbuf->offs - wbuf->used - + ubifs_auth_node_sz(c); if (snod->len > avail) /* * Do not skip data nodes in order to optimize @@ -378,14 +379,19 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) */ break; + ubifs_shash_update(c, c->jheads[GCHD].log_hash, + snod->node, snod->len); + err = move_node(c, sleb, snod, wbuf); if (err) goto out; + moved = 1; } /* Move non-data nodes */ list_for_each_entry_safe(snod, tmp, , list) { - avail = c->leb_size - wbuf->offs - wbuf->used; + avail = c->leb_size - wbuf->offs - wbuf->used - + ubifs_auth_node_sz(c); if (avail < min) break; @@ -403,7 +409,32 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) continue; } + ubifs_shash_update(c, c->jheads[GCHD].log_hash, + snod->node, snod->len); + err = move_node(c, sleb, snod, wbuf); + if (err) + goto out; + moved = 1; + } + + if (ubifs_authenticated(c) && moved) { + struct ubifs_auth_node *auth; + + auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS); + if (!auth) { + err = -ENOMEM; + goto out; + } + + ubifs_prepare_auth_node(c, auth, + c->jheads[GCHD].log_hash); + + err = ubifs_wbuf_write_nolock(wbuf, auth, + ubifs_auth_node_sz(c)); + + kfree(auth); + if (err) goto out; } -- 2.18.0
[PATCH 15/25] ubifs: Add auth nodes to garbage collector journal head
To be able to authenticate the garbage collector journal head add authentication nodes to the buds the garbage collector creates. Signed-off-by: Sascha Hauer --- fs/ubifs/gc.c | 37 ++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index ac3a3f7c6a6e..8feeeb12b6ed 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c @@ -365,12 +365,13 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) /* Write nodes to their new location. Use the first-fit strategy */ while (1) { - int avail; + int avail, moved = 0; struct ubifs_scan_node *snod, *tmp; /* Move data nodes */ list_for_each_entry_safe(snod, tmp, >nodes, list) { - avail = c->leb_size - wbuf->offs - wbuf->used; + avail = c->leb_size - wbuf->offs - wbuf->used - + ubifs_auth_node_sz(c); if (snod->len > avail) /* * Do not skip data nodes in order to optimize @@ -378,14 +379,19 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) */ break; + ubifs_shash_update(c, c->jheads[GCHD].log_hash, + snod->node, snod->len); + err = move_node(c, sleb, snod, wbuf); if (err) goto out; + moved = 1; } /* Move non-data nodes */ list_for_each_entry_safe(snod, tmp, , list) { - avail = c->leb_size - wbuf->offs - wbuf->used; + avail = c->leb_size - wbuf->offs - wbuf->used - + ubifs_auth_node_sz(c); if (avail < min) break; @@ -403,7 +409,32 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) continue; } + ubifs_shash_update(c, c->jheads[GCHD].log_hash, + snod->node, snod->len); + err = move_node(c, sleb, snod, wbuf); + if (err) + goto out; + moved = 1; + } + + if (ubifs_authenticated(c) && moved) { + struct ubifs_auth_node *auth; + + auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS); + if (!auth) { + err = -ENOMEM; + goto out; + } + + ubifs_prepare_auth_node(c, auth, + c->jheads[GCHD].log_hash); + + err = ubifs_wbuf_write_nolock(wbuf, auth, + ubifs_auth_node_sz(c)); + + kfree(auth); + if (err) goto out; } -- 2.18.0