04 Oct, 2018

1 commit

  • [ Upstream commit 67db7cd249e71f64346f481b629724376d063e08 ]

    Currently, the lower protocols sk_write_space handler is not called if
    TLS is sending a scatterlist via tls_push_sg. However, normally
    tls_push_sg calls do_tcp_sendpage, which may be under memory pressure,
    that in turn may trigger a wait via sk_wait_event. Typically, this
    happens when the in-flight bytes exceed the sdnbuf size. In the normal
    case when enough ACKs are received sk_write_space() will be called and
    the sk_wait_event will be woken up allowing it to send more data
    and/or return to the user.

    But, in the TLS case because the sk_write_space() handler does not
    wake up the events the above send will wait until the sndtimeo is
    exceeded. By default this is MAX_SCHEDULE_TIMEOUT so it look like a
    hang to the user (especially this impatient user). To fix this pass
    the sk_write_space event to the lower layers sk_write_space event
    which in the TCP case will wake any pending events.

    I observed the above while integrating sockmap and ktls. It
    initially appeared as test_sockmap (modified to use ktls) occasionally
    hanging. To reliably reproduce this reduce the sndbuf size and stress
    the tls layer by sending many 1B sends. This results in every byte
    needing a header and each byte individually being sent to the crypto
    layer.

    Signed-off-by: John Fastabend
    Acked-by: Dave Watson
    Signed-off-by: Daniel Borkmann
    Signed-off-by: Sasha Levin
    Signed-off-by: Greg Kroah-Hartman

    John Fastabend
     

29 Sep, 2018

3 commits


26 Sep, 2018

1 commit

  • [ Upstream commit 52ea992cfac357b73180d5c051dca43bc8d20c2a ]

    tls_sw_sendmsg() allocates plaintext and encrypted SG entries using
    function sk_alloc_sg(). In case the number of SG entries hit
    MAX_SKB_FRAGS, sk_alloc_sg() returns -ENOSPC and sets the variable for
    current SG index to '0'. This leads to calling of function
    tls_push_record() with 'sg_encrypted_num_elem = 0' and later causes
    kernel crash. To fix this, set the number of SG elements to the number
    of elements in plaintext/encrypted SG arrays in case sk_alloc_sg()
    returns -ENOSPC.

    Fixes: 3c4d7559159b ("tls: kernel TLS support")
    Signed-off-by: Vakul Garg
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Vakul Garg
     

15 Sep, 2018

1 commit

  • [ Upstream commit 037b0b86ecf5646f8eae777d8b52ff8b401692ec ]

    Lets not turn the TCP ULP lookup into an arbitrary module loader as
    we only intend to load ULP modules through this mechanism, not other
    unrelated kernel modules:

    [root@bar]# cat foo.c
    #include
    #include
    #include
    #include

    int main(void)
    {
    int sock = socket(PF_INET, SOCK_STREAM, 0);
    setsockopt(sock, IPPROTO_TCP, TCP_ULP, "sctp", sizeof("sctp"));
    return 0;
    }

    [root@bar]# gcc foo.c -O2 -Wall
    [root@bar]# lsmod | grep sctp
    [root@bar]# ./a.out
    [root@bar]# lsmod | grep sctp
    sctp 1077248 4
    libcrc32c 16384 3 nf_conntrack,nf_nat,sctp
    [root@bar]#

    Fix it by adding module alias to TCP ULP modules, so probing module
    via request_module() will be limited to tcp-ulp-[name]. The existing
    modules like kTLS will load fine given tcp-ulp-tls alias, but others
    will fail to load:

    [root@bar]# lsmod | grep sctp
    [root@bar]# ./a.out
    [root@bar]# lsmod | grep sctp
    [root@bar]#

    Sockmap is not affected from this since it's either built-in or not.

    Fixes: 734942cc4ea6 ("tcp: ULP infrastructure")
    Signed-off-by: Daniel Borkmann
    Acked-by: John Fastabend
    Acked-by: Song Liu
    Signed-off-by: Alexei Starovoitov
    Signed-off-by: Sasha Levin
    Signed-off-by: Greg Kroah-Hartman

    Daniel Borkmann
     

28 Jul, 2018

