Letting -check_media look for session checksum tags

This commit is contained in:
Thomas Schmitt 2009-08-14 21:15:52 +00:00
parent bebe13465f
commit 311d46d942
4 changed files with 166 additions and 56 deletions

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH XORRISO 1 "Aug 12, 2009" .TH XORRISO 1 "Aug 14, 2009"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -758,8 +758,8 @@ each single data file. If enabled then MD5 checksums get loaded from the image
if there are any. At image generation time they are computed for each file if there are any. At image generation time they are computed for each file
which gets its data written into the new session. The checksums of files which which gets its data written into the new session. The checksums of files which
have their data in older sessions get copied into the new session. have their data in older sessions get copied into the new session.
Checksums can be exploited via options -check_md5, -check_md5_r, and via find Checksums can be exploited via options -check_md5, -check_md5_r, via find
actions get_md5, check_md5. actions get_md5, check_md5, and via -check_media.
.TP .TP
\fB\-rom_toc_scan\fR "on"|"off"[:"emul_on"|"emul_off"] \fB\-rom_toc_scan\fR "on"|"off"[:"emul_on"|"emul_off"]
Read-only drives do not tell the actual media type but show any media as Read-only drives do not tell the actual media type but show any media as
@ -2548,9 +2548,16 @@ description of options.
.br .br
The result list tells intervals of 2 KiB blocks with start address, number The result list tells intervals of 2 KiB blocks with start address, number
of blocks and quality. Qualities which begin with "+" are of blocks and quality. Qualities which begin with "+" are
supposed to be valid readable data. Qualities with "-" are no valid data. supposed to be valid readable data. Qualities with "-" are unreadable or
corrupted data.
"0" indicates qualities which are covered by the check run or are regularly
allowed to to be unreadable (e.g. gaps between tracks).
.br .br
Alternatively it is possible to report damaged files rather than blocks. Alternatively it is possible to report damaged files rather than blocks.
.br
If -md5 is on then the default mode what=tracks looks out for libisofs
checksum tags for the ISO session data and and eventually checks them
against the checksums computed from the data stream.
.TP .TP
\fB\-check_media_defaults\fR [option [option ...]] -- \fB\-check_media_defaults\fR [option [option ...]] --
Preset options for runs of -check_media, -extract_cut and best_effort Preset options for runs of -check_media, -extract_cut and best_effort

View File

