Skip to content

Commit

Permalink
Fix crash when carve size is stored as string (osquery#8297)
Browse files Browse the repository at this point in the history
  • Loading branch information
zwass authored May 3, 2024
1 parent 7bc7f39 commit f3da9aa
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 37 deletions.
2 changes: 1 addition & 1 deletion osquery/carver/carver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ Status Carver::carve() {
}

PlatformFile uploadFile(uploadPath, PF_OPEN_EXISTING | PF_READ);
updateCarveValue(carveGuid_, "size", std::to_string(uploadFile.size()));
updateCarveValue(carveGuid_, "size", uploadFile.size());

std::string uploadHash =
(uploadFile.size() > FLAGS_read_max)
Expand Down
32 changes: 0 additions & 32 deletions osquery/carver/carver_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,38 +29,6 @@ CLI_FLAG(bool,

std::atomic<bool> kCarverPendingCarves{true};

/// Helper function to update values related to a carve
void updateCarveValue(const std::string& guid,
const std::string& key,
const std::string& value) {
std::string carve;
auto s = getDatabaseValue(kCarves, kCarverDBPrefix + guid, carve);
if (!s.ok()) {
VLOG(1) << "Failed to update status of carve in database " << guid;
return;
}

JSON tree;
s = tree.fromString(carve);
if (!s.ok()) {
VLOG(1) << "Failed to parse carve entries: " << s.what();
return;
}

tree.add(key, value);

std::string out;
s = tree.toString(out);
if (!s.ok()) {
VLOG(1) << "Failed to serialize carve entries: " << s.what();
}

s = setDatabaseValue(kCarves, kCarverDBPrefix + guid, out);
if (!s.ok()) {
VLOG(1) << "Failed to update status of carve in database " << guid;
}
}

std::string createCarveGuid() {
return boost::uuids::to_string(boost::uuids::random_generator()());
}
Expand Down
32 changes: 31 additions & 1 deletion osquery/carver/carver_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#pragma once

#include <osquery/database/database.h>
#include <osquery/logger/logger.h>
#include <osquery/utils/status/status.h>

#include <atomic>
Expand Down Expand Up @@ -46,9 +48,37 @@ const std::string kCarverStatusScheduled = "SCHEDULED";
extern std::atomic<bool> kCarverPendingCarves;

/// Update an attribute for a given carve GUID.
template <typename T>
void updateCarveValue(const std::string& guid,
const std::string& key,
const std::string& value);
const T& value) {
std::string carve;
auto s = getDatabaseValue(kCarves, kCarverDBPrefix + guid, carve);
if (!s.ok()) {
VLOG(1) << "Failed to update status of carve in database " << guid;
return;
}

JSON tree;
s = tree.fromString(carve);
if (!s.ok()) {
VLOG(1) << "Failed to parse carve entries: " << s.what();
return;
}

tree.add(key, value);

std::string out;
s = tree.toString(out);
if (!s.ok()) {
VLOG(1) << "Failed to serialize carve entries: " << s.what();
}

s = setDatabaseValue(kCarves, kCarverDBPrefix + guid, out);
if (!s.ok()) {
VLOG(1) << "Failed to update status of carve in database " << guid;
}
}

/// Returns a UUID.
std::string createCarveGuid();
Expand Down
13 changes: 10 additions & 3 deletions osquery/tables/forensic/carves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,14 @@ void enumerateCarves(QueryData& results, const std::string& new_guid) {
}

if (tree.doc().HasMember("size")) {
r["size"] = INTEGER(tree.doc()["size"].GetInt());
// In some instances, it was observed that the size is stored as a JSON
// string rather than number, resulting in an exception if GetInt was
// called. Check for the type for backwards compatibility.
if (tree.doc()["size"].IsInt()) {
r["size"] = INTEGER(tree.doc()["size"].GetInt());
} else {
r["size"] = INTEGER(tree.doc()["size"].GetString());
}
}

stringToRow("sha256", r, tree);
Expand Down Expand Up @@ -108,5 +115,5 @@ QueryData genCarves(QueryContext& context) {

return results;
}
}
}
} // namespace tables
} // namespace osquery

0 comments on commit f3da9aa

Please sign in to comment.