1 commit

  • [ Upstream commit 144fe2bfd236dc814eae587aea7e2af03dbdd755 ]

    Current sg coalescing logic in sk_alloc_sg() (latter is used by tls and
    sockmap) is not quite correct in that we do fetch the previous sg entry,
    however the subsequent check whether the refilled page frag from the
    socket is still the same as from the last entry with prior offset and
    length matching the start of the current buffer is comparing always the
    first sg list entry instead of the prior one.

    Fixes: 3c4d7559159b ("tls: kernel TLS support")
    Signed-off-by: Daniel Borkmann
    Acked-by: Dave Watson
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Daniel Borkmann
     

22 Jul, 2018

1 commit

  • commit 32da12216e467dea70a09cd7094c30779ce0f9db upstream.

    In the zerocopy sendmsg() path, there are error checks to revert
    the zerocopy if we get any error code. syzkaller has discovered
    that tls_push_record can return -ECONNRESET, which is fatal, and
    happens after the point at which it is safe to revert the iter,
    as we've already passed the memory to do_tcp_sendpages.

    Previously this code could return -ENOMEM and we would want to
    revert the iter, but AFAIK this no longer returns ENOMEM after
    a447da7d004 ("tls: fix waitall behavior in tls_sw_recvmsg"),
    so we fail for all error codes.

    Reported-by: syzbot+c226690f7b3126c5ee04@syzkaller.appspotmail.com
    Reported-by: syzbot+709f2810a6a05f11d4d3@syzkaller.appspotmail.com
    Signed-off-by: Dave Watson
    Fixes: 3c4d7559159b ("tls: kernel TLS support")
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Dave Watson
     

26 Jun, 2018

1 commit

  • [ Upstream commit a447da7d00410278c90d3576782a43f8b675d7be ]

    syzkaller managed to trigger a use-after-free in tls like the
    following:

    BUG: KASAN: use-after-free in tls_push_record.constprop.15+0x6a2/0x810 [tls]
    Write of size 1 at addr ffff88037aa08000 by task a.out/2317

    CPU: 3 PID: 2317 Comm: a.out Not tainted 4.17.0+ #144
    Hardware name: LENOVO 20FBCTO1WW/20FBCTO1WW, BIOS N1FET47W (1.21 ) 11/28/2016
    Call Trace:
    dump_stack+0x71/0xab
    print_address_description+0x6a/0x280
    kasan_report+0x258/0x380
    ? tls_push_record.constprop.15+0x6a2/0x810 [tls]
    tls_push_record.constprop.15+0x6a2/0x810 [tls]
    tls_sw_push_pending_record+0x2e/0x40 [tls]
    tls_sk_proto_close+0x3fe/0x710 [tls]
    ? tcp_check_oom+0x4c0/0x4c0
    ? tls_write_space+0x260/0x260 [tls]
    ? kmem_cache_free+0x88/0x1f0
    inet_release+0xd6/0x1b0
    __sock_release+0xc0/0x240
    sock_close+0x11/0x20
    __fput+0x22d/0x660
    task_work_run+0x114/0x1a0
    do_exit+0x71a/0x2780
    ? mm_update_next_owner+0x650/0x650
    ? handle_mm_fault+0x2f5/0x5f0
    ? __do_page_fault+0x44f/0xa50
    ? mm_fault_error+0x2d0/0x2d0
    do_group_exit+0xde/0x300
    __x64_sys_exit_group+0x3a/0x50
    do_syscall_64+0x9a/0x300
    ? page_fault+0x8/0x30
    entry_SYSCALL_64_after_hwframe+0x44/0xa9

    This happened through fault injection where aead_req allocation in
    tls_do_encryption() eventually failed and we returned -ENOMEM from
    the function. Turns out that the use-after-free is triggered from
    tls_sw_sendmsg() in the second tls_push_record(). The error then
    triggers a jump to waiting for memory in sk_stream_wait_memory()
    resp. returning immediately in case of MSG_DONTWAIT. What follows is
    the trim_both_sgl(sk, orig_size), which drops elements from the sg
    list added via tls_sw_sendmsg(). Now the use-after-free gets triggered
    when the socket is being closed, where tls_sk_proto_close() callback
    is invoked. The tls_complete_pending_work() will figure that there's
    a pending closed tls record to be flushed and thus calls into the
    tls_push_pending_closed_record() from there. ctx->push_pending_record()
    is called from the latter, which is the tls_sw_push_pending_record()
    from sw path. This again calls into tls_push_record(). And here the
    tls_fill_prepend() will panic since the buffer address has been freed
    earlier via trim_both_sgl(). One way to fix it is to move the aead
    request allocation out of tls_do_encryption() early into tls_push_record().
    This means we don't prep the tls header and advance state to the
    TLS_PENDING_CLOSED_RECORD before allocation which could potentially
    fail happened. That fixes the issue on my side.

    Fixes: 3c4d7559159b ("tls: kernel TLS support")
    Reported-by: syzbot+5c74af81c547738e1684@syzkaller.appspotmail.com
    Reported-by: syzbot+709f2810a6a05f11d4d3@syzkaller.appspotmail.com
    Signed-off-by: Daniel Borkmann
    Acked-by: Dave Watson
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Daniel Borkmann
     

30 May, 2018

1 commit

  • [ Upstream commit a1dfa6812b682eef750412dd5a90e7d38d7af068 ]

    Current code returns four bytes of salt followed by four bytes of IV.
    This patch returns all eight bytes of IV.

    fixes: 3c4d7559159b ("tls: kernel TLS support")
    Signed-off-by: Boris Pismenny
    Signed-off-by: David S. Miller
    Signed-off-by: Sasha Levin
    Signed-off-by: Greg Kroah-Hartman

    Boris Pismenny
     

19 May, 2018

2 commits

  • [ Upstream commit 080324c36ade319f57e505633ab54f6f53289b45 ]

    In the case of writing a partial tls record we forgot to clear the
    ctx->in_tcp_sendpages flag, causing some connections to stall.

    Fixes: c212d2c7fc47 ("net/tls: Don't recursively call push_record during tls_write_space callbacks")
    Signed-off-by: Andre Tomt
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Andre Tomt
     
  • [ Upstream commit c212d2c7fc4736d49be102fb7a1a545cdc2f1fea ]

    It is reported that in some cases, write_space may be called in
    do_tcp_sendpages, such that we recursively invoke do_tcp_sendpages again:

    [ 660.468802] ? do_tcp_sendpages+0x8d/0x580
    [ 660.468826] ? tls_push_sg+0x74/0x130 [tls]
    [ 660.468852] ? tls_push_record+0x24a/0x390 [tls]
    [ 660.468880] ? tls_write_space+0x6a/0x80 [tls]
    ...

    tls_push_sg already does a loop over all sending sg's, so ignore
    any tls_write_space notifications until we are done sending.
    We then have to call the previous write_space to wake up
    poll() waiters after we are done with the send loop.

    Reported-by: Andre Tomt
    Signed-off-by: Dave Watson
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Dave Watson
     

31 Jan, 2018

5 commits

  • [ Upstream commit 6db959c82eb039a151d95a0f8b7dea643657327a ]

    The current code copies directly from userspace to ctx->crypto_send, but
    doesn't always reinitialize it to 0 on failure. This causes any
    subsequent attempt to use this setsockopt to fail because of the
    TLS_CRYPTO_INFO_READY check, eventhough crypto_info is not actually
    ready.

    This should result in a correctly set up socket after the 3rd call, but
    currently it does not:

    size_t s = sizeof(struct tls12_crypto_info_aes_gcm_128);
    struct tls12_crypto_info_aes_gcm_128 crypto_good = {
    .info.version = TLS_1_2_VERSION,
    .info.cipher_type = TLS_CIPHER_AES_GCM_128,
    };

    struct tls12_crypto_info_aes_gcm_128 crypto_bad_type = crypto_good;
    crypto_bad_type.info.cipher_type = 42;

    setsockopt(sock, SOL_TLS, TLS_TX, &crypto_bad_type, s);
    setsockopt(sock, SOL_TLS, TLS_TX, &crypto_good, s - 1);
    setsockopt(sock, SOL_TLS, TLS_TX, &crypto_good, s);

    Fixes: 3c4d7559159b ("tls: kernel TLS support")
    Signed-off-by: Sabrina Dubroca
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Sabrina Dubroca
     
  • [ Upstream commit 877d17c79b66466942a836403773276e34fe3614 ]

    do_tls_setsockopt_tx returns 0 without doing anything when crypto_info
    is already set. Silent failure is confusing for users.

    Fixes: 3c4d7559159b ("tls: kernel TLS support")
    Signed-off-by: Sabrina Dubroca
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Sabrina Dubroca
     
  • [ Upstream commit cf6d43ef66f416282121f436ce1bee9a25199d52 ]

    During setsockopt(SOL_TCP, TLS_TX), if initialization of the software
    context fails in tls_set_sw_offload(), we leak sw_ctx. We also don't
    reassign ctx->priv_ctx to NULL, so we can't even do another attempt to
    set it up on the same socket, as it will fail with -EEXIST.

    Fixes: 3c4d7559159b ('tls: kernel TLS support')
    Signed-off-by: Sabrina Dubroca
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Sabrina Dubroca
     
  • [ Upstream commit d91c3e17f75f218022140dee18cf515292184a8f ]

    Calling accept on a TCP socket with a TLS ulp attached results
    in two sockets that share the same ulp context.
    The ulp context is freed while a socket is destroyed, so
    after one of the sockets is released, the second second will
    trigger a use after free when it tries to access the ulp context
    attached to it.
    We restrict the TLS ulp to sockets in ESTABLISHED state
    to prevent the scenario above.

    Fixes: 3c4d7559159b ("tls: kernel TLS support")
    Reported-by: syzbot+904e7cd6c5c741609228@syzkaller.appspotmail.com
    Signed-off-by: Ilya Lesokhin
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Ilya Lesokhin
     
  • [ Upstream commit 30be8f8dba1bd2aff73e8447d59228471233a3d4 ]

    sendfile() calls can hang endless with using Kernel TLS if a socket error occurs.
    Socket error codes must be inverted by Kernel TLS before returning because
    they are stored with positive sign. If returned non-inverted they are
    interpreted as number of bytes sent, causing endless looping of the
    splice mechanic behind sendfile().

    Signed-off-by: Robert Hering
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    r.hering@avm.de
     

14 Dec, 2017

1 commit

  • [ Upstream commit 61ef6da622aa7b66bf92991bd272490eea6c712e ]

    Use kzalloc for aead_request allocation as
    we don't set all the bits in the request.

    Fixes: 3c4d7559159b ('tls: kernel TLS support')
    Signed-off-by: Ilya Lesokhin
    Signed-off-by: David S. Miller
    Signed-off-by: Sasha Levin
    Signed-off-by: Greg Kroah-Hartman

    Ilya Lesokhin
     

15 Sep, 2017

1 commit


06 Jul, 2017

1 commit


24 Jun, 2017

1 commit


18 Jun, 2017

1 commit

  • Missing crypto deps for some platforms.
    Default to n for new module.

    config: m68k-amcore_defconfig (attached as .config)
    compiler: m68k-linux-gcc (GCC) 4.9.0

    make.cross ARCH=m68k
    All errors (new ones prefixed by >>):

    net/built-in.o: In function `tls_set_sw_offload':
    >> (.text+0x732f8): undefined reference to `crypto_alloc_aead'
    net/built-in.o: In function `tls_set_sw_offload':
    >> (.text+0x7333c): undefined reference to `crypto_aead_setkey'
    net/built-in.o: In function `tls_set_sw_offload':
    >> (.text+0x73354): undefined reference to `crypto_aead_setauthsize'

    Reported-by: kbuild test robot
    Signed-off-by: Dave Watson
    Signed-off-by: David S. Miller

    Dave Watson
     

16 Jun, 2017

2 commits

  • We refer to TCP et al. symbols so have to use INET as
    the dependency.

    ERROR: "tcp_prot" [net/tls/tls.ko] undefined!
    >> ERROR: "tcp_rate_check_app_limited" [net/tls/tls.ko] undefined!
    ERROR: "tcp_register_ulp" [net/tls/tls.ko] undefined!
    ERROR: "tcp_unregister_ulp" [net/tls/tls.ko] undefined!
    ERROR: "do_tcp_sendpages" [net/tls/tls.ko] undefined!

    Reported-by: kbuild test robot
    Signed-off-by: David S. Miller

    David S. Miller
     
  • Software implementation of transport layer security, implemented using ULP
    infrastructure. tcp proto_ops are replaced with tls equivalents of sendmsg and
    sendpage.

    Only symmetric crypto is done in the kernel, keys are passed by setsockopt
    after the handshake is complete. All control messages are supported via CMSG
    data - the actual symmetric encryption is the same, just the message type needs
    to be passed separately.

    For user API, please see Documentation patch.

    Pieces that can be shared between hw and sw implementation
    are in tls_main.c

    Signed-off-by: Boris Pismenny
    Signed-off-by: Ilya Lesokhin
    Signed-off-by: Aviad Yehezkel
    Signed-off-by: Dave Watson
    Signed-off-by: David S. Miller

    Dave Watson