Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.7.4 #249

Merged
merged 2 commits into from
Mar 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
1.7.2
1.7.4
=====
Fixes:
------
* Fix potential use after free if the `string` parameter to `cJSON_AddItemToObject` is an alias of the `string` property of the object that is added (#248). Thanks @hhallen for reporting.

1.7.3
=====
Fixes:
------
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ include(GNUInstallDirs)

set(PROJECT_VERSION_MAJOR 1)
set(PROJECT_VERSION_MINOR 7)
set(PROJECT_VERSION_PATCH 3)
set(PROJECT_VERSION_PATCH 4)
set(CJSON_VERSION_SO 1)
set(CJSON_UTILS_VERSION_SO 1)
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ CJSON_TEST_SRC = cJSON.c test.c

LDLIBS = -lm

LIBVERSION = 1.7.3
LIBVERSION = 1.7.4
CJSON_SOVERSION = 1
UTILS_SOVERSION = 1

Expand Down
29 changes: 17 additions & 12 deletions cJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) {
}

/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 3)
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 4)
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
#endif

Expand Down Expand Up @@ -1895,33 +1895,38 @@ static void* cast_away_const(const void* string)

static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
{
char *new_key = NULL;
int new_type = cJSON_Invalid;

if ((object == NULL) || (string == NULL) || (item == NULL))
{
return false;
}

if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
{
hooks->deallocate(item->string);
}

if (constant_key)
{
item->string = (char*)cast_away_const(string);
item->type |= cJSON_StringIsConst;
new_key = (char*)cast_away_const(string);
new_type = item->type | cJSON_StringIsConst;
}
else
{
char *key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
if (key == NULL)
new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
if (new_key == NULL)
{
return false;
}

item->string = key;
item->type &= ~cJSON_StringIsConst;
new_type = item->type & ~cJSON_StringIsConst;
}

if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
{
hooks->deallocate(item->string);
}

item->string = new_key;
item->type = new_type;

return add_item_to_array(object, item);
}

Expand Down
2 changes: 1 addition & 1 deletion cJSON.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extern "C"
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 3
#define CJSON_VERSION_PATCH 4

#include <stddef.h>

Expand Down
20 changes: 20 additions & 0 deletions tests/misc_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,25 @@ static void cjson_create_array_reference_should_create_an_array_reference(void)
cJSON_Delete(number_reference);
}

static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased(void)
{
cJSON *object = cJSON_CreateObject();
cJSON *number = cJSON_CreateNumber(42);
char *name = (char*)cJSON_strdup((const unsigned char*)"number", &global_hooks);

TEST_ASSERT_NOT_NULL(object);
TEST_ASSERT_NOT_NULL(number);
TEST_ASSERT_NOT_NULL(name);

number->string = name;

/* The following should not have a use after free
* that would show up in valgrind or with AddressSanitizer */
cJSON_AddItemToObject(object, number->string, number);

cJSON_Delete(object);
}

int main(void)
{
UNITY_BEGIN();
Expand All @@ -530,6 +549,7 @@ int main(void)
RUN_TEST(cjson_create_string_reference_should_create_a_string_reference);
RUN_TEST(cjson_create_object_reference_should_create_an_object_reference);
RUN_TEST(cjson_create_array_reference_should_create_an_array_reference);
RUN_TEST(cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased);

return UNITY_END();
}