diff --git a/lib/crypto_backend/crypto_cipher_kernel.c b/lib/crypto_backend/crypto_cipher_kernel.c index 6ee2a5a5..49032660 100644 --- a/lib/crypto_backend/crypto_cipher_kernel.c +++ b/lib/crypto_backend/crypto_cipher_kernel.c @@ -96,11 +96,14 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name, .salg_family = AF_ALG, .salg_type = "skcipher", }; + int r; if (!strcmp(name, "cipher_null")) key_length = 0; - snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name); + r = snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name); + if (r < 0 || (size_t)r >= sizeof(sa.salg_name)) + return -EINVAL; return _crypt_cipher_init(ctx, key, key_length, 0, &sa); } @@ -229,7 +232,10 @@ int crypt_cipher_check_kernel(const char *name, const char *mode, } salg_type = aead ? "aead" : "skcipher"; - snprintf((char *)sa.salg_type, sizeof(sa.salg_type), "%s", salg_type); + r = snprintf((char *)sa.salg_type, sizeof(sa.salg_type), "%s", salg_type); + if (r < 0 || (size_t)r >= sizeof(sa.salg_name)) + return -EINVAL; + memset(tmp_salg_name, 0, sizeof(tmp_salg_name)); /* FIXME: this is duplicating a part of devmapper backend */ @@ -242,7 +248,7 @@ int crypt_cipher_check_kernel(const char *name, const char *mode, else r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name); - if (r <= 0 || r > (int)(sizeof(sa.salg_name) - 1)) + if (r < 0 || (size_t)r >= sizeof(tmp_salg_name)) return -EINVAL; memcpy(sa.salg_name, tmp_salg_name, sizeof(sa.salg_name)); diff --git a/lib/crypto_backend/crypto_gcrypt.c b/lib/crypto_backend/crypto_gcrypt.c index 1f6fd35a..2845382e 100644 --- a/lib/crypto_backend/crypto_gcrypt.c +++ b/lib/crypto_backend/crypto_gcrypt.c @@ -96,6 +96,8 @@ static void crypt_hash_test_whirlpool_bug(void) int crypt_backend_init(void) { + int r; + if (crypto_backend_initialised) return 0; @@ -125,11 +127,12 @@ int crypt_backend_init(void) crypto_backend_initialised = 1; crypt_hash_test_whirlpool_bug(); - snprintf(version, 64, "gcrypt %s%s%s", + r = snprintf(version, sizeof(version), "gcrypt %s%s%s", gcry_check_version(NULL), crypto_backend_secmem ? "" : ", secmem disabled", - crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : "" - ); + crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : ""); + if (r < 0 || (size_t)r >= sizeof(version)) + return -EINVAL; return 0; } diff --git a/lib/crypto_backend/crypto_kernel.c b/lib/crypto_backend/crypto_kernel.c index 18c9a3ef..2e3d65b2 100644 --- a/lib/crypto_backend/crypto_kernel.c +++ b/lib/crypto_backend/crypto_kernel.c @@ -125,7 +125,7 @@ int crypt_backend_init(void) .salg_type = "hash", .salg_name = "sha256", }; - int tfmfd = -1, opfd = -1; + int r, tfmfd = -1, opfd = -1; if (crypto_backend_initialised) return 0; @@ -133,15 +133,17 @@ int crypt_backend_init(void) if (uname(&uts) == -1 || strcmp(uts.sysname, "Linux")) return -EINVAL; + r = snprintf(version, sizeof(version), "%s %s kernel cryptoAPI", + uts.sysname, uts.release); + if (r < 0 || (size_t)r >= sizeof(version)) + return -EINVAL; + if (crypt_kernel_socket_init(&sa, &tfmfd, &opfd, NULL, 0) < 0) return -EINVAL; close(tfmfd); close(opfd); - snprintf(version, sizeof(version), "%s %s kernel cryptoAPI", - uts.sysname, uts.release); - crypto_backend_initialised = 1; return 0; } @@ -262,6 +264,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, .salg_family = AF_ALG, .salg_type = "hash", }; + int r; h = malloc(sizeof(*h)); if (!h) @@ -274,8 +277,12 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, } h->hash_len = ha->length; - snprintf((char *)sa.salg_name, sizeof(sa.salg_name), + r = snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "hmac(%s)", ha->kernel_name); + if (r < 0 || (size_t)r >= sizeof(sa.salg_name)) { + free(h); + return -EINVAL; + } if (crypt_kernel_socket_init(&sa, &h->tfmfd, &h->opfd, key, key_length) < 0) { free(h); diff --git a/lib/crypto_backend/crypto_nss.c b/lib/crypto_backend/crypto_nss.c index 8332ecc9..ebe9de0e 100644 --- a/lib/crypto_backend/crypto_nss.c +++ b/lib/crypto_backend/crypto_nss.c @@ -77,6 +77,8 @@ static struct hash_alg *_get_alg(const char *name) int crypt_backend_init(void) { + int r; + if (crypto_backend_initialised) return 0; @@ -84,10 +86,13 @@ int crypt_backend_init(void) return -EINVAL; #if HAVE_DECL_NSS_GETVERSION - snprintf(version, 64, "NSS %s", NSS_GetVersion()); + r = snprintf(version, sizeof(version), "NSS %s", NSS_GetVersion()); #else - snprintf(version, 64, "NSS"); + r = snprintf(version, sizeof(version), "NSS"); #endif + if (r < 0 || (size_t)r >= sizeof(version)) + return -EINVAL; + crypto_backend_initialised = 1; return 0; } diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c index b453583b..b1390b93 100644 --- a/lib/crypto_backend/crypto_openssl.c +++ b/lib/crypto_backend/crypto_openssl.c @@ -403,7 +403,7 @@ static int _cipher_init(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec, const key_bits /= 2; r = snprintf(cipher_name, sizeof(cipher_name), "%s-%d-%s", name, key_bits, mode); - if (r < 0 || r >= (int)sizeof(cipher_name)) + if (r < 0 || (size_t)r >= sizeof(cipher_name)) return -EINVAL; type = EVP_get_cipherbyname(cipher_name); diff --git a/lib/integrity/integrity.c b/lib/integrity/integrity.c index 7bf954da..086b42f5 100644 --- a/lib/integrity/integrity.c +++ b/lib/integrity/integrity.c @@ -330,7 +330,9 @@ int INTEGRITY_format(struct crypt_device *cd, uuid_generate(tmp_uuid_bin); uuid_unparse(tmp_uuid_bin, tmp_uuid); - snprintf(tmp_name, sizeof(tmp_name), "temporary-cryptsetup-%s", tmp_uuid); + r = snprintf(tmp_name, sizeof(tmp_name), "temporary-cryptsetup-%s", tmp_uuid); + if (r < 0 || (size_t)r >= sizeof(tmp_name)) + return -EINVAL; /* There is no data area, we can actually use fake zeroed key */ if (params && params->integrity_key_size) diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index f6c9131f..034c7d90 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -578,9 +578,14 @@ static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char i = sscanf(capi, "%" CLENS "[^(](%" CLENS "[^)])", mode, cipher); if (i == 2) - snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv); + i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv); else - snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv); + i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv); + if (i < 0 || (size_t)i >= sizeof(dmcrypt_tmp)) { + free(*org_i); + *org_i = NULL; + return -EINVAL; + } if (!(*org_c = strdup(dmcrypt_tmp))) { free(*org_i); @@ -1206,7 +1211,7 @@ static int dm_prepare_uuid(struct crypt_device *cd, const char *name, const char { char *ptr, uuid2[UUID_LEN] = {0}; uuid_t uu; - unsigned i = 0; + int i = 0; /* Remove '-' chars */ if (uuid) { @@ -1226,9 +1231,11 @@ static int dm_prepare_uuid(struct crypt_device *cd, const char *name, const char type ?: "", type ? "-" : "", uuid2[0] ? uuid2 : "", uuid2[0] ? "-" : "", name); + if (i < 0) + return 0; log_dbg(cd, "DM-UUID is %s", buf); - if (i >= buflen) + if ((size_t)i >= buflen) log_err(cd, _("DM-UUID for device %s was truncated."), name); return 1; diff --git a/lib/luks2/luks2_digest.c b/lib/luks2/luks2_digest.c index 7e273fb0..85c30e76 100644 --- a/lib/luks2/luks2_digest.c +++ b/lib/luks2/luks2_digest.c @@ -219,7 +219,9 @@ static int assign_one_digest(struct crypt_device *cd, struct luks2_hdr *hdr, if (!jobj_digest_keyslots) return -EINVAL; - snprintf(num, sizeof(num), "%d", keyslot); + if (snprintf(num, sizeof(num), "%d", keyslot) < 0) + return -EINVAL; + if (assign) { jobj1 = LUKS2_array_jobj(jobj_digest_keyslots, num); if (!jobj1) @@ -303,7 +305,9 @@ static int assign_one_segment(struct crypt_device *cd, struct luks2_hdr *hdr, if (!jobj_digest_segments) return -EINVAL; - snprintf(num, sizeof(num), "%d", segment); + if (snprintf(num, sizeof(num), "%d", segment) < 0) + return -EINVAL; + if (assign) { jobj1 = LUKS2_array_jobj(jobj_digest_segments, num); if (!jobj1) diff --git a/lib/luks2/luks2_json_format.c b/lib/luks2/luks2_json_format.c index 5fb992be..350ebf4c 100644 --- a/lib/luks2/luks2_json_format.c +++ b/lib/luks2/luks2_json_format.c @@ -219,7 +219,7 @@ int LUKS2_generate_hdr( struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_segments, *jobj_config; char cipher[128]; uuid_t partitionUuid; - int digest; + int r, digest; uint64_t mdev_size; if (!metadata_size) @@ -293,9 +293,11 @@ int LUKS2_generate_hdr( uuid_unparse(partitionUuid, hdr->uuid); if (*cipherMode != '\0') - snprintf(cipher, sizeof(cipher), "%s-%s", cipherName, cipherMode); + r = snprintf(cipher, sizeof(cipher), "%s-%s", cipherName, cipherMode); else - snprintf(cipher, sizeof(cipher), "%s", cipherName); + r = snprintf(cipher, sizeof(cipher), "%s", cipherName); + if (r < 0 || (size_t)r >= sizeof(cipher)) + return -EINVAL; hdr->jobj = json_object_new_object(); diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c index 2838aa82..e0d893a6 100644 --- a/lib/luks2/luks2_reencrypt.c +++ b/lib/luks2/luks2_reencrypt.c @@ -2399,9 +2399,11 @@ static int reencrypt_init(struct crypt_device *cd, } if (!cipher_mode || *cipher_mode == '\0') - snprintf(_cipher, sizeof(_cipher), "%s", cipher); + r = snprintf(_cipher, sizeof(_cipher), "%s", cipher); else - snprintf(_cipher, sizeof(_cipher), "%s-%s", cipher, cipher_mode); + r = snprintf(_cipher, sizeof(_cipher), "%s-%s", cipher, cipher_mode); + if (r < 0 || (size_t)r >= sizeof(_cipher)) + return -EINVAL; if (MISALIGNED(params->data_shift, sector_size >> SECTOR_SHIFT)) { log_err(cd, _("Data shift is not aligned to requested encryption sector size (%" PRIu32 " bytes)."), sector_size); diff --git a/lib/luks2/luks2_token.c b/lib/luks2/luks2_token.c index 67f5f0af..36858e02 100644 --- a/lib/luks2/luks2_token.c +++ b/lib/luks2/luks2_token.c @@ -320,7 +320,8 @@ int LUKS2_token_create(struct crypt_device *cd, if (!json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens)) return -EINVAL; - snprintf(num, sizeof(num), "%d", token); + if (snprintf(num, sizeof(num), "%d", token) < 0) + return -EINVAL; /* Remove token */ if (!json) @@ -678,7 +679,9 @@ static int assign_one_keyslot(struct crypt_device *cd, struct luks2_hdr *hdr, if (!jobj_token_keyslots) return -EINVAL; - snprintf(num, sizeof(num), "%d", keyslot); + if (snprintf(num, sizeof(num), "%d", keyslot) < 0) + return -EINVAL; + if (assign) { jobj1 = LUKS2_array_jobj(jobj_token_keyslots, num); if (!jobj1) diff --git a/lib/luks2/luks2_token_keyring.c b/lib/luks2/luks2_token_keyring.c index fe0645d0..aa25861d 100644 --- a/lib/luks2/luks2_token_keyring.c +++ b/lib/luks2/luks2_token_keyring.c @@ -114,8 +114,12 @@ void keyring_dump(struct crypt_device *cd, const char *json) int LUKS2_token_keyring_json(char *buffer, size_t buffer_size, const struct crypt_token_params_luks2_keyring *keyring_params) { - snprintf(buffer, buffer_size, "{ \"type\": \"%s\", \"keyslots\":[],\"key_description\":\"%s\"}", + int r; + + r = snprintf(buffer, buffer_size, "{ \"type\": \"%s\", \"keyslots\":[],\"key_description\":\"%s\"}", LUKS2_TOKEN_KEYRING, keyring_params->key_description); + if (r < 0 || (size_t)r >= buffer_size) + return -EINVAL; return 0; } diff --git a/lib/setup.c b/lib/setup.c index ba45b705..a044b878 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -1082,10 +1082,15 @@ static int _init_by_name_crypt_none(struct crypt_device *cd) _mode); if (!r) { - snprintf(cd->u.none.cipher_spec, sizeof(cd->u.none.cipher_spec), + r = snprintf(cd->u.none.cipher_spec, sizeof(cd->u.none.cipher_spec), "%s-%s", cd->u.none.cipher, _mode); - cd->u.none.cipher_mode = cd->u.none.cipher_spec + strlen(cd->u.none.cipher) + 1; - cd->u.none.key_size = tgt->u.crypt.vk->keylength; + if (r < 0 || (size_t)r >= sizeof(cd->u.none.cipher_spec)) + r = -EINVAL; + else { + cd->u.none.cipher_mode = cd->u.none.cipher_spec + strlen(cd->u.none.cipher) + 1; + cd->u.none.key_size = tgt->u.crypt.vk->keylength; + r = 0; + } } dm_targets_free(cd, &dmd); @@ -5797,7 +5802,9 @@ int crypt_token_luks2_keyring_set(struct crypt_device *cd, if ((r = onlyLUKS2(cd))) return r; - LUKS2_token_keyring_json(json, sizeof(json), params); + r = LUKS2_token_keyring_json(json, sizeof(json), params); + if (r < 0) + return r; return LUKS2_token_create(cd, &cd->u.luks2.hdr, token, json, 1); } diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c index 6f407909..93565e61 100644 --- a/lib/utils_crypt.c +++ b/lib/utils_crypt.c @@ -88,7 +88,7 @@ int crypt_parse_hash_integrity_mode(const char *s, char *integrity) else return -EINVAL; - if (r < 0 || r == MAX_CIPHER_LEN) + if (r < 0 || r >= MAX_CIPHER_LEN) return -EINVAL; return 0; diff --git a/lib/utils_devpath.c b/lib/utils_devpath.c index be89cc9a..7371881f 100644 --- a/lib/utils_devpath.c +++ b/lib/utils_devpath.c @@ -367,7 +367,9 @@ char *crypt_get_base_device(const char *dev_path) if (dm_is_dm_kernel_name(devname)) return NULL; - snprintf(part_path, sizeof(part_path), "/dev/%s", devname); + if (snprintf(part_path, sizeof(part_path), "/dev/%s", devname) < 0) + return NULL; + return strdup(part_path); } diff --git a/lib/utils_loop.c b/lib/utils_loop.c index c712f1c5..904b9b5a 100644 --- a/lib/utils_loop.c +++ b/lib/utils_loop.c @@ -288,8 +288,9 @@ static char *_sysfs_backing_file(const char *loop) if (stat(loop, &st) || !S_ISBLK(st.st_mode)) return NULL; - snprintf(buf, sizeof(buf), "/sys/dev/block/%d:%d/loop/backing_file", - major(st.st_rdev), minor(st.st_rdev)); + if (snprintf(buf, sizeof(buf), "/sys/dev/block/%d:%d/loop/backing_file", + major(st.st_rdev), minor(st.st_rdev)) < 0) + return NULL; fd = open(buf, O_RDONLY); if (fd < 0) diff --git a/src/cryptsetup.c b/src/cryptsetup.c index a7dfcf03..f321d8d2 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -1046,8 +1046,10 @@ static int action_benchmark(void) /* TRANSLATORS: The string is header of a table and must be exactly (right side) aligned. */ log_std(_("# Algorithm | Key | Encryption | Decryption\n")); - snprintf(cipher, MAX_CIPHER_LEN, "%s-%s", - bciphers[i].cipher, bciphers[i].mode); + if (snprintf(cipher, MAX_CIPHER_LEN, "%s-%s", + bciphers[i].cipher, bciphers[i].mode) < 0) + r = -EINVAL; + if (!r) log_std("%15s %9zub %10.1f MiB/s %10.1f MiB/s\n", cipher, bciphers[i].key_size*8, enc_mbr, dec_mbr); @@ -2875,7 +2877,10 @@ static int action_encrypt_luks2(struct crypt_device **cd) } if (!ARG_SET(OPT_HEADER_ID)) { - snprintf(header_file, sizeof(header_file), "LUKS2-temp-%s.new", ARG_STR(OPT_UUID_ID)); + r = snprintf(header_file, sizeof(header_file), "LUKS2-temp-%s.new", ARG_STR(OPT_UUID_ID)); + if (r < 0 || (size_t)r >= sizeof(header_file)) + return -EINVAL; + fd = open(header_file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR); if (fd == -1) { if (errno == EEXIST) @@ -3161,7 +3166,8 @@ static int fill_keyslot_passwords(struct crypt_device *cd, if (ARG_INT32(OPT_KEY_SLOT_ID) == CRYPT_ANY_SLOT) { for (i = 0; (size_t)i < kp_size; i++) { - snprintf(msg, sizeof(msg), _("Enter passphrase for key slot %d: "), i); + if (snprintf(msg, sizeof(msg), _("Enter passphrase for key slot %d: "), i) < 0) + return -EINVAL; r = init_passphrase(kp, kp_size, cd, msg, i); if (r == -ENOENT) r = 0; @@ -3169,7 +3175,8 @@ static int fill_keyslot_passwords(struct crypt_device *cd, break; } } else { - snprintf(msg, sizeof(msg), _("Enter passphrase for key slot %u: "), ARG_INT32(OPT_KEY_SLOT_ID)); + if (snprintf(msg, sizeof(msg), _("Enter passphrase for key slot %u: "), ARG_INT32(OPT_KEY_SLOT_ID)) < 0) + return -EINVAL; r = init_passphrase(kp, kp_size, cd, msg, ARG_INT32(OPT_KEY_SLOT_ID)); }