Various structures in a dump file optionally contain a checksum, but
the code to compute and validate the checksum has not been enabled.
The checksum code has a negligible performance impact and so this
patch enables the checksum code unconditionally. Also:
- make sure all header sizes are multiples of 4 bytes
(a requirement of the checksum routine)
- zero structures to ensure internal padding has a known value
- fix a bug in dump_extattr_buildrecord() which checksummed
the wrong header structure
- add calc_checksum() and is_checksum_valid() routines to
cut down on duplicate code
Signed-off-by: Bill Kendall <wkendall@xxxxxxx>
---
Changes since v2:
- Add an ASSERT in the checksum routines to enforce the
multiple of 4 requirement, rather than checking at
init (which may not catch all checksum users).
- Remove unnecessary cast from void * to u_int32_t *.
- Calculate endp different to avoid having to cast to
void * or char *.
common/content_inode.h | 27 ++++++++++++++++
dump/content.c | 78 +++++++----------------------------------------
restore/Makefile | 2 +-
restore/content.c | 40 ++----------------------
4 files changed, 44 insertions(+), 103 deletions(-)
diff --git a/common/content_inode.h b/common/content_inode.h
index 479fdfc..0f21840 100644
--- a/common/content_inode.h
+++ b/common/content_inode.h
@@ -347,4 +347,31 @@ typedef struct extattrhdr extattrhdr_t;
/* a linux "secure" mode attribute
*/
+/* Routines for calculating and validating checksums on xfsdump headers.
+ * The header length must be an integral number of u_int32_t's.
+ */
+static inline u_int32_t
+calc_checksum(void *bufp, size_t len)
+{
+ u_int32_t sum = 0;
+ u_int32_t *sump = bufp;
+ u_int32_t *endp = sump + len / sizeof(u_int32_t);
+ ASSERT(len % sizeof(u_int32_t) == 0);
+ while (sump < endp)
+ sum += *sump++;
+ return ~sum + 1;
+}
+
+static inline bool_t
+is_checksum_valid(void *bufp, size_t len)
+{
+ u_int32_t sum = 0;
+ u_int32_t *sump = bufp;
+ u_int32_t *endp = sump + len / sizeof(u_int32_t);
+ ASSERT(len % sizeof(u_int32_t) == 0);
+ while (sump < endp)
+ sum += *sump++;
+ return sum == 0 ? BOOL_TRUE : BOOL_FALSE;
+}
+
#endif /* CONTENT_INODE_H */
diff --git a/dump/content.c b/dump/content.c
index 9905c88..0b1eb31 100644
--- a/dump/content.c
+++ b/dump/content.c
@@ -1491,8 +1491,7 @@ baseuuidbypass:
var_skip( &fsid, inomap_skip );
/* fill in write header template content info. always produce
- * an inomap and dir dump for each media file. flag the checksums
- * available if so compiled (see -D...CHECKSUM in Makefile).
+ * an inomap and dir dump for each media file.
*/
ASSERT( sizeof( cwhdrtemplatep->ch_specific ) >= sizeof(
*scwhdrtemplatep ));
scwhdrtemplatep->cih_mediafiletype = CIH_MEDIAFILETYPE_DATA;
@@ -1506,15 +1505,9 @@ baseuuidbypass:
if ( sc_inv_updatepr ) {
scwhdrtemplatep->cih_dumpattr |= CIH_DUMPATTR_INVENTORY;
}
-#ifdef FILEHDR_CHECKSUM
scwhdrtemplatep->cih_dumpattr |= CIH_DUMPATTR_FILEHDR_CHECKSUM;
-#endif /* FILEHDR_CHECKSUM */
-#ifdef EXTENTHDR_CHECKSUM
scwhdrtemplatep->cih_dumpattr |= CIH_DUMPATTR_EXTENTHDR_CHECKSUM;
-#endif /* EXTENTHDR_CHECKSUM */
-#ifdef DIRENTHDR_CHECKSUM
scwhdrtemplatep->cih_dumpattr |= CIH_DUMPATTR_DIRENTHDR_CHECKSUM;
-#endif /* DIRENTHDR_CHECKSUM */
scwhdrtemplatep->cih_dumpattr |= CIH_DUMPATTR_DIRENTHDR_GEN;
if ( sc_incrpr ) {
scwhdrtemplatep->cih_dumpattr |= CIH_DUMPATTR_INCREMENTAL;
@@ -1528,10 +1521,8 @@ baseuuidbypass:
}
if ( sc_dumpextattrpr ) {
scwhdrtemplatep->cih_dumpattr |= CIH_DUMPATTR_EXTATTR;
-#ifdef EXTATTRHDR_CHECKSUM
scwhdrtemplatep->cih_dumpattr |=
CIH_DUMPATTR_EXTATTRHDR_CHECKSUM;
-#endif /* EXTATTRHDR_CHECKSUM */
}
scwhdrtemplatep->cih_rootino = sc_rootxfsstatp->bs_ino;
@@ -3743,6 +3734,8 @@ dump_extattr_buildrecord( xfs_bstat_t *statp,
namesz, namesrcp,
valuesz );
( void )strcpy( namep, namesrcp );
+
+ memset( ( void * )&tmpah, 0, sizeof( tmpah ));
tmpah.ah_sz = recsz;
ASSERT( EXTATTRHDR_SZ + namesz < UINT16MAX );
tmpah.ah_valoff = ( u_int16_t )( EXTATTRHDR_SZ + namesz );
@@ -3750,17 +3743,8 @@ dump_extattr_buildrecord( xfs_bstat_t *statp,
(( flag & ATTR_ROOT ) ? EXTATTRHDR_FLAGS_ROOT :
(( flag & ATTR_SECURE ) ? EXTATTRHDR_FLAGS_SECURE : 0));
tmpah.ah_valsz = valuesz;
- tmpah.ah_checksum = 0;
-#ifdef EXTATTRHDR_CHECKSUM
- {
- register u_int32_t *sump = ( u_int32_t * )ahdrp;
- register u_int32_t *endp = ( u_int32_t * )( ahdrp + 1 );
- register u_int32_t sum;
tmpah.ah_flags |= EXTATTRHDR_FLAGS_CHECKSUM;
- for ( sum = 0 ; sump < endp ; sum += *sump++ ) ;
- tmpah.ah_checksum = ~sum + 1;
- }
-#endif /* EXTATTRHDR_CHECKSUM */
+ tmpah.ah_checksum = calc_checksum( &tmpah, EXTATTRHDR_SZ );
xlate_extattrhdr(ahdrp, &tmpah, -1);
*valuepp = valuep;
@@ -3782,23 +3766,13 @@ dump_extattrhdr( drive_t *drivep,
intgen_t rval;
rv_t rv;
+ memset( ( void * )&ahdr, 0, sizeof( ahdr ));
ahdr.ah_sz = recsz;
ASSERT( valoff < UINT16MAX );
ahdr.ah_valoff = ( u_int16_t )valoff;
- ahdr.ah_flags = ( u_int16_t )flags;
+ ahdr.ah_flags = ( u_int16_t )flags | EXTATTRHDR_FLAGS_CHECKSUM;
ahdr.ah_valsz = valsz;
- ahdr.ah_checksum = 0;
-
-#ifdef EXTATTRHDR_CHECKSUM
- {
- register u_int32_t *sump = ( u_int32_t * )&ahdr;
- register u_int32_t *endp = ( u_int32_t * )( &ahdr + 1 );
- register u_int32_t sum;
- ahdr.ah_flags |= EXTATTRHDR_FLAGS_CHECKSUM;
- for ( sum = 0 ; sump < endp ; sum += *sump++ ) ;
- ahdr.ah_checksum = ~sum + 1;
- }
-#endif /* EXTATTRHDR_CHECKSUM */
+ ahdr.ah_checksum = calc_checksum( &ahdr, EXTATTRHDR_SZ );
xlate_extattrhdr(&ahdr, &tmpahdr, 1);
rval = write_buf( ( char * )&tmpahdr,
@@ -5102,11 +5076,6 @@ dump_filehdr( drive_t *drivep,
drive_ops_t *dop = drivep->d_opsp;
register filehdr_t *fhdrp = contextp->cc_filehdrp;
filehdr_t tmpfhdrp;
-#ifdef FILEHDR_CHECKSUM
- register u_int32_t *sump = ( u_int32_t * )fhdrp;
- register u_int32_t *endp = ( u_int32_t * )( fhdrp + 1 );
- register u_int32_t sum;
-#endif /* FILEHDR_CHECKSUM */
intgen_t rval;
rv_t rv;
@@ -5118,13 +5087,8 @@ dump_filehdr( drive_t *drivep,
copy_xfs_bstat(&fhdrp->fh_stat, statp);
}
fhdrp->fh_offset = offset;
- fhdrp->fh_flags = flags;
-
-#ifdef FILEHDR_CHECKSUM
- fhdrp->fh_flags |= FILEHDR_FLAGS_CHECKSUM;
- for ( sum = 0 ; sump < endp ; sum += *sump++ ) ;
- fhdrp->fh_checksum = ~sum + 1;
-#endif /* FILEHDR_CHECKSUM */
+ fhdrp->fh_flags = flags | FILEHDR_FLAGS_CHECKSUM;
+ fhdrp->fh_checksum = calc_checksum( fhdrp, FILEHDR_SZ );
xlate_filehdr(fhdrp, &tmpfhdrp, 1);
rval = write_buf( ( char * )&tmpfhdrp,
@@ -5164,11 +5128,6 @@ dump_extenthdr( drive_t *drivep,
drive_ops_t *dop = drivep->d_opsp;
register extenthdr_t *ehdrp = contextp->cc_extenthdrp;
extenthdr_t tmpehdrp;
-#ifdef EXTENTHDR_CHECKSUM
- register u_int32_t *sump = ( u_int32_t * )ehdrp;
- register u_int32_t *endp = ( u_int32_t * )( ehdrp + 1 );
- register u_int32_t sum;
-#endif /* EXTENTHDR_CHECKSUM */
intgen_t rval;
rv_t rv;
char typestr[20];
@@ -5198,15 +5157,10 @@ dump_extenthdr( drive_t *drivep,
( void )memset( ( void * )ehdrp, 0, sizeof( *ehdrp ));
ehdrp->eh_type = type;
- ehdrp->eh_flags = flags;
+ ehdrp->eh_flags = flags | EXTENTHDR_FLAGS_CHECKSUM;
ehdrp->eh_offset = offset;
ehdrp->eh_sz = sz;
-
-#ifdef EXTENTHDR_CHECKSUM
- ehdrp->eh_flags |= EXTENTHDR_FLAGS_CHECKSUM;
- for ( sum = 0 ; sump < endp ; sum += *sump++ ) ;
- ehdrp->eh_checksum = ~sum + 1;
-#endif /* EXTENTHDR_CHECKSUM */
+ ehdrp->eh_checksum = calc_checksum( ehdrp, EXTENTHDR_SZ );
xlate_extenthdr(ehdrp, &tmpehdrp, 1);
rval = write_buf( ( char * )&tmpehdrp,
@@ -5249,11 +5203,6 @@ dump_dirent( drive_t *drivep,
direnthdr_t *tmpdhdrp;
size_t direntbufsz = contextp->cc_mdirentbufsz;
size_t sz;
-#ifdef DIRENTHDR_CHECKSUM
- register u_int32_t *sump = ( u_int32_t * )dhdrp;
- register u_int32_t *endp = ( u_int32_t * )( dhdrp + 1 );
- register u_int32_t sum;
-#endif /* DIRENTHDR_CHECKSUM */
intgen_t rval;
rv_t rv;
@@ -5290,10 +5239,7 @@ dump_dirent( drive_t *drivep,
strcpy( dhdrp->dh_name, name );
}
-#ifdef DIRENTHDR_CHECKSUM
- for ( sum = 0 ; sump < endp ; sum += *sump++ ) ;
- dhdrp->dh_checksum = ~sum + 1;
-#endif /* DIRENTHDR_CHECKSUM */
+ dhdrp->dh_checksum = calc_checksum( dhdrp, DIRENTHDR_SZ );
tmpdhdrp = malloc(sz);
xlate_direnthdr(dhdrp, tmpdhdrp, 1);
diff --git a/restore/Makefile b/restore/Makefile
index 78ecc2c..588a8f0 100644
--- a/restore/Makefile
+++ b/restore/Makefile
@@ -103,7 +103,7 @@ LLDLIBS = $(LIBUUID) $(LIBHANDLE) $(LIBATTR) $(LIBRMT)
LTDEPENDENCIES = $(LIBRMT)
LCFLAGS = -DRESTORE -DRMT -DBASED -DDOSOCKS -DINVCONVFIX -DPIPEINVFIX \
- -DEOMFIX -DSESSCPLT -DWHITEPARSE -DDIRENTHDR_CHECKSUM \
+ -DEOMFIX -DSESSCPLT -DWHITEPARSE \
-DF_FSSETDM
default: depend $(LTCOMMAND)
diff --git a/restore/content.c b/restore/content.c
index e3e4994..a278640 100644
--- a/restore/content.c
+++ b/restore/content.c
@@ -8000,11 +8000,6 @@ read_filehdr( drive_t *drivep, filehdr_t *fhdrp, bool_t
fhcs )
drive_ops_t *dop = drivep->d_opsp;
/* REFERENCED */
intgen_t nread;
-#ifdef FILEHDR_CHECKSUM
- register u_int32_t *sump = ( u_int32_t * )fhdrp;
- register u_int32_t *endp = ( u_int32_t * )( fhdrp + 1 );
- register u_int32_t sum;
-#endif /* FILEHDR_CHECKSUM */
intgen_t rval;
filehdr_t tmpfh;
@@ -8041,21 +8036,18 @@ read_filehdr( drive_t *drivep, filehdr_t *fhdrp, bool_t
fhcs )
bstatp->bs_ino,
bstatp->bs_mode );
-#ifdef FILEHDR_CHECKSUM
if ( fhcs ) {
if ( ! ( fhdrp->fh_flags & FILEHDR_FLAGS_CHECKSUM )) {
mlog( MLOG_NORMAL | MLOG_WARNING, _(
"corrupt file header\n") );
return RV_CORRUPT;
}
- for ( sum = 0 ; sump < endp ; sum += *sump++ ) ;
- if ( sum ) {
+ if ( !is_checksum_valid( fhdrp, FILEHDR_SZ )) {
mlog( MLOG_NORMAL | MLOG_WARNING, _(
"bad file header checksum\n") );
return RV_CORRUPT;
}
}
-#endif /* FILEHDR_CHECKSUM */
return RV_OK;
}
@@ -8067,11 +8059,6 @@ read_extenthdr( drive_t *drivep, extenthdr_t *ehdrp,
bool_t ehcs )
drive_ops_t *dop = drivep->d_opsp;
/* REFERENCED */
intgen_t nread;
-#ifdef EXTENTHDR_CHECKSUM
- register u_int32_t *sump = ( u_int32_t * )ehdrp;
- register u_int32_t *endp = ( u_int32_t * )( ehdrp + 1 );
- register u_int32_t sum;
-#endif /* EXTENTHDR_CHECKSUM */
intgen_t rval;
extenthdr_t tmpeh;
@@ -8108,21 +8095,18 @@ read_extenthdr( drive_t *drivep, extenthdr_t *ehdrp,
bool_t ehcs )
ehdrp->eh_type,
ehdrp->eh_flags );
-#ifdef EXTENTHDR_CHECKSUM
if ( ehcs ) {
if ( ! ( ehdrp->eh_flags & EXTENTHDR_FLAGS_CHECKSUM )) {
mlog( MLOG_NORMAL | MLOG_WARNING, _(
"corrupt extent header\n") );
return RV_CORRUPT;
}
- for ( sum = 0 ; sump < endp ; sum += *sump++ ) ;
- if ( sum ) {
+ if ( !is_checksum_valid( ehdrp, EXTENTHDR_SZ )) {
mlog( MLOG_NORMAL | MLOG_WARNING, _(
"bad extent header checksum\n") );
return RV_CORRUPT;
}
}
-#endif /* EXTENTHDR_CHECKSUM */
return RV_OK;
}
@@ -8137,11 +8121,6 @@ read_dirent( drive_t *drivep,
drive_ops_t *dop = drivep->d_opsp;
/* REFERENCED */
intgen_t nread;
-#ifdef DIRENTHDR_CHECKSUM
- register u_int32_t *sump = ( u_int32_t * )dhdrp;
- register u_int32_t *endp = ( u_int32_t * )( dhdrp + 1 );
- register u_int32_t sum;
-#endif /* DIRENTHDR_CHECKSUM */
intgen_t rval;
direnthdr_t tmpdh;
@@ -8180,21 +8159,18 @@ read_dirent( drive_t *drivep,
( size_t )dhdrp->dh_gen,
( size_t )dhdrp->dh_sz );
-#ifdef DIRENTHDR_CHECKSUM
if ( dhcs ) {
if ( dhdrp->dh_sz == 0 ) {
mlog( MLOG_NORMAL | MLOG_WARNING, _(
"corrupt directory entry header\n") );
return RV_CORRUPT;
}
- for ( sum = 0 ; sump < endp ; sum += *sump++ ) ;
- if ( sum ) {
+ if ( !is_checksum_valid( dhdrp, DIRENTHDR_SZ )) {
mlog( MLOG_NORMAL | MLOG_WARNING, _(
"bad directory entry header checksum\n") );
return RV_CORRUPT;
}
}
-#endif /* DIRENTHDR_CHECKSUM */
/* if null, return
*/
@@ -8246,11 +8222,6 @@ read_extattrhdr( drive_t *drivep, extattrhdr_t *ahdrp,
bool_t ahcs )
drive_ops_t *dop = drivep->d_opsp;
/* REFERENCED */
intgen_t nread;
-#ifdef EXTATTRHDR_CHECKSUM
- register u_int32_t *sump = ( u_int32_t * )ahdrp;
- register u_int32_t *endp = ( u_int32_t * )( ahdrp + 1 );
- register u_int32_t sum;
-#endif /* EXTATTRHDR_CHECKSUM */
intgen_t rval;
extattrhdr_t tmpah;
@@ -8288,21 +8259,18 @@ read_extattrhdr( drive_t *drivep, extattrhdr_t *ahdrp,
bool_t ahcs )
ahdrp->ah_valsz,
ahdrp->ah_checksum );
-#ifdef EXTATTRHDR_CHECKSUM
if ( ahcs ) {
if ( ! ( ahdrp->ah_flags & EXTATTRHDR_FLAGS_CHECKSUM )) {
mlog( MLOG_NORMAL | MLOG_WARNING, _(
"corrupt extattr header\n") );
return RV_CORRUPT;
}
- for ( sum = 0 ; sump < endp ; sum += *sump++ ) ;
- if ( sum ) {
+ if ( !is_checksum_valid( ahdrp, EXTATTRHDR_SZ )) {
mlog( MLOG_NORMAL | MLOG_WARNING, _(
"bad extattr header checksum\n") );
return RV_CORRUPT;
}
}
-#endif /* EXTATTRHDR_CHECKSUM */
return RV_OK;
}
--
1.7.0.4
|