* Alignment check in tnum_is_aligned()
@ 2020-02-27 17:07 Bogdan Harjoc
2020-02-28 0:42 ` Daniel Borkmann
0 siblings, 1 reply; 2+ messages in thread
From: Bogdan Harjoc @ 2020-02-27 17:07 UTC (permalink / raw)
To: bpf
Hello,
bpf programs that call lock_xadd() on pointers obtained from bpf
helpers fail to load because tnum_is_aligned() returns false during
bpf validation. Should tnum_is_aligned() evaluate a.value & a.mask
instead of a.value | a.mask ?
An example bpf tracing snippet that fails validation is:
struct task_struct *t = (struct task_struct *)bpf_get_current_task();
lock_xadd(&t->usage.refs.counter, 1);
I noticed using a kprobe (listed below) that tnum_is_aligned()
receives value=0, mask=0xffffffffffffffff and returns 0 for the
lock_xadd() call above.
=====
b = BPF(text=R"""
#include <uapi/linux/ptrace.h>
int in_tnum_is_aligned(struct pt_regs *regs) {
bpf_trace_printk("in value=%llx mask=%llx\n", regs->di, regs->si);
return 0;
}
int out_tnum_is_aligned(struct pt_regs *regs) {
bpf_trace_printk("out aligned=%llx\n", regs->ax);
return 0;
}
""")
b.attach_kprobe(event="tnum_is_aligned", fn_name="in_fn")
b.attach_kretprobe(event="tnum_is_aligned", fn_name="out_fn")
b.trace_print(fmt="{1} {5}")
=====
Cheers!
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Alignment check in tnum_is_aligned()
2020-02-27 17:07 Alignment check in tnum_is_aligned() Bogdan Harjoc
@ 2020-02-28 0:42 ` Daniel Borkmann
0 siblings, 0 replies; 2+ messages in thread
From: Daniel Borkmann @ 2020-02-28 0:42 UTC (permalink / raw)
To: Bogdan Harjoc, bpf
On 2/27/20 6:07 PM, Bogdan Harjoc wrote:
> Hello,
>
> bpf programs that call lock_xadd() on pointers obtained from bpf
> helpers fail to load because tnum_is_aligned() returns false during
> bpf validation. Should tnum_is_aligned() evaluate a.value & a.mask
> instead of a.value | a.mask ?
>
> An example bpf tracing snippet that fails validation is:
>
> struct task_struct *t = (struct task_struct *)bpf_get_current_task();
> lock_xadd(&t->usage.refs.counter, 1);
Note that bumping the refcount on bpf_get_current_task() pointer is not
possible from BPF.
> I noticed using a kprobe (listed below) that tnum_is_aligned()
> receives value=0, mask=0xffffffffffffffff and returns 0 for the
> lock_xadd() call above.
The implementation is ...
bool tnum_is_aligned(struct tnum a, u64 size)
{
if (!size)
return true;
return !((a.value | a.mask) & (size - 1));
}
... an a.value=0, a.mask=0xffffffffffffffff means that the verifier knows
nothing about the returned value from bpf_get_current_task(), so it could
be any pointer value in the whole u64 range. The masking for alignment is
based on the size arg above, not a.mask. Also bpf_get_current_task() does not
return a pointer type from verifier pov, so there's no check_generic_ptr_alignment()
test performed.
Cheers,
Daniel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-02-28 0:42 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-27 17:07 Alignment check in tnum_is_aligned() Bogdan Harjoc
2020-02-28 0:42 ` Daniel Borkmann
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.