summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Scherle2022-06-03 01:56:27 +0200
committerMichael Scherle2022-06-03 01:56:27 +0200
commit4a8bfaae9f7056da60d36d9a74f95b7f7a58486d (patch)
tree615910a16955099c1234a219e217ced3d2c212cd
parentfixed wrong bitfield size (diff)
downloaddnbd3-4a8bfaae9f7056da60d36d9a74f95b7f7a58486d.tar.gz
dnbd3-4a8bfaae9f7056da60d36d9a74f95b7f7a58486d.tar.xz
dnbd3-4a8bfaae9f7056da60d36d9a74f95b7f7a58486d.zip
security fixes
-rw-r--r--inc/dnbd3/config.h1
-rw-r--r--src/fuse/CMakeLists.txt6
-rw-r--r--src/fuse/cowfile.c109
-rw-r--r--src/fuse/cowfile.h5
4 files changed, 59 insertions, 62 deletions
diff --git a/inc/dnbd3/config.h b/inc/dnbd3/config.h
index 98af571..3caa7af 100644
--- a/inc/dnbd3/config.h
+++ b/inc/dnbd3/config.h
@@ -47,6 +47,7 @@
#define COW_MIN_UPLOAD_DELAY 60 // in seconds
#define COW_STATS_UPDATE_TIME 5 // time in seconds the cow status files gets updated (while uploading blocks)
#define COW_MAX_PARALLEL_UPLOADS 10 // maximum number of parallel uploads
+#define COW_URL_STRING_SIZE 500 // Max string size for an url
// +++++ COW API Endpoints +++++
#define COW_API_CREATE "%s/api/File/Create"
#define COW_API_UPDATE "%s/api/File/Update?guid=%s&BlockNumber=%u"
diff --git a/src/fuse/CMakeLists.txt b/src/fuse/CMakeLists.txt
index 489f43e..05b3fcd 100644
--- a/src/fuse/CMakeLists.txt
+++ b/src/fuse/CMakeLists.txt
@@ -13,8 +13,6 @@ find_package(Libatomic REQUIRED)
# find curl for cow
find_package(CURL REQUIRED)
-pkg_search_module(UUID REQUIRED uuid)
-
# add compile option to enable enhanced POSIX pthread features
add_definitions(-D_GNU_SOURCE)
@@ -28,8 +26,8 @@ set(DNBD3_FUSE_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/cowfile.h
${CMAKE_CURRENT_SOURCE_DIR}/main.h)
add_executable(dnbd3-fuse ${DNBD3_FUSE_SOURCE_FILES})
-target_include_directories(dnbd3-fuse PRIVATE ${FUSE_INCLUDE_DIRS} ${CURL_INCLUDE_DIR} ${UUID_INCLUDE_DIRS})
-target_link_libraries(dnbd3-fuse dnbd3-build dnbd3-version dnbd3-shared ${FUSE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CURL_LIBRARIES} ${UUID_LIBRARIES})
+target_include_directories(dnbd3-fuse PRIVATE ${FUSE_INCLUDE_DIRS} ${CURL_INCLUDE_DIR} )
+target_link_libraries(dnbd3-fuse dnbd3-build dnbd3-version dnbd3-shared ${FUSE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CURL_LIBRARIES} )
install(TARGETS dnbd3-fuse RUNTIME DESTINATION bin
COMPONENT fuse)
diff --git a/src/fuse/cowfile.c b/src/fuse/cowfile.c
index 14db252..cd58734 100644
--- a/src/fuse/cowfile.c
+++ b/src/fuse/cowfile.c
@@ -7,12 +7,11 @@ static pthread_t tidCowUploader;
static char *cowServerAddress;
static CURL *curl;
static cowfile_metadata_header_t *metadata = NULL;
-static char uuidStr[37];
atomic_bool uploadLoop = true;
//both variables are only relevant for the upload after the image is dismounted
-static atomic_uint_fast32_t blocksForCompleteUpload = 0;
-static atomic_uint_fast32_t blocksUploaded = 0;
+static uint32_t blocksForCompleteUpload = 0;
+static uint32_t blocksUploaded = 0;
static struct cow
{
@@ -109,11 +108,11 @@ size_t curlCallbackCreateSession( char *buffer, size_t itemSize, size_t nitems,
{
size_t bytes = itemSize * nitems;
if ( strlen( response ) + bytes != 36 ) {
- logadd( LOG_INFO, "strlen(response): %i bytes: %i \n", strlen( response ), bytes );
+ logadd( LOG_INFO, "strlen(response): %lu bytes: %lu \n", strlen( response ), bytes );
return bytes;
}
- strcat( response, buffer );
+ strncat( response, buffer, 36 );
return bytes;
}
@@ -123,11 +122,11 @@ size_t curlCallbackCreateSession( char *buffer, size_t itemSize, size_t nitems,
* @param imageName
* @param version of the original Image
*/
-bool createSession( char *imageName, uint16_t version )
+bool createSession( const char *imageName, uint16_t version )
{
CURLcode res;
- char url[300];
- sprintf( url, COW_API_CREATE, cowServerAddress );
+ char url[COW_URL_STRING_SIZE];
+ snprintf ( url, COW_URL_STRING_SIZE, COW_API_CREATE, cowServerAddress );
logadd( LOG_INFO, "COW_API_CREATE URL: %s", url );
curl_easy_setopt( curl, CURLOPT_POST, 1L );
curl_easy_setopt( curl, CURLOPT_URL, url );
@@ -151,10 +150,9 @@ bool createSession( char *imageName, uint16_t version )
curl_easy_setopt( curl, CURLOPT_MIMEPOST, mime );
- char response[37];
- response[0] = '\0';
+ metadata->uuid[0] = '\0';
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, curlCallbackCreateSession );
- curl_easy_setopt( curl, CURLOPT_WRITEDATA, &response );
+ curl_easy_setopt( curl, CURLOPT_WRITEDATA, &metadata->uuid );
res = curl_easy_perform( curl );
curl_mime_free( mime );
@@ -172,13 +170,8 @@ bool createSession( char *imageName, uint16_t version )
return false;
}
curl_easy_reset( curl );
- response[36] = '\0';
- logadd( LOG_DEBUG1, "Cow session started, guid: %s\n", response );
- if ( uuid_parse( response, metadata->uuid ) != 0 ) {
- logadd( LOG_ERROR, "uuid_parse failed\n" );
- return false;
- }
- strcpy( uuidStr, response );
+ metadata->uuid[36] = '\0';
+ logadd( LOG_DEBUG1, "Cow session started, guid: %s\n", metadata->uuid );
return true;
}
@@ -226,6 +219,11 @@ size_t curlReadCallbackUploadBlock( char *ptr, size_t size, size_t nmemb, void *
( size * nmemb ) - len );
off_t inBlockOffset = uploadBlock->position - metadata->bitfieldSize;
size_t lengthRead = pread( cow.fhd, ( ptr + len ), lenRead, uploadBlock->block->offset + inBlockOffset );
+
+ if(lenRead != lengthRead){
+ // temp fix, fill up non full blocks
+ lengthRead = lenRead;
+ }
uploadBlock->position += lengthRead;
len += lengthRead;
}
@@ -244,10 +242,9 @@ bool uploadBlock( cow_block_metadata_t *block, uint32_t blocknumber, uint32_t ti
{
CURLcode res;
cow_curl_read_upload_t curlUploadBlock;
+ char url[COW_URL_STRING_SIZE];
- char url[400];
-
- sprintf( url, COW_API_UPDATE, cowServerAddress, uuidStr, blocknumber );
+ snprintf( url, COW_URL_STRING_SIZE, COW_API_UPDATE, cowServerAddress, metadata->uuid, blocknumber );
curlUploadBlock.block = block;
curlUploadBlock.position = 0;
@@ -279,7 +276,7 @@ bool uploadBlock( cow_block_metadata_t *block, uint32_t blocknumber, uint32_t ti
curl_off_t ul;
res = curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, &ul);
if(CURLE_OK == res) {
- logadd( LOG_INFO, "Speed: %ld kb/s", (long) ((ul/total)/1000));
+ logadd( LOG_INFO, "Speed: %f kb/s", (double) (((double)ul/total)/1000));
}
}
logadd( LOG_INFO, "CURLINFO_TOTAL_TIME: %f", total);
@@ -310,8 +307,8 @@ bool mergeRequest()
CURLcode res;
curl_easy_setopt( curl, CURLOPT_POST, 1L );
- char url[400];
- sprintf( url, COW_API_START_MERGE, cowServerAddress);
+ char url[COW_URL_STRING_SIZE];
+ snprintf( url, COW_URL_STRING_SIZE, COW_API_START_MERGE, cowServerAddress);
curl_easy_setopt( curl, CURLOPT_URL, url );
@@ -321,7 +318,7 @@ bool mergeRequest()
part = curl_mime_addpart( mime );
curl_mime_name( part, "guid" );
- curl_mime_data( part, uuidStr, CURL_ZERO_TERMINATED );
+ curl_mime_data( part, metadata->uuid, CURL_ZERO_TERMINATED );
part = curl_mime_addpart( mime );
curl_mime_name( part, "fileSize" );
@@ -364,6 +361,14 @@ void startMerge()
}
}
+void updateCowStatsFile( uint blocks, uint totalBlocks, bool done ) {
+ char buffer[300];
+
+ int len = snprintf( buffer, 100, "state: %s\nuploaded: %lu\ntotalBlocks: %lu\n", done?"done":"uploading" ,blocks, totalBlocks );
+ pwrite( cow.fhs, buffer, len, 43 );
+ ftruncate( cow.fhs, 43 + len );
+}
+
/**
* @brief loops through all blocks and uploads them.
*
@@ -373,7 +378,7 @@ bool uploaderLoop( bool lastLoop )
{
bool success = true;
uint64_t lastUpdateTime = time( NULL );
- int l1MaxOffset = ceil( metadata->imageSize / COW_L2_STORAGE_CAPACITY );
+ int l1MaxOffset = 1 + ((metadata->imageSize - 1) / COW_L2_STORAGE_CAPACITY);
int fails = 0;
for ( int l1Offset = 0; l1Offset < l1MaxOffset; l1Offset++ ) {
if ( cow.l1[l1Offset] == -1 ) {
@@ -401,7 +406,7 @@ bool uploaderLoop( bool lastLoop )
if( lastLoop ) {
blocksUploaded++;
if( time(NULL) - lastUpdateTime > COW_STATS_UPDATE_TIME ) {
- updateCowStatsFile( blocksUploaded,blocksForCompleteUpload , false );
+ updateCowStatsFile( blocksUploaded, blocksForCompleteUpload, false );
lastUpdateTime = time( NULL );
}
}
@@ -417,7 +422,7 @@ Counts blocks that have changes that have not yet been uploaded
*/
int countBlocksForUpload() {
int res = 0;
- int l1MaxOffset = ceil( metadata->imageSize / COW_L2_STORAGE_CAPACITY );
+ int l1MaxOffset = 1 + ((metadata->imageSize - 1) / COW_L2_STORAGE_CAPACITY);
for ( int l1Offset = 0; l1Offset < l1MaxOffset; l1Offset++ ) {
if ( cow.l1[l1Offset] == -1 ) {
continue;
@@ -473,15 +478,15 @@ bool cowfile_init(
{
char pathMeta[strlen( path ) + 6];
char pathData[strlen( path ) + 6];
- strcpy( pathMeta, path );
- strcpy( pathData, path );
- strcat( pathMeta, "/meta" );
+
+ snprintf( pathMeta, strlen( path ) + 6, "%s%s", path, "/meta" ) ;
+ snprintf( pathData, strlen( path ) + 6, "%s%s", path, "/data" ) ;
+
if ( ( cow.fhm = open( pathMeta, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR ) ) == -1 ) {
logadd( LOG_ERROR, "Could not create cow meta file. Bye.\n %s \n", pathMeta );
return false;
}
- strcat( pathData, "/data" );
if ( ( cow.fhd = open( pathData, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR ) ) == -1 ) {
logadd( LOG_ERROR, "Could not create cow data file. Bye.\n" );
return false;
@@ -530,7 +535,7 @@ bool cowfile_init(
metadata->metaDataStart = meta_data_start;
metadata->bitfieldSize = COW_BITFIELD_SIZE;
metadata->maxImageSize = cow.maxImageSize;
- strcpy( metadata->imageName, image_Name );
+ snprintf( metadata->imageName, 200, "%s", image_Name );
cow.l1 = (l1 *)( cow.metadata_mmap + meta_data_start );
metadata->nextL2 = 0;
@@ -578,10 +583,11 @@ bool cowfile_load( char *path, size_t **imageSizePtr, char *serverAddress )
cowServerAddress = serverAddress;
char pathMeta[strlen( path ) + 6];
char pathData[strlen( path ) + 6];
- strcpy( pathMeta, path );
- strcpy( pathData, path );
- strcat( pathMeta, "/meta" );
- strcat( pathData, "/data" );
+
+ snprintf( pathMeta, strlen( path ) + 6, "%s%s", path, "/meta" ) ;
+ snprintf( pathData, strlen( path ) + 6, "%s%s", path, "/data" ) ;
+
+
if ( ( cow.fhm = open( pathMeta, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR ) ) == -1 ) {
logadd( LOG_ERROR, "Could not open cow meta file. Bye.\n" );
return false;
@@ -661,9 +667,6 @@ bool cowfile_load( char *path, size_t **imageSizePtr, char *serverAddress )
cow.firstL2 = (l2 *)( ( (char *)cow.l1 ) + cow.l1Size );
-
- uuid_unparse( metadata->uuid, uuidStr );
-
createCowStatsFile( path );
pthread_mutex_init( &cow.l2CreateLock, NULL );
@@ -803,10 +806,11 @@ static void padBlockFromRemote( fuse_req_t req, off_t offset, cow_request_t *cow
{
if ( offset > (off_t)metadata->originalImageSize ) {
//pad 0 and done
- char buffer[DNBD3_BLOCK_SIZE] = { 0 };
- memcpy( buffer, buffer, size );
+ //TODO
+ char buf[DNBD3_BLOCK_SIZE] = { 0 };
+ memcpy( buf, buffer, size );
- writeData( buffer, DNBD3_BLOCK_SIZE, (ssize_t)size, cowRequest, block, inBlockOffset );
+ writeData( buf, DNBD3_BLOCK_SIZE, (ssize_t)size, cowRequest, block, inBlockOffset );
return;
}
cow_sub_request_t *sRequest = malloc( sizeof( cow_sub_request_t ) + DNBD3_BLOCK_SIZE );
@@ -1105,25 +1109,20 @@ fail:;
void createCowStatsFile( char* path ) {
- char pathStatus[strlen( path ) + 11];
- strcpy( pathStatus, path );
- strcat( pathStatus, "/status.txt" );
+ char pathStatus[strlen( path ) + 12];
+
+ snprintf( pathStatus, strlen( path ) + 12, "%s%s", path, "/status.txt") ;
+
if ( ( cow.fhs = open( pathStatus, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR ) ) == -1 ) {
logadd( LOG_ERROR, "Could not create cow status file. Bye.\n" );
return false;
}
char buffer[100];
- int len = snprintf( buffer, 100, "uuid: %s\nstate: active\n",uuidStr );
+ int len = snprintf( buffer, 100, "uuid: %s\nstate: active\n",metadata->uuid );
pwrite(cow.fhs, buffer, len, 0);
}
-void updateCowStatsFile( uint blocks, uint totalBlocks, bool done ) {
- char buffer[300];
- int len = snprintf( buffer, 100, "state: %s\nuploaded: %lu\ntotalBlocks: %lu\n", done?"done":"uploading" ,blocks, totalBlocks );
- pwrite( cow.fhs, buffer, len, 43 );
- ftruncate( cow.fhs, 43 + len );
-}
int cow_printStats( char *buffer, const size_t len ) {
@@ -1131,12 +1130,12 @@ int cow_printStats( char *buffer, const size_t len ) {
int ret = 0;
if(uploadLoop){
ret = snprintf( buffer, len, "uuid: %s\nstate: %s\ntotalBlocks: \n",
- uuidStr, "active");
+ metadata->uuid, "active");
}
if(!uploadLoop){
ret = snprintf( buffer, len, "uuidS %s\nstate: %s\ntotalBlocks: \nuploading: %lu/%lu\n",
- uuidStr, "uploading", blocksUploaded, blocksForCompleteUpload );
+ metadata->uuid, "uploading", blocksUploaded, blocksForCompleteUpload );
}
if ( ret < 0 ) {
ret = 0;
diff --git a/src/fuse/cowfile.h b/src/fuse/cowfile.h
index 416a1fd..b57f031 100644
--- a/src/fuse/cowfile.h
+++ b/src/fuse/cowfile.h
@@ -11,7 +11,6 @@
#include <string.h>
#include <pthread.h>
#include <errno.h>
-#include <uuid/uuid.h>
#include <curl/curl.h>
@@ -21,7 +20,7 @@
#define container_of( ptr, type, member ) ( (type *)( (char *)( ptr ) - (char *)&( ( (type *)NULL )->member ) ) )
-#define COW_METADATA_HEADER_SIZE 296
+#define COW_METADATA_HEADER_SIZE 317
typedef struct __attribute__( ( packed ) ) cowfile_metadata_header
{
uint64_t magicValue; // 8byte
@@ -36,7 +35,7 @@ typedef struct __attribute__( ( packed ) ) cowfile_metadata_header
atomic_size_t dataFileSize; // 8byte
uint64_t maxImageSize; // 8byte
uint64_t creationTime; // 8byte
- uuid_t uuid; // 16byte
+ char uuid[37]; // 37byte
char imageName[200]; // 200byte
} cowfile_metadata_header_t;
_Static_assert(