Latent bug [patch]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi again,

When I tested the UUID-change patch on a read-only device it would fail silently. I tracked this down to the bug described below. (It is possible you already know about this and just choose to ignore it, because as far as I can tell it has no consequences for the current version of cryptsetup.)

The function write_blockwise() will return a negative value in case of an I/O error, or the number of bytes written otherwise. The return value is then tested in LUKS_write_phdr() to detect an error:

r = write_blockwise(devfd, &convHdr, sizeof(struct luks_phdr)) < sizeof(struct luks_phdr) ? -EIO : 0;

...but if write_blockwise() returns a (small) negative error number it will be cast to a (large) positive value in the comparison, because the return value of sizeof() is unsigned (size_t). So the test will fail, and r = 0, so the error will go undetected.

This is sneaky, because for older versions of gcc, sizeof() would return an ssize_t. At some point they changed it to be ANSI compliant.

There is a similar comparison in LUKS_read_phdr. The attached patch just casts the sizeof() value to ssize_t in these two cases.

Best regards,
Jacob Nielsen
Index: luks/keymanage.c
===================================================================
--- luks/keymanage.c	(revision 58)
+++ luks/keymanage.c	(working copy)
@@ -83,7 +83,7 @@
 		return -EINVAL; 
 	}
 
-	if(read_blockwise(devfd, hdr, sizeof(struct luks_phdr)) < sizeof(struct luks_phdr)) {
+	if(read_blockwise(devfd, hdr, sizeof(struct luks_phdr)) < (ssize_t)sizeof(struct luks_phdr)) {
 		r = -EIO;
 	} else if(memcmp(hdr->magic, luksMagic, LUKS_MAGIC_L)) { /* Check magic */
 		set_error(_("%s is not a LUKS partition\n"), device);
@@ -138,7 +138,7 @@
 		convHdr.keyblock[i].stripes            = htonl(hdr->keyblock[i].stripes);
 	}
 
-	r = write_blockwise(devfd, &convHdr, sizeof(struct luks_phdr)) < sizeof(struct luks_phdr) ? -EIO : 0;
+	r = write_blockwise(devfd, &convHdr, sizeof(struct luks_phdr)) < (ssize_t)sizeof(struct luks_phdr) ? -EIO : 0;
 
 	close(devfd);
 	return r;

---------------------------------------------------------------------
dm-crypt mailing list - http://www.saout.de/misc/dm-crypt/
To unsubscribe, e-mail: dm-crypt-unsubscribe@xxxxxxxx
For additional commands, e-mail: dm-crypt-help@xxxxxxxx

[Index of Archives]     [Device Mapper Devel]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]     [Fedora Docs]

  Powered by Linux