• Martin KaFai Lau's avatar
    bpf: Avoid iter->offset making backward progress in bpf_iter_udp · 2242fd53
    Martin KaFai Lau authored
    There is a bug in the bpf_iter_udp_batch() function that stops
    the userspace from making forward progress.
    
    The case that triggers the bug is the userspace passed in
    a very small read buffer. When the bpf prog does bpf_seq_printf,
    the userspace read buffer is not enough to capture the whole bucket.
    
    When the read buffer is not large enough, the kernel will remember
    the offset of the bucket in iter->offset such that the next userspace
    read() can continue from where it left off.
    
    The kernel will skip the number (== "iter->offset") of sockets in
    the next read(). However, the code directly decrements the
    "--iter->offset". This is incorrect because the next read() may
    not consume the whole bucket either and then the next-next read()
    will start from offset 0. The net effect is the userspace will
    keep reading from the beginning of a bucket and the process will
    never finish. "iter->offset" must always go forward until the
    whole bucket is consumed.
    
    This patch fixes it by using a local variable "resume_offset"
    and "resume_bucket". "iter->offset" is always reset to 0 before
    it may be used. "iter->offset" will be advanced to the
    "resume_offset" when it continues from the "resume_bucket" (i.e.
    "state->bucket == resume_bucket"). This brings it closer to
    the bpf_iter_tcp's offset handling which does not suffer
    the same bug.
    
    Cc: Aditi Ghag <aditi.ghag@isovalent.com>
    Fixes: c96dac8d ("bpf: udp: Implement batching for sockets iterator")
    Acked-by: default avatarYonghong Song <yonghong.song@linux.dev>
    Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
    Reviewed-by: default avatarAditi Ghag <aditi.ghag@isovalent.com>
    Link: https://lore.kernel.org/r/20240112190530.3751661-3-martin.lau@linux.devSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    2242fd53
udp.c 91.7 KB