@ -4199,9 +4199,9 @@ int Spotlist_get_item(struct SpotlisT *o, int idx,
if(idx < 0 || idx > o->list_count) if(idx < 0 || idx > o->list_count)
return(0); return(0);
if(idx == o->current_idx) if(idx == o->current_idx && o->current_item != NULL)
li= o->current_item; li= o->current_item;
else if(idx == o->current_idx) { else if(idx == o->current_idx + 1 && o->current_item != NULL) {
li= o->current_item->next; li= o->current_item->next;
} else { } else {
li= o->list_start; li= o->list_start;
@ -4221,6 +4221,8 @@ char *Spotlist__quality_name(int quality, char name[80], int flag)
{ {
if(quality == Xorriso_read_quality_gooD) if(quality == Xorriso_read_quality_gooD)
strcpy(name, "+ good"); strcpy(name, "+ good");
else if(quality == Xorriso_read_quality_md5_matcH)
strcpy(name, "+ md5_match");
else if(quality == Xorriso_read_quality_sloW) else if(quality == Xorriso_read_quality_sloW)
strcpy(name, "+ slow"); strcpy(name, "+ slow");
else if(quality == Xorriso_read_quality_partiaL) else if(quality == Xorriso_read_quality_partiaL)
@ -4232,9 +4234,11 @@ char *Spotlist__quality_name(int quality, char name[80], int flag)
else if(quality == Xorriso_read_quality_invaliD) else if(quality == Xorriso_read_quality_invaliD)
strcpy(name, "- invalid"); strcpy(name, "- invalid");
else if(quality == Xorriso_read_quality_tao_enD) else if(quality == Xorriso_read_quality_tao_enD)
strcpy(name, "- tao end"); strcpy(name, "0 tao end");
else if(quality == Xorriso_read_quality_off_tracK) else if(quality == Xorriso_read_quality_off_tracK)
strcpy(name, "- off track"); strcpy(name, "0 off track");
else if(quality == Xorriso_read_quality_md5_mismatcH)
strcpy(name, "- md5_mismatch");
else if(quality == Xorriso_read_quality_unreadablE) else if(quality == Xorriso_read_quality_unreadablE)
strcpy(name, "- unreadable"); strcpy(name, "- unreadable");
else else
@ -11589,7 +11593,7 @@ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
struct SectorbitmaP *m; struct SectorbitmaP *m;
int map_sectors= -1, map_sector_size= -1; int map_sectors= -1, map_sector_size= -1;
int list_sectors, list_blocks, sector_size, sector_blocks; int list_sectors, list_blocks, sector_size, sector_blocks;
int replace_map= 0, count, i, lba, blocks, quality, ret; int replace_map= 0, count, i, lba, blocks, quality, ret, pass;
sector_size= Spotlist_sector_size(spotlist, read_chunk, 0); sector_size= Spotlist_sector_size(spotlist, read_chunk, 0);
sector_blocks= sector_size / 2048; sector_blocks= sector_size / 2048;
@ -11629,15 +11633,22 @@ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
} }
count= Spotlist_count(spotlist, 0); count= Spotlist_count(spotlist, 0);
/* first set good bits, then eventueally override by bad bits */
for(pass= 0; pass < 2; pass++) {
for(i= 0; i < count; i++) { for(i= 0; i < count; i++) {
ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0);
if(ret <= 0) if(ret <= 0)
continue; continue;
if(quality == Xorriso_read_quality_untesteD && !(flag & 1)) if(quality == Xorriso_read_quality_untesteD && !(flag & 1))
continue;
if(pass == 0 && quality < Xorriso_read_quality_untesteD)
continue;
else if(pass == 1 && quality >= Xorriso_read_quality_untesteD)
continue; continue;
Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks, Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks,
quality >= Xorriso_read_quality_untesteD); quality >= Xorriso_read_quality_untesteD);
} }
}
if(replace_map) { if(replace_map) {
Sectorbitmap_destroy(map, 0); Sectorbitmap_destroy(map, 0);
*map= m; *map= m;
@ -13346,13 +13357,13 @@ int Xorriso_option_charset(struct XorrisO *xorriso, char *name, int flag)
/* Options -check_md5 and -check_md5_r /* Options -check_md5 and -check_md5_r
@param flag bit0= issue summary message @param flag bit0= issue summary message
bit1= do not reset pacifier, no final pacifier message bit1= do not reset pacifier, no final pacifier message
bit2= do not issue pacifier messages at all >>> bit2= do not issue pacifier messages at all
bit3= recursive: -check_md5_r bit3= recursive: -check_md5_r
*/ */
int Xorriso_option_check_md5(struct XorrisO *xorriso, int Xorriso_option_check_md5(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag) int argc, char **argv, int *idx, int flag)
{ {
int ret, i, mem_pci, end_idx, fret, sev; int ret, i, mem_pci, end_idx, fret, sev, do_report= 0;
int optc= 0; int optc= 0;
char **optv= NULL, *cpt, *severity; char **optv= NULL, *cpt, *severity;
struct FindjoB *job= NULL; struct FindjoB *job= NULL;
@ -13388,7 +13399,7 @@ int Xorriso_option_check_md5(struct XorrisO *xorriso,
ret= -1; goto ex; ret= -1; goto ex;
} }
if(!(flag&2)) { if(!(flag & (2 | 4))) {
Xorriso_pacifier_reset(xorriso, 0); Xorriso_pacifier_reset(xorriso, 0);
mem_lut= xorriso->last_update_time; mem_lut= xorriso->last_update_time;
} }
@ -13399,6 +13410,7 @@ int Xorriso_option_check_md5(struct XorrisO *xorriso,
if(optc == 0) { if(optc == 0) {
ret= Xorriso_check_session_md5(xorriso, severity, 0); ret= Xorriso_check_session_md5(xorriso, severity, 0);
do_report= 1;
goto ex; goto ex;
} }
@ -13439,14 +13451,35 @@ int Xorriso_option_check_md5(struct XorrisO *xorriso,
} }
ret= 1; ret= 1;
report_outcome:;
do_report= 1;
ex:;
if(!(flag & (2 | 4))) {
xorriso->pacifier_interval= mem_pci; xorriso->pacifier_interval= mem_pci;
if(mem_lut!=xorriso->last_update_time && !(flag&2)) if(mem_lut!=xorriso->last_update_time && !(flag&2))
Xorriso_pacifier_callback(xorriso, "content bytes read", Xorriso_pacifier_callback(xorriso, "content bytes read",
xorriso->pacifier_count, 0, "", 1); xorriso->pacifier_count, 0, "", 1);
report_outcome:; }
if(do_report) {
if(optc == 0) {
if(ret <= 0) {
sprintf(xorriso->result_line,
"MD5 MISMATCH WITH DATA OF LOADED SESSION !\n");
Xorriso_result(xorriso,0);
if(strcmp(severity, "ALL") != 0) {
sprintf(xorriso->info_text,
"Event triggered by MD5 comparison mismatch");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0);
}
} else {
sprintf(xorriso->result_line, "Ok, session data match recorded md5.\n");
Xorriso_result(xorriso,0);
}
} else {
Xorriso_report_md5_outcome(xorriso, severity, 0); Xorriso_report_md5_outcome(xorriso, severity, 0);
}
ex:; }
(*idx)= end_idx; (*idx)= end_idx;
Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx, Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx,
&optc, &optv, 256); &optc, &optv, 256);
@ -13461,7 +13494,7 @@ ex:;
int Xorriso_option_check_media(struct XorrisO *xorriso, int Xorriso_option_check_media(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag) int argc, char **argv, int *idx, int flag)
{ {
int ret, i, count, lba, blocks, quality; int ret, i, count, lba, blocks, quality, pass, was_md5= 0;
int end_idx, old_idx, os_errno; int end_idx, old_idx, os_errno;
char quality_name[80], head_buffer[64*1024]; char quality_name[80], head_buffer[64*1024];
struct SpotlisT *spotlist= NULL; struct SpotlisT *spotlist= NULL;
@ -13536,19 +13569,37 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
} }
if(job->report_mode == 0 || job->report_mode == 2) { /* report blocks */ if(job->report_mode == 0 || job->report_mode == 2) { /* report blocks */
for(pass= 0; pass < 2; pass++) {
if(pass == 0) {
sprintf(xorriso->result_line, sprintf(xorriso->result_line,
"MCL layout : lba , size , quality\n"); "Media checks : lba , size , quality\n");
} else {
if(!was_md5)
break;
sprintf(xorriso->result_line,
"MD5 checks : lba , size , result\n");
}
Xorriso_result(xorriso,0); Xorriso_result(xorriso,0);
count= Spotlist_count(spotlist, 0); count= Spotlist_count(spotlist, 0);
for(i= 0; i < count; i++) { for(i= 0; i < count; i++) {
ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0);
if(ret <= 0) if(ret <= 0)
continue; continue;
sprintf(xorriso->result_line, "MCL item : %10d , %10d , %s\n", if(pass == 0 && (quality == Xorriso_read_quality_md5_matcH ||
quality == Xorriso_read_quality_md5_mismatcH)) {
was_md5= 1;
continue;
}
else if(pass == 1 && !(quality == Xorriso_read_quality_md5_matcH ||
quality == Xorriso_read_quality_md5_mismatcH))
continue;
sprintf(xorriso->result_line, "%s: %10d , %10d , %s\n",
pass == 0 ? "Media region " : "MD5 tag range",
lba, blocks, Spotlist__quality_name(quality, quality_name, 0)); lba, blocks, Spotlist__quality_name(quality, quality_name, 0));
Xorriso_result(xorriso,0); Xorriso_result(xorriso,0);
} }
} }
}
if(job->report_mode == 1 || job->report_mode == 2) { /* report files */ if(job->report_mode == 1 || job->report_mode == 2) { /* report files */
ret= Findjob_new(&findjob, "/", 0); ret= Findjob_new(&findjob, "/", 0);
if(ret<=0) { if(ret<=0) {

View File

@ -1 +1 @@
#define Xorriso_timestamP "2009.08.14.102355" #define Xorriso_timestamP "2009.08.14.211648"

View File

@ -9195,14 +9195,15 @@ int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag)
/* @param flag bit0= this is a follow-up session (i.e. on CD: TAO) /* @param flag bit0= this is a follow-up session (i.e. on CD: TAO)
bit1= no pacifier messages bit1= no pacifier messages
bit2= compute stream MD5 and look out for checksum tag
@return <=0 error, 1= done, 2= aborted due to limit @return <=0 error, 1= done, 2= aborted due to limit
*/ */
int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist, int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
struct CheckmediajoB *job, struct CheckmediajoB *job,
int from_lba, int block_count, int read_chunk, int from_lba, int block_count, int read_chunk,
int flag) int md5_start, int flag)
{ {
int i, j, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading; int i, j, k, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading;
int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd= 0; int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd= 0;
int start_sec, end_sec, first_value, fret; int start_sec, end_sec, first_value, fret;
char profile_name[80]; char profile_name[80];
@ -9214,6 +9215,9 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
double pre_read_time, post_read_time, time_diff, total_time_diff= 0; double pre_read_time, post_read_time, time_diff, total_time_diff= 0;
double last_abort_file_time= 0; double last_abort_file_time= 0;
struct stat stbuf; struct stat stbuf;
void *ctx= NULL;
char md5[16], tag_md5[16];
uint32_t pos, range_start, range_size;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to check media readability", "on attempt to check media readability",
@ -9235,6 +9239,14 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
else if(job->retry == 0 && is_cd) else if(job->retry == 0 && is_cd)
retry= 1; retry= 1;
if(flag & 4) {
ret= iso_md5_start(&ctx);
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
}
start_lba= from_lba; start_lba= from_lba;
to_read= read_chunk; to_read= read_chunk;
post_read_time= Sfile_microtime(0); post_read_time= Sfile_microtime(0);
@ -9364,6 +9376,54 @@ abort_check:;
quality= Xorriso_read_quality_sloW; quality= Xorriso_read_quality_sloW;
} }
if(ctx != NULL) {
for(j= 0; j < to_read; j++) {
ret= iso_util_decode_md5_tag(data + j * 2048, &pos, &range_start,
&range_size, tag_md5, 0);
if(ret == 1 && pos == i + j + from_lba) {
if(range_start != md5_start) {
sprintf(xorriso->info_text,
"Found MD5 checksum tag which covers different data range");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
sprintf(xorriso->info_text,
" Expected: %u Found: %u",
(unsigned int) md5_start, range_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
} else {
iso_md5_end(&ctx, md5);
for(k= 0; k < 16; k++)
if(tag_md5[k] != md5[k])
break;
if(k < 16 ) {
ret= Spotlist_add_item(spotlist, md5_start,
i + j + from_lba - md5_start,
Xorriso_read_quality_md5_mismatcH, 0);
sprintf(xorriso->info_text,
"Found NON-MATCHING MD5 checksum tag: start=%d size=%d",
md5_start, i + j + from_lba - md5_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
"WARNING", 0);
} else {
ret= Spotlist_add_item(spotlist, md5_start,
i + j + from_lba - md5_start,
Xorriso_read_quality_md5_matcH, 0);
sprintf(xorriso->info_text,
"Found matching MD5 checksum tag: start=%d size=%d",
md5_start, i + j + from_lba - md5_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE",
0);
}
}
} else {
/* >>> ??? warn if ret == ISO_MD5_AREA_CORRUPTED */;
if(from_lba + i + j >= md5_start)
iso_md5_compute(ctx, data + j * 2048, 2048);
}
}
}
write_amount= data_count; write_amount= data_count;
if(data_count > 0) { if(data_count > 0) {
read_count+= data_count; read_count+= data_count;
@ -9424,6 +9484,8 @@ failed_to_write:;
ret= 1; ret= 1;
ex: ex:
if(ctx != NULL)
iso_md5_end(&ctx, md5);
return(ret); return(ret);
} }
@ -9433,7 +9495,7 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
{ {
int media_blocks= 0, read_chunk= 16, ret, mode, start_lba= 0; int media_blocks= 0, read_chunk= 16, ret, mode, start_lba= 0;
int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba; int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba;
int num_sessions, num_tracks, declare_untested= 0; int num_sessions, num_tracks, declare_untested= 0, md5_start;
char *toc_info= NULL; char *toc_info= NULL;
struct burn_drive *drive; struct burn_drive *drive;
struct burn_drive_info *dinfo; struct burn_drive_info *dinfo;
@ -9492,7 +9554,7 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
blocks= job->max_lba + 1 - start_lba; blocks= job->max_lba + 1 - start_lba;
xorriso->pacifier_total= blocks; xorriso->pacifier_total= blocks;
ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks, ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks,
read_chunk, 0); read_chunk, 0, 0);
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
@ -9511,6 +9573,7 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
continue; continue;
track_lba= isoburn_entry.start_lba; track_lba= isoburn_entry.start_lba;
track_blocks= isoburn_entry.track_blocks; track_blocks= isoburn_entry.track_blocks;
md5_start= track_lba;
if(i == 0 && j == 0) { if(i == 0 && j == 0) {
if(track_lba == 32) { if(track_lba == 32) {
ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0);
@ -9547,7 +9610,8 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
goto ex; goto ex;
} else { } else {
ret= Xorriso_check_interval(xorriso, *spotlist, job, track_lba, ret= Xorriso_check_interval(xorriso, *spotlist, job, track_lba,
track_blocks, read_chunk, i > 0); track_blocks, read_chunk, md5_start,
(i > 0) | (4 * (xorriso->do_md5 & 1)));
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
if(ret == 2) if(ret == 2)
@ -9572,7 +9636,7 @@ no_content_visible:;
goto no_content_visible; goto no_content_visible;
xorriso->pacifier_total= blocks; xorriso->pacifier_total= blocks;
ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks, ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks,
read_chunk, 0); read_chunk, 0, 0);
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
} else if(mode == 2) { } else if(mode == 2) {
@ -9701,7 +9765,7 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
file_processed_bytes+= ((off_t) count) * (off_t) 2048; file_processed_bytes+= ((off_t) count) * (off_t) 2048;
ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk, ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk,
(flag & 2)); 0, (flag & 2));
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
if (ret == 2) { if (ret == 2) {
@ -12310,18 +12374,6 @@ int Xorriso_check_session_md5(struct XorrisO *xorriso, char *severity,
Xorriso_result(xorriso,0); Xorriso_result(xorriso,0);
ret= Xorriso_check_md5_range(xorriso, (off_t) start_lba, (off_t) end_lba, ret= Xorriso_check_md5_range(xorriso, (off_t) start_lba, (off_t) end_lba,
md5, 0); md5, 0);
if(ret <= 0) {
sprintf(xorriso->result_line,
"MD5 MISMATCH WITH DATA OF LOADED SESSION !\n");
Xorriso_result(xorriso,0);
if(strcmp(severity, "ALL") != 0) {
sprintf(xorriso->info_text, "Event triggered by MD5 comparison mismatch");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0);
}
} else {
sprintf(xorriso->result_line, "Ok, session data match recorded md5.\n");
Xorriso_result(xorriso,0);
}
return(ret); return(ret);
} }