diff --git a/libcheckisomd5.c b/libcheckisomd5.c index bd7b86f..9f86734 100644 --- a/libcheckisomd5.c +++ b/libcheckisomd5.c @@ -67,7 +67,8 @@ static enum isomd5sum_status checkmd5sum(int isofd, checkCallback cb, void *cbda while (offset < total_size) { const size_t nbyte = MIN((size_t)(total_size - offset), buffer_size); - ssize_t nread = read(isofd, buffer, nbyte); + /** Read more than nbyte to make sure that it's O_DIRECT compatible. */ + ssize_t nread = read(isofd, buffer, buffer_size); if (nread <= 0L) break; @@ -76,9 +77,11 @@ static enum isomd5sum_status checkmd5sum(int isofd, checkCallback cb, void *cbda * size from where it started up to the end of the block it pre-fetched * from a cd drive. */ - if (nread > nbyte) { - nread = nbyte; + if (nread > buffer_size) { + nread = buffer_size; lseek(isofd, offset + nread, SEEK_SET); + } else if (nread > nbyte) { + nread = nbyte; } /* Make sure appdata which contains the md5sum is cleared. */ clear_appdata(buffer, nread, info->offset + APPDATA_OFFSET, offset); diff --git a/libimplantisomd5.c b/libimplantisomd5.c index 0688b1c..0f340a0 100644 --- a/libimplantisomd5.c +++ b/libimplantisomd5.c @@ -41,7 +41,7 @@ static int writeAppData(unsigned char *const appdata, const char *const valstr, return -1; } - memcpy(appdata + *loc, valstr, vallen); + memcpy(appdata + (APPDATA_OFFSET - BLOCK_SIZE) + *loc, valstr, vallen); *loc += vallen; return 0; @@ -67,25 +67,29 @@ int implantISOFD(int isofd, int supported, int forceit, int quiet, char **errstr return -1; } - lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET); - unsigned char appdata[APPDATA_SIZE]; - if (read(isofd, appdata, APPDATA_SIZE) <= 0) { + lseek(isofd, pvd_offset + BLOCK_SIZE, SEEK_SET); + unsigned char appdata[BLOCK_SIZE * 2] __attribute__((aligned(BLOCK_SIZE))); + const size_t appdata_offset = APPDATA_OFFSET - BLOCK_SIZE; + + /* Read more than needed to stay O_DIRECT compatible. */ + if (read(isofd, appdata, BLOCK_SIZE * 2) <= 0) { *errstr = "Failed to read application data from file."; return -errno; } if (!forceit) { for (size_t i = 0; i < APPDATA_SIZE; i++) { - if (appdata[i] != ' ') { + if (appdata[appdata_offset + i] != ' ') { *errstr = "Application data has been used - not implanting md5sum!"; return -1; } } } else { /* Write out blanks to erase old app data. */ - lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET); - memset(appdata, ' ', APPDATA_SIZE); - ssize_t error = write(isofd, appdata, APPDATA_SIZE); + lseek(isofd, pvd_offset + BLOCK_SIZE, SEEK_SET); + memset(appdata + appdata_offset, ' ', APPDATA_SIZE); + /* Write more than needed to stay O_DIRECT compatible. */ + ssize_t error = write(isofd, appdata + BLOCK_SIZE, BLOCK_SIZE * 2); if (error < 0) { *errstr = "Write failed."; return error; @@ -99,7 +103,6 @@ int implantISOFD(int isofd, int supported, int forceit, int quiet, char **errstr MD5_Init(&hashctx); char fragmentsums[FRAGMENT_SUM_SIZE + 1]; *fragmentsums = '\0'; - const size_t pagesize = (size_t) getpagesize(); const size_t buffer_size = NUM_SYSTEM_SECTORS * SECTOR_SIZE; unsigned char *buffer; @@ -136,7 +139,9 @@ int implantISOFD(int isofd, int supported, int forceit, int quiet, char **errstr printf("fragmd5 = %s\n", fragmentsums); printf("frags = %lu\n", FRAGMENT_COUNT); } - memset(appdata, ' ', APPDATA_SIZE); + if (!forceit) { + memset(appdata + appdata_offset, ' ', APPDATA_SIZE); + } size_t loc = 0; if (writeAppData(appdata, "ISO MD5SUM = ", &loc, errstr)) @@ -183,12 +188,13 @@ int implantISOFD(int isofd, int supported, int forceit, int quiet, char **errstr appdata, "THIS IS NOT THE SAME AS RUNNING MD5SUM ON THIS ISO!!", &loc, errstr)) return -1; - if (lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET) < 0) { + if (lseek(isofd, pvd_offset + BLOCK_SIZE, SEEK_SET) < 0) { *errstr = "Seek failed."; return -1; } - ssize_t error = write(isofd, appdata, APPDATA_SIZE); + /* Write more than needed to stay O_DIRECT compatible. */ + ssize_t error = write(isofd, appdata, BLOCK_SIZE * 2); if (error < 0) { *errstr = "Write failed."; return -1; diff --git a/utilities.c b/utilities.c index b00337f..c4a5bcc 100644 --- a/utilities.c +++ b/utilities.c @@ -41,7 +41,7 @@ static unsigned char *read_primary_volume_descriptor(const int fd, off_t *const return NULL; } unsigned char *sector_buffer; - sector_buffer = aligned_alloc((size_t) getpagesize(), SECTOR_SIZE * sizeof(*sector_buffer)); + sector_buffer = aligned_alloc(BLOCK_SIZE, SECTOR_SIZE * sizeof(*sector_buffer)); /* Read n volume descriptors. */ for (;;) { if (read(fd, sector_buffer, SECTOR_SIZE) == -1) { @@ -137,8 +137,6 @@ struct volume_info *const parsepvd(const int isofd) { result->offset = offset; result->isosize = isosize(aligned_buffer); - free(aligned_buffer); - for (size_t index = 0; index < APPDATA_SIZE;) { size_t len; if ((len = starts_with(buffer + index, "ISO MD5SUM = "))) { diff --git a/utilities.h b/utilities.h index 909696a..50b2392 100644 --- a/utilities.h +++ b/utilities.h @@ -39,6 +39,7 @@ int getpagesize() { return 2048; } #define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define BLOCK_SIZE 512 #define HASH_SIZE 32 /* Length in characters of string used for fragment md5sum checking */ #define FRAGMENT_SUM_SIZE 60UL