From cdbc0eea9eb7c71707cd3863ea9a29e00b781488 Mon Sep 17 00:00:00 2001 From: Jiyong Min Date: Thu, 2 Nov 2017 10:41:53 +0900 Subject: Apply security patch (revision:09b9e1da804ae6e254f14dc9a31df751255db595) - Fix security issues : SATIZENVUL-915, SATIZENVUL-926, SATIZENVUL-956 Change-Id: I1266213f645c33374ddedde27e918da0f2d54f65 Signed-off-by: Jiyong Min --- server/thumb-server-internal.c | 54 ++++++++++++++++++++++-------------- src/include/util/media-thumb-debug.h | 19 +++++++++++++ src/include/util/media-thumb-util.h | 1 + src/ipc/media-thumb-ipc.c | 23 +++++---------- src/media-thumb-internal.c | 46 ++++++++++++++++++------------ 5 files changed, 89 insertions(+), 54 deletions(-) diff --git a/server/thumb-server-internal.c b/server/thumb-server-internal.c index f42d1d8..3faddc7 100755 --- a/server/thumb-server-internal.c +++ b/server/thumb-server-internal.c @@ -246,17 +246,26 @@ static int __thumb_daemon_all_extract(uid_t uid) break; } - strncpy(path, (const char *)sqlite3_column_text(sqlite_stmt, 0), sizeof(path)); - path[sizeof(path) - 1] = '\0'; + SAFE_STRLCPY(path, (const char *)sqlite3_column_text(sqlite_stmt, 0), sizeof(path)); thumb_dbg_slog("Path : %s", path); if (g_idx == 0) { arr_path = (char**)malloc(sizeof(char*)); arr_uid = (uid_t*)malloc(sizeof(uid_t)); + if (arr_path == NULL || arr_uid == NULL) { + SAFE_FREE(arr_path); + SAFE_FREE(arr_uid); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } } else { arr_path = (char**)realloc(arr_path, (g_idx + 1) * sizeof(char*)); arr_uid = (uid_t*)realloc(arr_uid, (g_idx + 1) * sizeof(uid_t)); + if (arr_path == NULL || arr_uid == NULL) { + SAFE_FREE(arr_path); + SAFE_FREE(arr_uid); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } } arr_uid[g_idx] = uid; arr_path[g_idx++] = strdup(path); @@ -674,7 +683,6 @@ int _media_thumb_process(thumbMsg *req_msg, thumbMsg *res_msg) int thumb_h = 0; int origin_w = 0; int origin_h = 0; - int max_length = 0; char *thumb_path = NULL; int need_update_db = 0; int alpha = 0; @@ -691,9 +699,8 @@ int _media_thumb_process(thumbMsg *req_msg, thumbMsg *res_msg) media_thumb_format thumb_format = MEDIA_THUMB_BGRA; thumb_w = req_msg->thumb_width; thumb_h = req_msg->thumb_height; + memset(res_msg->dst_path, 0, MAX_FILEPATH_LEN); thumb_path = res_msg->dst_path; - thumb_path[0] = '\0'; - max_length = sizeof(res_msg->dst_path) -1; if (!g_file_test(origin_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { thumb_err("origin_path does not exist in file system."); @@ -707,7 +714,7 @@ int _media_thumb_process(thumbMsg *req_msg, thumbMsg *res_msg) } if (msg_type == THUMB_REQUEST_DB_INSERT) { - err = _media_thumb_get_thumb_from_db_with_size(origin_path, thumb_path, max_length, &need_update_db, &origin_w, &origin_h); + err = _media_thumb_get_thumb_from_db_with_size(origin_path, thumb_path, MAX_FILEPATH_LEN, &need_update_db, &origin_w, &origin_h); if (err == MS_MEDIA_ERR_NONE) { res_msg->origin_width = origin_w; res_msg->origin_height = origin_h; @@ -715,31 +722,27 @@ int _media_thumb_process(thumbMsg *req_msg, thumbMsg *res_msg) return MS_MEDIA_ERR_NONE; } else { if (strlen(thumb_path) == 0) { - err = _media_thumb_get_hash_name(origin_path, thumb_path, max_length, req_msg->uid); + err = _media_thumb_get_hash_name(origin_path, thumb_path, MAX_FILEPATH_LEN, req_msg->uid); if (err != MS_MEDIA_ERR_NONE) { thumb_err("_media_thumb_get_hash_name failed - %d", err); - strncpy(thumb_path, THUMB_EMPTY_STR, max_length); + SAFE_STRLCPY(thumb_path, THUMB_EMPTY_STR, MAX_FILEPATH_LEN); _media_thumb_db_disconnect(); return err; } - - thumb_path[strlen(thumb_path)] = '\0'; } } } else if (msg_type == THUMB_REQUEST_SAVE_FILE) { - strncpy(thumb_path, req_msg->dst_path, max_length); + SAFE_STRLCPY(thumb_path, req_msg->dst_path, MAX_FILEPATH_LEN); } else if (msg_type == THUMB_REQUEST_ALL_MEDIA) { - err = _media_thumb_get_hash_name(origin_path, thumb_path, max_length, req_msg->uid); + err = _media_thumb_get_hash_name(origin_path, thumb_path, MAX_FILEPATH_LEN, req_msg->uid); if (err != MS_MEDIA_ERR_NONE) { thumb_err("_media_thumb_get_hash_name failed - %d", err); - strncpy(thumb_path, THUMB_EMPTY_STR, max_length); + SAFE_STRLCPY(thumb_path, THUMB_EMPTY_STR, MAX_FILEPATH_LEN); _media_thumb_db_disconnect(); return err; } - - thumb_path[strlen(thumb_path)] = '\0'; } thumb_dbg_slog("Thumb path : %s", thumb_path); @@ -753,7 +756,7 @@ int _media_thumb_process(thumbMsg *req_msg, thumbMsg *res_msg) if (err != MS_MEDIA_ERR_NONE) { thumb_err("_thumbnail_get_data failed - %d", err); SAFE_FREE(data); - strncpy(thumb_path, THUMB_EMPTY_STR, max_length); + SAFE_STRLCPY(thumb_path, THUMB_EMPTY_STR, MAX_FILEPATH_LEN); goto DB_UPDATE; } @@ -785,7 +788,7 @@ int _media_thumb_process(thumbMsg *req_msg, thumbMsg *res_msg) SAFE_FREE(data); if (msg_type == THUMB_REQUEST_DB_INSERT || msg_type == THUMB_REQUEST_ALL_MEDIA) { - strncpy(thumb_path, THUMB_EMPTY_STR, max_length); + SAFE_STRLCPY(thumb_path, THUMB_EMPTY_STR, MAX_FILEPATH_LEN); } _media_thumb_db_disconnect(); return err; @@ -846,21 +849,30 @@ _media_thumb_process_raw(thumbMsg *req_msg, thumbMsg *res_msg) thumb_w = req_msg->thumb_width; thumb_h = req_msg->thumb_height; - err = _thumbnail_get_raw_data(origin_path, thumb_format, &thumb_w, &thumb_h, &data, &thumb_size); + res_msg->msg_type = THUMB_RESPONSE_RAW_DATA; + err = _thumbnail_get_raw_data(origin_path, thumb_format, &thumb_w, &thumb_h, &data, &thumb_size); if (err != MS_MEDIA_ERR_NONE) { thumb_err("_thumbnail_get_data failed - %d", err); + res_msg->status = err; + res_msg->thumb_size = 0; SAFE_FREE(data); + + return err; } - res_msg->msg_type = THUMB_RESPONSE_RAW_DATA; res_msg->thumb_width = thumb_w; res_msg->thumb_height = thumb_h; res_msg->thumb_size = thumb_size; res_msg->thumb_data = malloc(thumb_size * sizeof(unsigned char)); - memcpy(res_msg->thumb_data, data, thumb_size); + if (res_msg->thumb_data != NULL) { + memcpy(res_msg->thumb_data, data, thumb_size); + } else { + thumb_err("Allocation failed"); + err = MS_MEDIA_ERR_OUT_OF_MEMORY; + } SAFE_FREE(data); - return MS_MEDIA_ERR_NONE; + return err; } diff --git a/src/include/util/media-thumb-debug.h b/src/include/util/media-thumb-debug.h index 66ae59e..3a9bd34 100755 --- a/src/include/util/media-thumb-debug.h +++ b/src/include/util/media-thumb-debug.h @@ -72,6 +72,25 @@ LOGE(FONT_COLOR_RED fmt" : standard error [%s]", strerror_r(errno, thumb_stderror_buffer, ERR_BUF_LENGHT)); \ } while (0) +#define thumb_retm_if(expr, fmt, arg...) do { \ + if (expr) { \ + LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg); \ + return; \ + } \ + } while (0) +#define thumb_retv_if(expr, val) do { \ + if (expr) { \ + LOGE(FONT_COLOR_RED""FONT_COLOR_RESET); \ + return (val); \ + } \ + } while (0) +#define thumb_retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg); \ + return (val); \ + } \ + } while (0) + #ifdef _USE_LOG_FILE_ void thumb_init_file_debug(); void thumb_close_file_debug(); diff --git a/src/include/util/media-thumb-util.h b/src/include/util/media-thumb-util.h index 9c2e4d3..73838ae 100755 --- a/src/include/util/media-thumb-util.h +++ b/src/include/util/media-thumb-util.h @@ -28,6 +28,7 @@ #define SAFE_FREE(src) { if (src) {free(src); src = NULL;}} #define THUMB_MALLOC(src, size) { if (size <= 0) {src = NULL;} \ else { src = malloc(size); if (src) memset(src, 0x0, size);} } +#define SAFE_STRLCPY(dst, src, n) g_strlcpy(dst, src, n); typedef enum { MEDIA_THUMB_BGRA, /* BGRA, especially provided for evas users */ diff --git a/src/ipc/media-thumb-ipc.c b/src/ipc/media-thumb-ipc.c index 29ce6b1..1edde11 100755 --- a/src/ipc/media-thumb-ipc.c +++ b/src/ipc/media-thumb-ipc.c @@ -560,7 +560,7 @@ _media_thumb_request(int msg_type, const char *origin_path, char *thumb_path, in memset(&serv_addr, 0, sizeof(serv_addr)); sock = sock_info.sock_fd; serv_addr.sun_family = AF_UNIX; - strncpy(serv_addr.sun_path, THUMB_IPC_PATH, strlen(THUMB_IPC_PATH)); + SAFE_STRLCPY(serv_addr.sun_path, THUMB_IPC_PATH, sizeof(serv_addr.sun_path)); /* Connecting to the thumbnail server */ if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { @@ -582,14 +582,7 @@ _media_thumb_request(int msg_type, const char *origin_path, char *thumb_path, in /* Set requset message */ req_msg.msg_type = msg_type; req_msg.uid = uid; - strncpy(req_msg.org_path, origin_path, sizeof(req_msg.org_path)); - req_msg.org_path[strlen(req_msg.org_path)] = '\0'; - - if (msg_type == THUMB_REQUEST_SAVE_FILE) { - strncpy(req_msg.dst_path, thumb_path, sizeof(req_msg.dst_path)); - req_msg.dst_path[strlen(req_msg.dst_path)] = '\0'; - } - + SAFE_STRLCPY(req_msg.org_path, origin_path, sizeof(req_msg.org_path)); req_msg.origin_path_size = strlen(req_msg.org_path) + 1; req_msg.dest_path_size = strlen(req_msg.dst_path) + 1; req_msg.thumb_size = 0; @@ -642,7 +635,7 @@ _media_thumb_request(int msg_type, const char *origin_path, char *thumb_path, in } if (msg_type != THUMB_REQUEST_SAVE_FILE) { - strncpy(thumb_path, recv_msg.dst_path, max_length); + SAFE_STRLCPY(thumb_path, recv_msg.dst_path, max_length); } thumb_info->origin_width = recv_msg.origin_width; @@ -782,7 +775,7 @@ int _media_thumb_send_request() memset(&serv_addr, 0, sizeof(serv_addr)); sock = sock_info.sock_fd; serv_addr.sun_family = AF_UNIX; - strncpy(serv_addr.sun_path, THUMB_IPC_PATH, strlen(THUMB_IPC_PATH)); + SAFE_STRLCPY(serv_addr.sun_path, THUMB_IPC_PATH, sizeof(serv_addr.sun_path)); GIOChannel *channel = NULL; channel = g_io_channel_unix_new(sock); @@ -827,8 +820,7 @@ int _media_thumb_send_request() req_msg.msg_type = req_manager->msg_type; req_msg.request_id = 0; req_msg.uid = req_manager->uid; - strncpy(req_msg.org_path, req_manager->path, sizeof(req_msg.org_path)); - req_msg.org_path[strlen(req_msg.org_path)] = '\0'; + SAFE_STRLCPY(req_msg.org_path, req_manager->path, sizeof(req_msg.org_path)); req_msg.dst_path[0] = '\0'; req_msg.origin_path_size = strlen(req_msg.org_path) + 1; req_msg.dest_path_size = 1; @@ -902,7 +894,7 @@ int _media_thumb_raw_data_send_request() memset(&serv_addr, 0, sizeof(serv_addr)); sock = sock_info.sock_fd; serv_addr.sun_family = AF_UNIX; - strncpy(serv_addr.sun_path, THUMB_IPC_PATH, strlen(THUMB_IPC_PATH)); + SAFE_STRLCPY(serv_addr.sun_path, THUMB_IPC_PATH, sizeof(serv_addr.sun_path)); GIOChannel *channel = NULL; channel = g_io_channel_unix_new(sock); @@ -948,8 +940,7 @@ int _media_thumb_raw_data_send_request() req_msg.thumb_height = req_manager->height; req_msg.uid = req_manager->uid; - strncpy(req_msg.org_path, req_manager->path, sizeof(req_msg.org_path)); - req_msg.org_path[strlen(req_msg.org_path)] = '\0'; + SAFE_STRLCPY(req_msg.org_path, req_manager->path, sizeof(req_msg.org_path)); req_msg.dst_path[0] = '\0'; req_msg.origin_path_size = strlen(req_msg.org_path) + 1; diff --git a/src/media-thumb-internal.c b/src/media-thumb-internal.c index dfa825b..180f8de 100755 --- a/src/media-thumb-internal.c +++ b/src/media-thumb-internal.c @@ -368,20 +368,31 @@ int _media_thumb_get_exif_info(ExifData *ed, char *buf, int max_size, int *value ExifByteOrder mByteOrder = exif_data_get_byte_order(ed); short exif_value = exif_get_short(entry->data, mByteOrder); *value = (int)exif_value; - } else { - /* Get the contents of the tag in human-readable form */ - if (buf == NULL) { - thumb_err("buf is NULL"); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - exif_entry_get_value(entry, buf, max_size); - buf[strlen(buf)] = '\0'; } } return MS_MEDIA_ERR_NONE; } +static int __media_thumb_safe_atoi(char *buffer, int *si) +{ + char *end = NULL; + errno = 0; + thumb_retvm_if(buffer == NULL || si == NULL, MS_MEDIA_ERR_INTERNAL, "invalid parameter"); + + const long sl = strtol(buffer, &end, 10); + + thumb_retvm_if(end == buffer, MS_MEDIA_ERR_INTERNAL, "not a decimal number"); + thumb_retvm_if('\0' != *end, MS_MEDIA_ERR_INTERNAL, "extra characters at end of input: %s", end); + thumb_retvm_if((LONG_MIN == sl || LONG_MAX == sl) && (ERANGE == errno), MS_MEDIA_ERR_INTERNAL, "out of range of type long"); + thumb_retvm_if(sl > INT_MAX, MS_MEDIA_ERR_INTERNAL, "greater than INT_MAX"); + thumb_retvm_if(sl < INT_MIN, MS_MEDIA_ERR_INTERNAL, "less than INT_MIN"); + + *si = (int)sl; + + return MS_MEDIA_ERR_NONE; +} + static int _media_thumb_get_data_from_exif(ExifData *ed, void **thumb_data, int *thumb_size, @@ -419,7 +430,12 @@ static int _media_thumb_get_data_from_exif(ExifData *ed, /* copy the real thumbnail data from exif data */ if (ed->data && ed->size) { - //thumb_dbg("Size: %d, thumb: 0x%x", ed->size, ed->data); + /* NOTICE : ExifData->size type is unsigned int, But Internal IPC, and CAPI use int */ + if (ed->size > INT_MAX) { + thumb_err("EXIF thumbnail size is over INT_MAX"); + return MS_MEDIA_ERR_THUMB_TOO_BIG; + } + *thumb_data = (char *)malloc(ed->size); if (*thumb_data == NULL) { @@ -442,8 +458,7 @@ static int _media_thumb_get_data_from_exif(ExifData *ed, /* Get the contents of the tag in human-readable form */ char width[10] = {0,}; exif_entry_get_value(entry, width, 10); - - *thumb_width = atoi(width); + __media_thumb_safe_atoi(width, thumb_width); } else { thumb_warn("EXIF_TAG_IMAGE_WIDTH does not exist"); *thumb_width = 0; @@ -455,8 +470,7 @@ static int _media_thumb_get_data_from_exif(ExifData *ed, /* Get the contents of the tag in human-readable form */ char height[10] = {0, }; exif_entry_get_value(entry, height, 10); - - *thumb_height = atoi(height); + __media_thumb_safe_atoi(height, thumb_height); } else { thumb_warn("EXIF_TAG_IMAGE_LENGTH does not exist"); *thumb_height = 0; @@ -472,8 +486,7 @@ static int _media_thumb_get_data_from_exif(ExifData *ed, if (entry) { char width[10] = {0,}; exif_entry_get_value(entry, width, 10); - - *origin_width = atoi(width); + __media_thumb_safe_atoi(width, origin_width); } else { thumb_warn("EXIF_TAG_PIXEL_X_DIMENSION does not exist"); *origin_width = 0; @@ -485,8 +498,7 @@ static int _media_thumb_get_data_from_exif(ExifData *ed, if (entry) { char height[10] = {0, }; exif_entry_get_value(entry, height, 10); - - *origin_height = atoi(height); + __media_thumb_safe_atoi(height, origin_height); } else { thumb_warn("EXIF_TAG_PIXEL_Y_DIMENSION does not exist"); *origin_height = 0; -- cgit v1.2.3