diff --git a/ChangeLog b/ChangeLog index fd985caf..47031e3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 2011-07-25 Milan Broz * Remove hash/hmac restart from crypto backend and make it part of hash/hmac final. + * Improve check for invalid offset and size values. 2011-07-19 Milan Broz * Revert default initialisation of volume key in crypt_init_by_name(). diff --git a/lib/utils.c b/lib/utils.c index 59e8fad4..b030a3d1 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -432,19 +432,30 @@ int device_check_and_adjust(struct crypt_device *cd, return r; } + if (*offset >= real_size) { + log_err(cd, _("Requested offset is beyond real size of device %s.\n"), + device); + return -EINVAL; + } + if (!*size) { *size = real_size; if (!*size) { log_err(cd, _("Device %s has zero size.\n"), device); return -ENOTBLK; } - if (*size < *offset) { - log_err(cd, _("Device %s is too small.\n"), device); - return -EINVAL; - } *size -= *offset; } + /* in case of size is set by parameter */ + if ((real_size - *offset) < *size) { + log_dbg("Device %s: offset = %" PRIu64 " requested size = %" PRIu64 + ", backing device size = %" PRIu64, + device, *offset, *size, real_size); + log_err(cd, _("Device %s is too small.\n"), device); + return -EINVAL; + } + if (device_check == DEV_SHARED) { log_dbg("Checking crypt segments for device %s.", device); r = crypt_sysfs_check_crypt_segment(device, *offset, *size); diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 758cb7a5..29e6e6fa 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -1204,8 +1205,11 @@ int main(int argc, const char **argv) unsigned long long ull_value; char *endp; + errno = 0; ull_value = strtoull(popt_tmp, &endp, 0); - if (*endp || !*popt_tmp) + if (*endp || !*popt_tmp || + (errno == ERANGE && ull_value == ULLONG_MAX) || + (errno != 0 && ull_value == 0)) r = POPT_ERROR_BADNUMBER; switch(r) {