Skip to content
Draft
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
15 changes: 13 additions & 2 deletions osquery/tables/system/posix/sudoers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,16 @@ void genSudoersFile(const std::string& filename,

if (is_includedir) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔴 genSudoersFile ignores unchecked substr/at() calls on possibly malformed sudoers lines

In genSudoersFile (osquery/tables/system/posix/sudoers.cpp), the two rule_details.at(0) calls under the is_includedir and is_include branches are now guarded with !rule_details.empty() before indexing, and an explicit empty-string check (with a TLOG message and continue) was added right after each path-normalization block to avoid passing an empty string into listFilesInDirectory/recursive genSudoersFile calls. This removes the possibility of an uncaught std::out_of_range from .at(0) on a malformed/empty rule_details value while preserving existing control flow and style.

🤖 Prompt for AI agents
In osquery/tables/system/posix/sudoers.cpp around line 118, review and complete this code-review fix: genSudoersFile ignores unchecked substr/at() calls on possibly malformed sudoers lines.
What the draft fix changed: In genSudoersFile (osquery/tables/system/posix/sudoers.cpp), the two `rule_details.at(0)` calls under the `is_includedir` and `is_include` branches are now guarded with `!rule_details.empty()` before indexing, and an explicit empty-string check (with a TLOG message and `continue`) was added right after each path-normalization block to avoid passing an empty string into `listFilesInDirectory`/recursive `genSudoersFile` calls. This removes the possibility of an uncaught `std::out_of_range` from `.at(0)` on a malformed/empty rule_details value while preserving existing control flow and style.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 85 medium — react 👍/👎 to teach the reviewer

// support both relative and full paths
if (rule_details.at(0) != '/') {
if (!rule_details.empty() && rule_details.at(0) != '/') {
auto path = fs::path(filename).parent_path() / rule_details;
rule_details = path.string();
}

if (rule_details.empty()) {
TLOG << "Empty includedir target in sudoers file: " << filename;
continue;
}

std::vector<std::string> inc_files;
if (!listFilesInDirectory(rule_details, inc_files).ok()) {
TLOG << "Could not list includedir: " << rule_details;
Expand All @@ -144,11 +149,16 @@ void genSudoersFile(const std::string& filename,
}
if (is_include) {
// support both relative and full paths
if (rule_details.at(0) != '/') {
if (!rule_details.empty() && rule_details.at(0) != '/') {
auto path = fs::path(filename).parent_path() / rule_details;
rule_details = path.string();
}

if (rule_details.empty()) {
TLOG << "Empty include target in sudoers file: " << filename;
continue;
}

genSudoersFile(rule_details, ++level, results);
}
}
Expand All @@ -167,3 +177,4 @@ QueryData genSudoers(QueryContext& context) {
}
} // namespace tables
} // namespace osquery

Loading