diff --git a/src/BPSecLib_Private.h b/src/BPSecLib_Private.h index b0f97db..3b59d40 100644 --- a/src/BPSecLib_Private.h +++ b/src/BPSecLib_Private.h @@ -514,15 +514,31 @@ int BSL_BundleCtx_DeleteBundle(BSL_BundleRef_t *bundle, BSL_ReasonCode_t reason_ * @note Uses semantics similar to @c memcpy(). * * @param[in] bundle Context bundle - * @param[in] block_num Number of block requesting re-allocated of BTSD - * @param[in] bytesize Size of new BTSD + * @param[in] block_num The unique block number for which BTSD will be resized. + * @param[in] btsd_size Size of new BTSD content. * @return 0 on success, negative on failure. */ -int BSL_BundleCtx_ReallocBTSD(BSL_BundleRef_t *bundle, uint64_t block_num, size_t bytesize); +int BSL_BundleCtx_ReallocBTSD(BSL_BundleRef_t *bundle, uint64_t block_num, size_t btsd_size); +/** Construct a new sequential reader for BTSD content. + * + * @param[in] bundle Context bundle + * @param[in] block_num The unique block number for which BTSD will be read from. + * @return Pointer to the new reader or NULL if some failure occurs. + */ BSL_SeqReader_t *BSL_BundleCtx_ReadBTSD(const BSL_BundleRef_t *bundle, uint64_t block_num); -BSL_SeqWriter_t *BSL_BundleCtx_WriteBTSD(BSL_BundleRef_t *bundle, uint64_t block_num, size_t btsd_len); +/** Construct a new sequential writer for BTSD content. + * + * @param[in] bundle Context bundle + * @param[in] block_num The unique block number for which BTSD will be overwritten. + * @param btsd_size The total total size of BTSD content that will be written. + * The actual sequence of writes must not exceed this total size or it will be considered an error. + * If the actual sequence of writes does not reach this size it should be zero-padded and logged + * as an anomaly. + * @return Pointer to the new writer or NULL if some failure occurs. + */ +BSL_SeqWriter_t *BSL_BundleCtx_WriteBTSD(BSL_BundleRef_t *bundle, uint64_t block_num, size_t btsd_size); /** @brief Security role of an operation */ diff --git a/src/BPSecLib_Public.h b/src/BPSecLib_Public.h index bdf12da..a757e64 100644 --- a/src/BPSecLib_Public.h +++ b/src/BPSecLib_Public.h @@ -330,9 +330,11 @@ typedef struct /// @brief Host BPA function to remove a given canonical block from the bundle int (*block_remove_fn)(BSL_BundleRef_t *bundle_ref, uint64_t block_num); - /// @brief Host BPA function to reallocate a canonical block's BTSD, keeping existing data in-place. - /// @deprecated use sequential writer to do this - int (*block_realloc_btsd_fn)(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t bytesize); + /** Host BPA function to reallocate a canonical block's BTSD content, keeping existing data in-place. + * + * @deprecated use sequential writer to do replace BTSD content + */ + int (*block_realloc_btsd_fn)(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t btsd_size); /** Host BPA function do create a new sequential reader on a single block-type-specific data. * @@ -350,11 +352,14 @@ typedef struct * * @param[in] bundle_ref The bundle to read data from. * @param block_num The specific block number to write BTSD into. - * @param total_size A hint as to the total size that will be written. + * @param btsd_size The total total size of BTSD content that will be written. + * The actual sequence of writes must not exceed this total size or it will be considered an error. + * If the actual sequence of writes does not reach this size it should be zero-padded and logged + * as an anomaly. * @return A pointer to a reader struct or NULL if the reader cannot * be configured for any reason. */ - struct BSL_SeqWriter_s *(*block_write_btsd_fn)(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t total_size); + struct BSL_SeqWriter_s *(*block_write_btsd_fn)(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t btsd_size); /// @brief Host BPA function to delete Bundle with a reason code. This can be called multiple times per-bundle with /// different reason codes diff --git a/src/backend/HostInterface.c b/src/backend/HostInterface.c index b55306f..06afa12 100644 --- a/src/backend/HostInterface.c +++ b/src/backend/HostInterface.c @@ -127,12 +127,12 @@ int BSL_BundleCtx_DeleteBundle(BSL_BundleRef_t *bundle, BSL_ReasonCode_t reason_ return (result == 0) ? BSL_SUCCESS : BSL_ERR_HOST_CALLBACK_FAILED; } -int BSL_BundleCtx_ReallocBTSD(BSL_BundleRef_t *bundle, uint64_t block_num, size_t bytesize) +int BSL_BundleCtx_ReallocBTSD(BSL_BundleRef_t *bundle, uint64_t block_num, size_t btsd_size) { CHK_ARG_NONNULL(bundle); CHK_ARG_EXPR(block_num > 0); CHK_PRECONDITION(HostDescriptorTable.block_remove_fn != NULL); - int result = HostDescriptorTable.block_realloc_btsd_fn(bundle, block_num, bytesize); + int result = HostDescriptorTable.block_realloc_btsd_fn(bundle, block_num, btsd_size); return (result == 0) ? BSL_SUCCESS : BSL_ERR_HOST_CALLBACK_FAILED; } @@ -145,13 +145,13 @@ BSL_SeqReader_t *BSL_BundleCtx_ReadBTSD(const BSL_BundleRef_t *bundle, uint64_t return HostDescriptorTable.block_read_btsd_fn(bundle, block_num); } -BSL_SeqWriter_t *BSL_BundleCtx_WriteBTSD(BSL_BundleRef_t *bundle, uint64_t block_num, size_t btsd_len) +BSL_SeqWriter_t *BSL_BundleCtx_WriteBTSD(BSL_BundleRef_t *bundle, uint64_t block_num, size_t btsd_size) { if (!bundle || !HostDescriptorTable.block_write_btsd_fn) { return NULL; } - return HostDescriptorTable.block_write_btsd_fn(bundle, block_num, btsd_len); + return HostDescriptorTable.block_write_btsd_fn(bundle, block_num, btsd_size); } void BSL_HostDescriptors_Get(BSL_HostDescriptors_t *desc) diff --git a/src/mock_bpa/agent.c b/src/mock_bpa/agent.c index 0a8bb44..594442a 100644 --- a/src/mock_bpa/agent.c +++ b/src/mock_bpa/agent.c @@ -119,9 +119,9 @@ int MockBPA_GetBlockMetadata(const BSL_BundleRef_t *bundle_ref, uint64_t block_n return 0; } -int MockBPA_ReallocBTSD(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t bytesize) +int MockBPA_ReallocBTSD(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t btsd_size) { - if (!bundle_ref || !bundle_ref->data || block_num == 0 || bytesize == 0) + if (!bundle_ref || !bundle_ref->data || block_num == 0 || btsd_size == 0) { return -1; } @@ -137,13 +137,13 @@ int MockBPA_ReallocBTSD(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t if (found_block->btsd == NULL) { - found_block->btsd = BSL_calloc(1, bytesize); - found_block->btsd_len = bytesize; + found_block->btsd = BSL_calloc(1, btsd_size); + found_block->btsd_len = btsd_size; } else { - found_block->btsd = BSL_realloc(found_block->btsd, bytesize); - found_block->btsd_len = bytesize; + found_block->btsd = BSL_realloc(found_block->btsd, btsd_size); + found_block->btsd_len = btsd_size; } // Return -9 if malloc/realloc faile. Return 0 for success. @@ -162,6 +162,8 @@ struct MockBPA_BTSD_Data_s size_t size; /// File opened for the buffer FILE *file; + /// Local dead-reckoned cursor into #file + size_t curs; }; static int MockBPA_ReadBTSD_Read(void *user_data, void *buf, size_t *bufsize) @@ -173,6 +175,7 @@ static int MockBPA_ReadBTSD_Read(void *user_data, void *buf, size_t *bufsize) ASSERT_PRECONDITION(obj->file); const size_t got = fread(buf, 1, *bufsize, obj->file); + obj->curs += got; BSL_LOG_DEBUG("reading up to %zd bytes, got %zd", *bufsize, got); *bufsize = got; return 0; @@ -208,6 +211,7 @@ static struct BSL_SeqReader_s *MockBPA_ReadBTSD(const BSL_BundleRef_t *bundle_re obj->ptr = found_block->btsd; obj->size = found_block->btsd_len; obj->file = fmemopen(obj->ptr, obj->size, "rb"); + obj->curs = 0; BSL_SeqReader_t *reader = BSL_calloc(1, sizeof(BSL_SeqReader_t)); if (!reader) @@ -229,7 +233,15 @@ static int MockBPA_WriteBTSD_Write(void *user_data, const void *buf, size_t size CHK_ARG_NONNULL(buf); ASSERT_PRECONDITION(obj->file); + const size_t excess = (obj->curs + size) - obj->size; + if (excess > 0) + { + BSL_LOG_ERR("write too large for buffer of %zu by %zu bytes", obj->size, excess); + return BSL_ERR_FAILURE; + } + const size_t got = fwrite(buf, 1, size, obj->file); + obj->curs += got; BSL_LOG_DEBUG("writing up to %zd bytes, got %zd", size, got); if (got < size) { @@ -245,7 +257,11 @@ static void MockBPA_WriteBTSD_Deinit(void *user_data) ASSERT_PRECONDITION(obj->file); fclose(obj->file); - BSL_LOG_DEBUG("closed block %p with size %zu", obj->block, obj->size); + BSL_LOG_DEBUG("closed block %p with size %zu and cursor %zu", obj->block, obj->size, obj->curs); + if (obj->curs < obj->size) + { + BSL_LOG_ERR("closed block %p for writing with only %zu of %zu written", obj->block, obj->curs, obj->size); + } // now write-back the BTSD BSL_free(obj->block->btsd); @@ -255,7 +271,7 @@ static void MockBPA_WriteBTSD_Deinit(void *user_data) BSL_free(obj); } -static struct BSL_SeqWriter_s *MockBPA_WriteBTSD(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t total_size) +static struct BSL_SeqWriter_s *MockBPA_WriteBTSD(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t btsd_size) { MockBPA_Bundle_t *bundle = bundle_ref->data; MockBPA_CanonicalBlock_t **found_ptr = MockBPA_BlockByNum_get(bundle->blocks_num, block_num); @@ -264,7 +280,7 @@ static struct BSL_SeqWriter_s *MockBPA_WriteBTSD(BSL_BundleRef_t *bundle_ref, ui return NULL; } MockBPA_CanonicalBlock_t *found_block = *found_ptr; - BSL_LOG_DEBUG("opened block %p for size %zu", found_block, total_size); + BSL_LOG_DEBUG("opened block %p for size %zu, previous size %zu", found_block, btsd_size, found_block->btsd_len); struct MockBPA_BTSD_Data_s *obj = BSL_calloc(1, sizeof(struct MockBPA_BTSD_Data_s)); if (!obj) @@ -276,6 +292,15 @@ static struct BSL_SeqWriter_s *MockBPA_WriteBTSD(BSL_BundleRef_t *bundle_ref, ui obj->ptr = NULL; obj->size = 0; obj->file = open_memstream(&obj->ptr, &obj->size); + obj->curs = 0; + + if (btsd_size) + { + // pre-allocate BTSD size + fseeko(obj->file, btsd_size, SEEK_SET); + fflush(obj->file); + fseeko(obj->file, 0UL, SEEK_SET); + } BSL_SeqWriter_t *writer = BSL_calloc(1, sizeof(BSL_SeqWriter_t)); if (!writer) diff --git a/src/mock_bpa/ctr.c b/src/mock_bpa/ctr.c index 550dd1c..3f352a1 100644 --- a/src/mock_bpa/ctr.c +++ b/src/mock_bpa/ctr.c @@ -19,6 +19,10 @@ * the prime contract 80NM0018D0004 between the Caltech and NASA under * subcontract 1700763. */ +/** @file + * @ingroup mock_bpa + * Container structs for BPv7 data. + */ #include #include diff --git a/src/mock_bpa/ctr.h b/src/mock_bpa/ctr.h index ef89a0a..ebdd8aa 100644 --- a/src/mock_bpa/ctr.h +++ b/src/mock_bpa/ctr.h @@ -19,6 +19,10 @@ * the prime contract 80NM0018D0004 between the Caltech and NASA under * subcontract 1700763. */ +/** @file + * @ingroup mock_bpa + * Container structs for BPv7 data. + */ #ifndef BSL_MOCK_BPA_CTR_H_ #define BSL_MOCK_BPA_CTR_H_ diff --git a/src/mock_bpa/mock_bpa.c b/src/mock_bpa/mock_bpa.c index b9b5eb8..721326b 100644 --- a/src/mock_bpa/mock_bpa.c +++ b/src/mock_bpa/mock_bpa.c @@ -20,6 +20,7 @@ * subcontract 1700763. */ /** @file + * @ingroup mock_bpa * This is the main entry for a mock BPA daemon that communicates through * unix domain sockets. */ diff --git a/src/mock_bpa/policy_config.c b/src/mock_bpa/policy_config.c index 1c8abd7..c018540 100644 --- a/src/mock_bpa/policy_config.c +++ b/src/mock_bpa/policy_config.c @@ -21,8 +21,8 @@ */ /** @file - * Implementations for permutations of policy configurations. * @ingroup mock_bpa + * Implementations for permutations of policy configurations. */ #include "policy_config.h" diff --git a/src/mock_bpa/policy_config.h b/src/mock_bpa/policy_config.h index 0e2d5ca..b8ac521 100644 --- a/src/mock_bpa/policy_config.h +++ b/src/mock_bpa/policy_config.h @@ -21,8 +21,8 @@ */ /** @file - * Definitions for permutations of policy configurations. * @ingroup mock_bpa + * Definitions for permutations of policy configurations. */ #ifndef BSL_MOCK_BPA_POLICY_CONFIG_H_