@@ -544,6 +544,7 @@ struct ovl_copy_up_ctx {
544
544
bool origin ;
545
545
bool indexed ;
546
546
bool metacopy ;
547
+ bool metacopy_digest ;
547
548
};
548
549
549
550
static int ovl_link_up (struct ovl_copy_up_ctx * c )
@@ -641,8 +642,20 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp)
641
642
}
642
643
643
644
if (c -> metacopy ) {
644
- err = ovl_check_setxattr (ofs , temp , OVL_XATTR_METACOPY ,
645
- NULL , 0 , - EOPNOTSUPP );
645
+ struct path lowerdatapath ;
646
+ struct ovl_metacopy metacopy_data = OVL_METACOPY_INIT ;
647
+
648
+ ovl_path_lowerdata (c -> dentry , & lowerdatapath );
649
+ if (WARN_ON_ONCE (lowerdatapath .dentry == NULL ))
650
+ return - EIO ;
651
+ err = ovl_get_verity_digest (ofs , & lowerdatapath , & metacopy_data );
652
+ if (err )
653
+ return err ;
654
+
655
+ if (metacopy_data .digest_algo )
656
+ c -> metacopy_digest = true;
657
+
658
+ err = ovl_set_metacopy_xattr (ofs , temp , & metacopy_data );
646
659
if (err )
647
660
return err ;
648
661
}
@@ -751,9 +764,15 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c)
751
764
if (err )
752
765
goto cleanup ;
753
766
754
- if (!c -> metacopy )
755
- ovl_set_upperdata (d_inode (c -> dentry ));
756
767
inode = d_inode (c -> dentry );
768
+ if (c -> metacopy_digest )
769
+ ovl_set_flag (OVL_HAS_DIGEST , inode );
770
+ else
771
+ ovl_clear_flag (OVL_HAS_DIGEST , inode );
772
+ ovl_clear_flag (OVL_VERIFIED_DIGEST , inode );
773
+
774
+ if (!c -> metacopy )
775
+ ovl_set_upperdata (inode );
757
776
ovl_inode_update (inode , temp );
758
777
if (S_ISDIR (inode -> i_mode ))
759
778
ovl_set_flag (OVL_WHITEOUTS , inode );
@@ -813,6 +832,12 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c)
813
832
if (err )
814
833
goto out_fput ;
815
834
835
+ if (c -> metacopy_digest )
836
+ ovl_set_flag (OVL_HAS_DIGEST , d_inode (c -> dentry ));
837
+ else
838
+ ovl_clear_flag (OVL_HAS_DIGEST , d_inode (c -> dentry ));
839
+ ovl_clear_flag (OVL_VERIFIED_DIGEST , d_inode (c -> dentry ));
840
+
816
841
if (!c -> metacopy )
817
842
ovl_set_upperdata (d_inode (c -> dentry ));
818
843
ovl_inode_update (d_inode (c -> dentry ), dget (temp ));
@@ -918,6 +943,19 @@ static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode,
918
943
if (flags && ((OPEN_FMODE (flags ) & FMODE_WRITE ) || (flags & O_TRUNC )))
919
944
return false;
920
945
946
+ /* Fall back to full copy if no fsverity on source data and we require verity */
947
+ if (ofs -> config .verity_mode == OVL_VERITY_REQUIRE ) {
948
+ struct path lowerdata ;
949
+
950
+ ovl_path_lowerdata (dentry , & lowerdata );
951
+
952
+ if (WARN_ON_ONCE (lowerdata .dentry == NULL ) ||
953
+ ovl_ensure_verity_loaded (& lowerdata ) ||
954
+ !fsverity_active (d_inode (lowerdata .dentry ))) {
955
+ return false;
956
+ }
957
+ }
958
+
921
959
return true;
922
960
}
923
961
@@ -984,6 +1022,8 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c)
984
1022
if (err )
985
1023
goto out_free ;
986
1024
1025
+ ovl_clear_flag (OVL_HAS_DIGEST , d_inode (c -> dentry ));
1026
+ ovl_clear_flag (OVL_VERIFIED_DIGEST , d_inode (c -> dentry ));
987
1027
ovl_set_upperdata (d_inode (c -> dentry ));
988
1028
out_free :
989
1029
kfree (capability );
0 commit comments