(1).
struct bpf_sock {
...
__s32 rx_queue_mapping;
}
The corresponding kernel fields are
struct sock_common {
...
unsigned short skc_rx_queue_mapping;
...
}
Current ctx rewriter uses unsigned load for the kernel field
which is correct and does not need further handling.
(2).
struct bpf_sockopt {
...
__s32 level;
__s32 optname;
__s32 optlen;
__s32 retval;
}
The level/optname/optlen are from struct bpf_sockopt_kern
struct bpf_sockopt_kern {
...
s32 level;
s32 optname;
s32 optlen;
...
}
and the 'retval' is from struct bpf_cg_run_ctx
struct bpf_cg_run_ctx {
...
int retval;
}
Current the above four fields are loaded with unsigned load.
Let us modify the read macro for bpf_sockopt which use
the same signedness for the original insn.
Signed-off-by: Yonghong Song <yhs@xxxxxx>
---
kernel/bpf/cgroup.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 5b2741aa0d9b..29e3606ff6f4 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -2397,9 +2397,10 @@ static bool cg_sockopt_is_valid_access(int off, int size,
}
#define CG_SOCKOPT_READ_FIELD(F) \
- BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_sockopt_kern, F), \
+ BPF_RAW_INSN((BPF_FIELD_SIZEOF(struct bpf_sockopt_kern, F) | \
+ BPF_MODE(si->code) | BPF_CLASS(si->code)), \
si->dst_reg, si->src_reg, \
- offsetof(struct bpf_sockopt_kern, F))
+ offsetof(struct bpf_sockopt_kern, F), si->imm)
#define CG_SOCKOPT_WRITE_FIELD(F) \
BPF_RAW_INSN((BPF_FIELD_SIZEOF(struct bpf_sockopt_kern, F) | \
@@ -2456,7 +2457,7 @@ static u32 cg_sockopt_convert_ctx_access(enum bpf_access_type type,
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct task_struct, bpf_ctx),
treg, treg,
offsetof(struct task_struct, bpf_ctx));
- *insn++ = BPF_RAW_INSN(BPF_CLASS(si->code) | BPF_MEM |
+ *insn++ = BPF_RAW_INSN(BPF_CLASS(si->code) | BPF_MODE(si->code) |
BPF_FIELD_SIZEOF(struct bpf_cg_run_ctx, retval),
treg, si->src_reg,
offsetof(struct bpf_cg_run_ctx, retval),
@@ -2470,9 +2471,10 @@ static u32 cg_sockopt_convert_ctx_access(enum bpf_access_type type,
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct task_struct, bpf_ctx),
si->dst_reg, si->dst_reg,
offsetof(struct task_struct, bpf_ctx));
- *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_cg_run_ctx, retval),
- si->dst_reg, si->dst_reg,
- offsetof(struct bpf_cg_run_ctx, retval));
+ *insn++ = BPF_RAW_INSN((BPF_FIELD_SIZEOF(struct bpf_cg_run_ctx, retval) |
+ BPF_MODE(si->code) | BPF_CLASS(si->code)),
+ si->dst_reg, si->dst_reg,
+ offsetof(struct bpf_cg_run_ctx, retval), si->imm);
}
break;
case offsetof(struct bpf_sockopt, optval):