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

Malloc off by one #33

Merged
merged 2 commits into from
Jun 5, 2020
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
4 changes: 3 additions & 1 deletion scripts/lava.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ def __str__(self):
"ATP_POINTER_WRITE",
"ATP_QUERY_POINT",
"ATP_PRINTF_LEAK",
"ATP_MALLOC_OFF_BY_ONE"
]
return 'ATP[{}](loc={}:{}, type={})'.format(
self.id, self.loc.filename, self.loc.begin.line, type_strs[self.typ]
Expand All @@ -181,9 +182,10 @@ class Bug(Base):
RET_BUFFER = 1
REL_WRITE = 2
PRINTF_LEAK = 3
MALLOC_OFF_BY_ONE = 4
# };
type_strings = ['BUG_PTR_ADD', 'BUG_RET_BUFFER',
'BUG_REL_WRITE', 'BUG_PRINTF_LEAK']
'BUG_REL_WRITE', 'BUG_PRINTF_LEAK', 'MALLOC_OFF_BY_ONE']

id = Column(BigInteger, primary_key=True)
type = Column(Integer)
Expand Down
2 changes: 1 addition & 1 deletion scripts/lava.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ demo=0
curtail=0
ATP_TYPE=""
# default bugtypes
bugtypes="ptr_add,rel_write"
bugtypes="ptr_add,rel_write,malloc_off_by_one"
# default # of bugs to be injected at a time
many=50

Expand Down
3 changes: 3 additions & 0 deletions tools/fbi/src/find_bug_inj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,9 @@ void attack_point_lval_usage(Panda__LogEntry *ple) {
case AttackPoint::PRINTF_LEAK:
record_injectable_bugs_at<Bug::PRINTF_LEAK>(atp, is_new_atp, { });
break;
case AttackPoint::MALLOC_OFF_BY_ONE:
record_injectable_bugs_at<Bug::MALLOC_OFF_BY_ONE>(atp, is_new_atp, { });
break;
}
t.commit();
}
Expand Down
5 changes: 5 additions & 0 deletions tools/lavaODB/include/lava.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ struct AttackPoint {
POINTER_WRITE,
QUERY_POINT,
PRINTF_LEAK,
MALLOC_OFF_BY_ONE,
TYPE_END
} type;

Expand All @@ -333,6 +334,7 @@ struct AttackPoint {
"ATP_POINTER_WRITE",
"ATP_QUERY_POINT",
"ATP_PRINTF_LEAK",
"ATP_MALLOC_OFF_BY_ONE"
};
os << "ATP [" << m.loc.filename << " " << m.loc.begin << "] {";
os << names[m.type] << "}";
Expand All @@ -350,13 +352,16 @@ struct Bug {
RET_BUFFER,
REL_WRITE,
PRINTF_LEAK,
MALLOC_OFF_BY_ONE,
TYPE_END
} type;

static constexpr uint32_t const num_extra_duas[] = {
[PTR_ADD] = 0,
[RET_BUFFER] = 1,
[REL_WRITE] = 2,
[PRINTF_LEAK] = 0,
[MALLOC_OFF_BY_ONE] = 0,
};

#pragma db not_null
Expand Down
52 changes: 52 additions & 0 deletions tools/lavaTool/include/MallocOffByOneArgHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef MALLOC_OFF_BY_ONE_H
#define MALLOC_OFF_BY_ONE_H

using namespace clang;

struct MallocOffByOneArgHandler : public LavaMatchHandler {
using LavaMatchHandler::LavaMatchHandler;

virtual void handle(const MatchFinder::MatchResult &Result) {
const SourceManager &sm = *Result.SourceManager;
const CallExpr *callExpr = Result.Nodes.getNodeAs<CallExpr>("call_expression");

if (ArgDataflow) {
auto fnname = get_containing_function_name(Result, *callExpr);

// only instrument this printf with a read disclosure
// if it's in the body of a function that is on our whitelist
if (fninstr(fnname)) {
debug(INJECT) << "MallocOffByOneHandler: Containing function is in whitelist " << fnname.second << " : " << fnname.first << "\n";
}
else {
debug(INJECT) << "MallocOffByOneHandler: Containing function is NOT in whitelist " << fnname.second << " : " << fnname.first << "\n";
return;
}

debug(INJECT) << "MallocOffByOneHandler handle: ok to instrument " << fnname.second << "\n";
}

LExpr addend = LDecimal(0);
const Expr *size_arg = callExpr->getArg(callExpr->getNumArgs() - 1);
if (size_arg) {
LavaASTLoc ast_loc = GetASTLoc(sm, size_arg);
Mod.Change(size_arg);
if (LavaAction == LavaQueries) {
addend = LavaAtpQuery(ast_loc,
AttackPoint::MALLOC_OFF_BY_ONE);
num_atp_queries++;
Mod.Add(addend, nullptr);
} else if (LavaAction == LavaInjectBugs) {

const std::vector<const Bug*> &injectable_bugs =
map_get_default(bugs_with_atp_at,
std::make_pair(ast_loc, AttackPoint::MALLOC_OFF_BY_ONE));
for (const Bug *bug : injectable_bugs) {
Mod.Parenthesize().InsertBefore(Test(bug).render() + " ? (" + ExprStr(size_arg) + " - 1 ) : ");
}
}
}
}
};

#endif
7 changes: 7 additions & 0 deletions tools/lavaTool/include/MatchFinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "FunctionPointerFieldHandler.h"
#include "CallExprArgAdditionalHandler.h"
#include "FunctionPointerTypedefHandler.h"
#include "MallocOffByOneArgHandler.h"

// Must match value in scripts/fninstr.py
//#define IGNORE_FN_PTRS
Expand Down Expand Up @@ -151,6 +152,12 @@ class LavaMatchFinder : public MatchFinder, public SourceFileCallbacks {
makeHandler<ReadDisclosureHandler>()
); */
}

addMatcher(
callExpr(
callee(functionDecl(hasName("malloc")))).bind("call_expression"),
makeHandler<MallocOffByOneArgHandler>()
);
}
virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) override {
Insert.clear();
Expand Down