Commit 3fef513c authored by yonghong-song's avatar yonghong-song Committed by GitHub

Merge pull request #1733 from pchaigno/fix-probesetter-memberexpr

Fix dereference replacements for structure members
parents be7955b7 0cdf296a
...@@ -105,6 +105,13 @@ class ProbeChecker : public RecursiveASTVisitor<ProbeChecker> { ...@@ -105,6 +105,13 @@ class ProbeChecker : public RecursiveASTVisitor<ProbeChecker> {
} }
return false; return false;
} }
bool VisitMemberExpr(MemberExpr *M) {
if (ptregs_.find(M->getMemberDecl()) != ptregs_.end()) {
needs_probe_ = true;
return false;
}
return true;
}
bool VisitDeclRefExpr(DeclRefExpr *E) { bool VisitDeclRefExpr(DeclRefExpr *E) {
if (ptregs_.find(E->getDecl()) != ptregs_.end()) if (ptregs_.find(E->getDecl()) != ptregs_.end())
needs_probe_ = true; needs_probe_ = true;
...@@ -126,6 +133,10 @@ class ProbeSetter : public RecursiveASTVisitor<ProbeSetter> { ...@@ -126,6 +133,10 @@ class ProbeSetter : public RecursiveASTVisitor<ProbeSetter> {
ptregs_->insert(E->getDecl()); ptregs_->insert(E->getDecl());
return true; return true;
} }
bool VisitMemberExpr(MemberExpr *M) {
ptregs_->insert(M->getMemberDecl());
return false;
}
private: private:
set<Decl *> *ptregs_; set<Decl *> *ptregs_;
}; };
...@@ -231,11 +242,6 @@ bool ProbeVisitor::VisitUnaryOperator(UnaryOperator *E) { ...@@ -231,11 +242,6 @@ bool ProbeVisitor::VisitUnaryOperator(UnaryOperator *E) {
bool ProbeVisitor::VisitMemberExpr(MemberExpr *E) { bool ProbeVisitor::VisitMemberExpr(MemberExpr *E) {
if (memb_visited_.find(E) != memb_visited_.end()) return true; if (memb_visited_.find(E) != memb_visited_.end()) return true;
// Checks to see if the expression references something that needs to be run
// through bpf_probe_read.
if (!ProbeChecker(E, ptregs_).needs_probe())
return true;
Expr *base; Expr *base;
SourceLocation rhs_start, member; SourceLocation rhs_start, member;
bool found = false; bool found = false;
...@@ -255,6 +261,12 @@ bool ProbeVisitor::VisitMemberExpr(MemberExpr *E) { ...@@ -255,6 +261,12 @@ bool ProbeVisitor::VisitMemberExpr(MemberExpr *E) {
error(base->getLocEnd(), "internal error: MemberLoc is invalid while preparing probe rewrite"); error(base->getLocEnd(), "internal error: MemberLoc is invalid while preparing probe rewrite");
return false; return false;
} }
// Checks to see if the expression references something that needs to be run
// through bpf_probe_read.
if (!ProbeChecker(base, ptregs_).needs_probe())
return true;
string rhs = rewriter_.getRewrittenText(expansionRange(SourceRange(rhs_start, E->getLocEnd()))); string rhs = rewriter_.getRewrittenText(expansionRange(SourceRange(rhs_start, E->getLocEnd())));
string base_type = base->getType()->getPointeeType().getAsString(); string base_type = base->getType()->getPointeeType().getAsString();
string pre, post; string pre, post;
......
...@@ -343,6 +343,32 @@ int kprobe____kmalloc(struct pt_regs *ctx, size_t size) { ...@@ -343,6 +343,32 @@ int kprobe____kmalloc(struct pt_regs *ctx, size_t size) {
return 0; return 0;
}""") }""")
def test_probe_simple_member_assign(self):
b = BPF(text="""
#include <uapi/linux/ptrace.h>
#include <linux/netdevice.h>
struct leaf { void *ptr; };
int test(struct pt_regs *ctx, struct sk_buff *skb) {
struct leaf l = {};
struct leaf *lp = &l;
lp->ptr = skb;
return 0;
}""")
b.load_func("test", BPF.KPROBE)
def test_probe_member_expr(self):
b = BPF(text="""
#include <uapi/linux/ptrace.h>
#include <linux/netdevice.h>
struct leaf { struct sk_buff *ptr; };
int test(struct pt_regs *ctx, struct sk_buff *skb) {
struct leaf l = {};
struct leaf *lp = &l;
lp->ptr = skb;
return lp->ptr->priority;
}""")
b.load_func("test", BPF.KPROBE)
def test_unop_probe_read(self): def test_unop_probe_read(self):
text = """ text = """
#include <linux/blkdev.h> #include <linux/blkdev.h>
......
...@@ -224,8 +224,8 @@ static int trace_return(struct pt_regs *ctx, int type) ...@@ -224,8 +224,8 @@ static int trace_return(struct pt_regs *ctx, int type)
// workaround (rewriter should handle file to d_name in one step): // workaround (rewriter should handle file to d_name in one step):
struct dentry *de = NULL; struct dentry *de = NULL;
struct qstr qs = {}; struct qstr qs = {};
bpf_probe_read(&de, sizeof(de), &valp->fp->f_path.dentry); de = valp->fp->f_path.dentry;
bpf_probe_read(&qs, sizeof(qs), (void *)&de->d_name); qs = de->d_name;
if (qs.len == 0) if (qs.len == 0)
return 0; return 0;
bpf_probe_read(&data.file, sizeof(data.file), (void *)qs.name); bpf_probe_read(&data.file, sizeof(data.file), (void *)qs.name);
......
...@@ -219,8 +219,8 @@ static int trace_return(struct pt_regs *ctx, int type) ...@@ -219,8 +219,8 @@ static int trace_return(struct pt_regs *ctx, int type)
// workaround (rewriter should handle file to d_name in one step): // workaround (rewriter should handle file to d_name in one step):
struct dentry *de = NULL; struct dentry *de = NULL;
struct qstr qs = {}; struct qstr qs = {};
bpf_probe_read(&de, sizeof(de), &valp->fp->f_path.dentry); de = valp->fp->f_path.dentry;
bpf_probe_read(&qs, sizeof(qs), (void *)&de->d_name); qs = de->d_name;
if (qs.len == 0) if (qs.len == 0)
return 0; return 0;
bpf_probe_read(&data.file, sizeof(data.file), (void *)qs.name); bpf_probe_read(&data.file, sizeof(data.file), (void *)qs.name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment