22 Jul, 2018

1 commit

  • [ Upstream commit 977c7114ebda2e746a114840d3a875e0cdb826fb ]

    On receving an incomplete message, the existing code stores the
    remaining length of the cloned skb in the early_eaten field instead of
    incrementing the value returned by __strp_recv. This defers invocation
    of sock_rfree for the current skb until the next invocation of
    __strp_recv, which returns early_eaten if early_eaten is non-zero.

    This behavior causes a stall when the current message occupies the very
    tail end of a massive skb, and strp_peek/need_bytes indicates that the
    remainder of the current message has yet to arrive on the socket. The
    TCP receive buffer is totally full, causing the TCP window to go to
    zero, so the remainder of the message will never arrive.

    Incrementing the value returned by __strp_recv by the amount otherwise
    stored in early_eaten prevents stalls of this nature.

    Signed-off-by: Doron Roberts-Kedes
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Doron Roberts-Kedes
     

29 Apr, 2018

2 commits

  • [ Upstream commit 9d0c75bf6e03d9bf80c55b0f677dc9b982958fd5 ]

    strp_data_ready resets strp->need_bytes to 0 if strp_peek_len indicates
    that the remainder of the message has been received. However,
    do_strp_work does not reset strp->need_bytes to 0. If do_strp_work
    completes a partial message, the value of strp->need_bytes will continue
    to reflect the needed bytes of the previous message, causing
    future invocations of strp_data_ready to return early if
    strp->need_bytes is less than strp_peek_len. Resetting strp->need_bytes
    to 0 in __strp_recv on handing a full message to the upper layer solves
    this problem.

    __strp_recv also calculates strp->need_bytes using stm->accum_len before
    stm->accum_len has been incremented by cand_len. This can cause
    strp->need_bytes to be equal to the full length of the message instead
    of the full length minus the accumulated length. This, in turn, causes
    strp_data_ready to return early, even when there is sufficient data to
    complete the partial message. Incrementing stm->accum_len before using
    it to calculate strp->need_bytes solves this problem.

    Found while testing net/tls_sw recv path.

    Fixes: 43a0c6751a322847 ("strparser: Stream parser for messages")
    Signed-off-by: Doron Roberts-Kedes
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Doron Roberts-Kedes
     
  • [ Upstream commit 7c5aba211dd61f41d737a2c51729eb9fdcd3edf4 ]

    struct sock's sk_rcvtimeo is initialized to
    LONG_MAX/MAX_SCHEDULE_TIMEOUT in sock_init_data. Calling
    mod_delayed_work with a timeout of LONG_MAX causes spurious execution of
    the work function. timer->expires is set equal to jiffies + LONG_MAX.
    When timer_base->clk falls behind the current value of jiffies,
    the delta between timer_base->clk and jiffies + LONG_MAX causes the
    expiration to be in the past. Returning early from strp_start_timer if
    timeo == LONG_MAX solves this problem.

    Found while testing net/tls_sw recv path.

    Fixes: 43a0c6751a322847 ("strparser: Stream parser for messages")
    Reviewed-by: Tejun Heo
    Signed-off-by: Doron Roberts-Kedes
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Doron Roberts-Kedes
     

12 Apr, 2018

1 commit

  • [ Upstream commit cd00edc179863848abab5cc5683de5b7b5f70954 ]

    strp_parser_err is called with a negative code everywhere, which then
    calls abort_parser with a negative code. strp_msg_timeout calls
    abort_parser directly with a positive code. Negate ETIMEDOUT
    to match signed-ness of other calls.

    The default abort_parser callback, strp_abort_strp, sets
    sk->sk_err to err. Also negate the error here so sk_err always
    holds a positive value, as the rest of the net code expects. Currently
    a negative sk_err can result in endless loops, or user code that
    thinks it actually sent/received err bytes.

    Found while testing net/tls_sw recv path.

    Fixes: 43a0c6751a322847 ("strparser: Stream parser for messages")
    Signed-off-by: Dave Watson
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Dave Watson
     

