diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index d0f45569a..90dda67ae 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -6061,6 +6061,7 @@ _spdk_blob_set_xattr(struct spdk_blob *blob, const char *name, const void *value { struct spdk_xattr_tailq *xattrs; struct spdk_xattr *xattr; + size_t desc_size; _spdk_blob_verify_md_op(blob); @@ -6068,6 +6069,13 @@ _spdk_blob_set_xattr(struct spdk_blob *blob, const char *name, const void *value return -EPERM; } + desc_size = sizeof(struct spdk_blob_md_descriptor_xattr) + strlen(name) + value_len; + if (desc_size > SPDK_BS_MAX_DESC_SIZE) { + SPDK_DEBUGLOG(SPDK_LOG_BLOB, "Xattr '%s' of size %ld does not fix into single page %ld\n", name, + desc_size, SPDK_BS_MAX_DESC_SIZE); + return -ENOMEM; + } + if (internal) { xattrs = &blob->xattrs_internal; blob->invalid_flags |= SPDK_BLOB_INTERNAL_XATTR; diff --git a/lib/blob/blobstore.h b/lib/blob/blobstore.h index 08f903931..3ee23a891 100644 --- a/lib/blob/blobstore.h +++ b/lib/blob/blobstore.h @@ -321,6 +321,8 @@ struct spdk_blob_md_page { #define SPDK_BS_PAGE_SIZE 0x1000 SPDK_STATIC_ASSERT(SPDK_BS_PAGE_SIZE == sizeof(struct spdk_blob_md_page), "Invalid md page size"); +#define SPDK_BS_MAX_DESC_SIZE sizeof(((struct spdk_blob_md_page*)0)->descriptors) + #define SPDK_BS_SUPER_BLOCK_SIG "SPDKBLOB" struct spdk_bs_super_block { diff --git a/test/unit/lib/blob/blob.c/blob_ut.c b/test/unit/lib/blob/blob.c/blob_ut.c index 779ece785..4df6b4aa3 100644 --- a/test/unit/lib/blob/blob.c/blob_ut.c +++ b/test/unit/lib/blob/blob.c/blob_ut.c @@ -4233,6 +4233,8 @@ blob_set_xattrs(void) spdk_blob_id blobid; const void *value; size_t value_len; + char *xattr; + size_t xattr_length; int rc; dev = init_dev(); @@ -4289,6 +4291,15 @@ blob_set_xattrs(void) rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); CU_ASSERT(rc == -ENOENT); + /* Try xattr exceeding maximum length of descriptor in single page */ + xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) - + strlen("large_xattr") + 1; + xattr = calloc(xattr_length, sizeof(char)); + SPDK_CU_ASSERT_FATAL(xattr != NULL); + rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); + free(xattr); + SPDK_CU_ASSERT_FATAL(rc == -ENOMEM); + spdk_blob_close(blob, blob_op_complete, NULL); poll_threads(); CU_ASSERT(g_bserrno == 0);