Skip to content

Commit

Permalink
Merge pull request #33 from jvijtiuk/malloc-off-by-one
Browse files Browse the repository at this point in the history
Malloc off by one
  • Loading branch information
AndrewFasano authored Jun 5, 2020
2 parents 41efcf3 + 5170f67 commit 1a3f3a5
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 2 deletions.
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

0 comments on commit 1a3f3a5

Please sign in to comment.