25 Oct, 2017

1 commit


25 Aug, 2017

1 commit

  • commit bbb03029a899 ("strparser: Generalize strparser") added more
    function pointers to 'struct strp_callbacks'; however, kcm_attach() was
    not updated to initialize them. This could cause the ->lock() and/or
    ->unlock() function pointers to be set to garbage values, causing a
    crash in strp_work().

    Fix the bug by moving the callback structs into static memory, so
    unspecified members are zeroed. Also constify them while we're at it.

    This bug was found by syzkaller, which encountered the following splat:

    IP: 0x55
    PGD 3b1ca067
    P4D 3b1ca067
    PUD 3b12f067
    PMD 0

    Oops: 0010 [#1] SMP KASAN
    Dumping ftrace buffer:
    (ftrace buffer empty)
    Modules linked in:
    CPU: 2 PID: 1194 Comm: kworker/u8:1 Not tainted 4.13.0-rc4-next-20170811 #2
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
    Workqueue: kstrp strp_work
    task: ffff88006bb0e480 task.stack: ffff88006bb10000
    RIP: 0010:0x55
    RSP: 0018:ffff88006bb17540 EFLAGS: 00010246
    RAX: dffffc0000000000 RBX: ffff88006ce4bd60 RCX: 0000000000000000
    RDX: 1ffff1000d9c97bd RSI: 0000000000000000 RDI: ffff88006ce4bc48
    RBP: ffff88006bb17558 R08: ffffffff81467ab2 R09: 0000000000000000
    R10: ffff88006bb17438 R11: ffff88006bb17940 R12: ffff88006ce4bc48
    R13: ffff88003c683018 R14: ffff88006bb17980 R15: ffff88003c683000
    FS: 0000000000000000(0000) GS:ffff88006de00000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000000000000055 CR3: 000000003c145000 CR4: 00000000000006e0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
    process_one_work+0xbf3/0x1bc0 kernel/workqueue.c:2098
    worker_thread+0x223/0x1860 kernel/workqueue.c:2233
    kthread+0x35e/0x430 kernel/kthread.c:231
    ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
    Code: Bad RIP value.
    RIP: 0x55 RSP: ffff88006bb17540
    CR2: 0000000000000055
    ---[ end trace f0e4920047069cee ]---

    Here is a C reproducer (requires CONFIG_BPF_SYSCALL=y and
    CONFIG_AF_KCM=y):

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    static const struct bpf_insn bpf_insns[3] = {
    { .code = 0xb7 }, /* BPF_MOV64_IMM(0, 0) */
    { .code = 0x95 }, /* BPF_EXIT_INSN() */
    };

    static const union bpf_attr bpf_attr = {
    .prog_type = 1,
    .insn_cnt = 2,
    .insns = (uintptr_t)&bpf_insns,
    .license = (uintptr_t)"",
    };

    int main(void)
    {
    int bpf_fd = syscall(__NR_bpf, BPF_PROG_LOAD,
    &bpf_attr, sizeof(bpf_attr));
    int inet_fd = socket(AF_INET, SOCK_STREAM, 0);
    int kcm_fd = socket(AF_KCM, SOCK_DGRAM, 0);

    ioctl(kcm_fd, SIOCKCMATTACH,
    &(struct kcm_attach) { .fd = inet_fd, .bpf_fd = bpf_fd });
    }

    Fixes: bbb03029a899 ("strparser: Generalize strparser")
    Cc: Dmitry Vyukov
    Cc: Tom Herbert
    Signed-off-by: Eric Biggers
    Signed-off-by: David S. Miller

    Eric Biggers
     

17 Aug, 2017

1 commit


02 Aug, 2017

1 commit

  • Generalize strparser from more than just being used in conjunction
    with read_sock. strparser will also be used in the send path with
    zero proxy. The primary change is to create strp_process function
    that performs the critical processing on skbs. The documentation
    is also updated to reflect the new uses.

    Signed-off-by: Tom Herbert
    Signed-off-by: David S. Miller

    Tom Herbert
     

04 Mar, 2017

1 commit


12 Oct, 2016

1 commit

  • With m68k-linux-gnu-gcc-4.1:

    net/strparser/strparser.c: In function ‘strp_recv’:
    net/strparser/strparser.c:98: warning: ‘err’ may be used uninitialized in this function

    Pass "len" (which is an error code when negative) instead of the
    uninitialized "err" variable to fix this.

    Fixes: 43a0c6751a322847 ("strparser: Stream parser for messages")
    Signed-off-by: Geert Uytterhoeven
    Signed-off-by: David S. Miller

    Geert Uytterhoeven
     

29 Aug, 2016

1 commit


24 Aug, 2016

1 commit


23 Aug, 2016

1 commit

  • sk_user_data mismatch between what kcm expects (psock) and what strparser expects (strparser).

    Queued rx_work, for example calling strp_check_rcv after socket buffer changes, will never complete.

    sk_user_data is unused in strparser, so just remove the check.

    Signed-off-by: Dave Watson
    Acked-by: Tom Herbert
    Signed-off-by: David S. Miller

    Dave Watson
     

18 Aug, 2016

1 commit

  • This patch introduces a utility for parsing application layer protocol
    messages in a TCP stream. This is a generalization of the mechanism
    implemented of Kernel Connection Multiplexor.

    The API includes a context structure, a set of callbacks, utility
    functions, and a data ready function.

    A stream parser instance is defined by a strparse structure that
    is bound to a TCP socket. The function to initialize the structure
    is:

    int strp_init(struct strparser *strp, struct sock *csk,
    struct strp_callbacks *cb);

    csk is the TCP socket being bound to and cb are the parser callbacks.

    The upper layer calls strp_tcp_data_ready when data is ready on the lower
    socket for strparser to process. This should be called from a data_ready
    callback that is set on the socket:

    void strp_tcp_data_ready(struct strparser *strp);

    A parser is bound to a TCP socket by setting data_ready function to
    strp_tcp_data_ready so that all receive indications on the socket
    go through the parser. This is assumes that sk_user_data is set to
    the strparser structure.

    There are four callbacks.
    - parse_msg is called to parse the message (returns length or error).
    - rcv_msg is called when a complete message has been received
    - read_sock_done is called when data_ready function exits
    - abort_parser is called to abort the parser

    The input to parse_msg is an skbuff which contains next message under
    construction. The backend processing of parse_msg will parse the
    application layer protocol headers to determine the length of
    the message in the stream. The possible return values are:

    >0 : indicates length of successfully parsed message
    0 : indicates more data must be received to parse the message
    -ESTRPIPE : current message should not be processed by the
    kernel, return control of the socket to userspace which
    can proceed to read the messages itself
    other < 0 : Error is parsing, give control back to userspace
    assuming that synchronzation is lost and the stream
    is unrecoverable (application expected to close TCP socket)

    In the case of error return (< 0) strparse will stop the parser
    and report and error to userspace. The application must deal
    with the error. To handle the error the strparser is unbound
    from the TCP socket. If the error indicates that the stream
    TCP socket is at recoverable point (ESTRPIPE) then the application
    can read the TCP socket to process the stream. Once the application
    has dealt with the exceptions in the stream, it may again bind the
    socket to a strparser to continue data operations.

    Note that ENODATA may be returned to the application. In this case
    parse_msg returned -ESTRPIPE, however strparser was unable to maintain
    synchronization of the stream (i.e. some of the message in question
    was already read by the parser).

    strp_pause and strp_unpause are used to provide flow control. For
    instance, if rcv_msg is called but the upper layer can't immediately
    consume the message it can hold the message and pause strparser.

    Signed-off-by: Tom Herbert
    Signed-off-by: David S. Miller

    Tom Herbert