summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Jones <dajones716@gmail.com>2017-06-14 17:28:51 -0700
committerMax Illfelder <illfelder@users.noreply.github.com>2017-06-14 17:28:51 -0700
commit63ef48831e8d8a8d8e086bb634a85e1051da16c9 (patch)
treee77b48aaeae988d289d3cda713f6626ac6397a20
parent00ea903015a6d86040583e4cb5eec40aa0231786 (diff)
downloadgoogle-compute-image-packages-oslogin.tar.gz
Add stricter type checking for JSON parse methods. (#413)oslogin
Some json-c methods, such as json_object_object_foreach, will segfault if they are given a given a json_object of a different type than expected. This meant that a malformed response from the metadata server could cause a segfault in the guest. This adds stricter type checking around these calls to cleanly handle malformed responses.
-rw-r--r--google_compute_engine_oslogin/utils/oslogin_utils.cc31
1 files changed, 31 insertions, 0 deletions
diff --git a/google_compute_engine_oslogin/utils/oslogin_utils.cc b/google_compute_engine_oslogin/utils/oslogin_utils.cc
index 50eaa50..505165b 100644
--- a/google_compute_engine_oslogin/utils/oslogin_utils.cc
+++ b/google_compute_engine_oslogin/utils/oslogin_utils.cc
@@ -114,6 +114,9 @@ bool NssCache::LoadJsonArrayToCache(string response) {
page_token_ = "";
return false;
}
+ if (json_object_get_type(login_profiles) != json_type_array) {
+ return false;
+ }
int arraylen = json_object_array_length(login_profiles);
if (arraylen == 0 || arraylen > cache_size_) {
page_token_ = "";
@@ -226,6 +229,9 @@ std::vector<string> ParseJsonToSshKeys(string response) {
if (!json_object_object_get_ex(root, "loginProfiles", &login_profiles)) {
return result;
}
+ if (json_object_get_type(login_profiles) != json_type_array) {
+ return result;
+ }
login_profiles = json_object_array_get_idx(login_profiles, 0);
json_object* ssh_public_keys = NULL;
@@ -234,19 +240,32 @@ std::vector<string> ParseJsonToSshKeys(string response) {
return result;
}
+ if (json_object_get_type(ssh_public_keys) != json_type_object) {
+ return result;
+ }
json_object_object_foreach(ssh_public_keys, key, val) {
json_object* iter;
if (!json_object_object_get_ex(ssh_public_keys, key, &iter)) {
return result;
}
+ if (json_object_get_type(iter) != json_type_object) {
+ continue;
+ }
string key_to_add = "";
bool expired = false;
json_object_object_foreach(iter, key, val) {
string string_key(key);
+ int val_type = json_object_get_type(val);
if (string_key == "key") {
+ if (val_type != json_type_string) {
+ continue;
+ }
key_to_add = (char*)json_object_get_string(val);
}
if (string_key == "expiration_time_usec") {
+ if (val_type != json_type_int) {
+ continue;
+ }
uint64_t expiry_usec = (uint64_t)json_object_get_int64(val);
struct timeval tp;
gettimeofday(&tp, NULL);
@@ -272,6 +291,9 @@ bool ParseJsonToPasswd(string response, struct passwd* result,
json_object* login_profiles = NULL;
// If this is called from getpwent_r, loginProfiles won't be in the response.
if (json_object_object_get_ex(root, "loginProfiles", &login_profiles)) {
+ if (json_object_get_type(login_profiles) != json_type_array) {
+ return false;
+ }
root = login_profiles;
root = json_object_array_get_idx(root, 0);
}
@@ -281,6 +303,9 @@ bool ParseJsonToPasswd(string response, struct passwd* result,
*errnop = ENOENT;
return false;
}
+ if (json_object_get_type(posix_accounts) != json_type_array) {
+ return false;
+ }
posix_accounts = json_object_array_get_idx(posix_accounts, 0);
// Populate with some default values that ValidatePasswd can detect if they
@@ -291,6 +316,9 @@ bool ParseJsonToPasswd(string response, struct passwd* result,
result->pw_dir = (char*)"";
// Iterate through the json response and populate the passwd struct.
+ if (json_object_get_type(posix_accounts) != json_type_object) {
+ return false;
+ }
json_object_object_foreach(posix_accounts, key, val) {
int val_type = json_object_get_type(val);
// Convert char* to c++ string for easier comparison.
@@ -352,6 +380,9 @@ string ParseJsonToEmail(string response) {
if (!json_object_object_get_ex(root, "loginProfiles", &login_profiles)) {
return "";
}
+ if (json_object_get_type(login_profiles) != json_type_array) {
+ return "";
+ }
login_profiles = json_object_array_get_idx(login_profiles, 0);
json_object* email = NULL;
if (!json_object_object_get_ex(login_profiles, "name", &email)) {