• yonghong-song's avatar
    prevent bpf_probe_read MemberExpr rewrite if not rewritable (#1827) · 66d28635
    yonghong-song authored
    For the test case in this patch below,
     #define _(P) ({typeof(P) val = 0; bpf_probe_read(&val, sizeof(val), &P); val;})
     int count_tcp(struct pt_regs *ctx, struct sk_buff *skb) {
         return _(TCP_SKB_CB(skb)->tcp_gso_size);
     }
    
    The clang AST will consider the whole `_(TCP_SKB_CB(skb)->tcp_gso_size)`
    as a MemberExpr during AST traversal. However, it will consider
    the start location of the member expression not rewritable.
    Without this patch, we will get an error like below:
        /virtual/main.c:15:44: error: expected ';' after return statement
        return _(TCP_SKB_CB(skb)->tcp_gso_size)); _val; });
    Basically, the start of bpf_probe_read() rewritingg failed but
    later part succeeded, so the code becomes uncompilable.
    
    Previously, we did not see such issues, but as rewriter got
    more smarter this bug is exposed.
    
    This patch fixed the issue by preventing rewriting the whole
    expression if the start location for the member expression is
    not rewritable.
    Signed-off-by: default avatarYonghong Song <yhs@fb.com>
    66d28635
b_frontend_action.cc 48.1 KB