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> {
}
return false;
}
bool VisitMemberExpr(MemberExpr *M) {
if (ptregs_.find(M->getMemberDecl()) != ptregs_.end()) {
needs_probe_ = true;
return false;
}
return true;
}
bool VisitDeclRefExpr(DeclRefExpr *E) {
if (ptregs_.find(E->getDecl()) != ptregs_.end())
needs_probe_ = true;
......@@ -126,6 +133,10 @@ class ProbeSetter : public RecursiveASTVisitor<ProbeSetter> {
ptregs_->insert(E->getDecl());
return true;
}
bool VisitMemberExpr(MemberExpr *M) {
ptregs_->insert(M->getMemberDecl());
return false;
}
private:
set<Decl *> *ptregs_;
};
......@@ -231,11 +242,6 @@ bool ProbeVisitor::VisitUnaryOperator(UnaryOperator *E) {
bool ProbeVisitor::VisitMemberExpr(MemberExpr *E) {
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;
SourceLocation rhs_start, member;
bool found = false;
......@@ -255,6 +261,12 @@ bool ProbeVisitor::VisitMemberExpr(MemberExpr *E) {
error(base->getLocEnd(), "internal error: MemberLoc is invalid while preparing probe rewrite");
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 base_type = base->getType()->getPointeeType().getAsString();
string pre, post;
......
......@@ -343,6 +343,32 @@ int kprobe____kmalloc(struct pt_regs *ctx, size_t size) {
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):
text = """
#include <linux/blkdev.h>
......
......@@ -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):
struct dentry *de = NULL;
struct qstr qs = {};
bpf_probe_read(&de, sizeof(de), &valp->fp->f_path.dentry);
bpf_probe_read(&qs, sizeof(qs), (void *)&de->d_name);
de = valp->fp->f_path.dentry;
qs = de->d_name;
if (qs.len == 0)
return 0;
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)
// workaround (rewriter should handle file to d_name in one step):
struct dentry *de = NULL;
struct qstr qs = {};
bpf_probe_read(&de, sizeof(de), &valp->fp->f_path.dentry);
bpf_probe_read(&qs, sizeof(qs), (void *)&de->d_name);
de = valp->fp->f_path.dentry;
qs = de->d_name;
if (qs.len == 0)
return 0;
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