All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Huth <thuth@redhat.com>
To: "Daniel P. Berrangé" <berrange@redhat.com>, qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Laurent Vivier" <lvivier@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Eric Blake" <eblake@redhat.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Hyman Huang" <yong.huang@smartx.com>,
	Qemu-block <qemu-block@nongnu.org>,
	"Kevin Wolf" <kwolf@redhat.com>,
	"Hanna Reitz" <hreitz@redhat.com>
Subject: Re: [PULL 10/11] crypto: push error reporting into TLS session I/O APIs
Date: Mon, 12 Aug 2024 17:38:41 +0200	[thread overview]
Message-ID: <25ea7357-99e1-4fdf-9ef8-885cb7e75f47@redhat.com> (raw)
In-Reply-To: <20240724094706.30396-11-berrange@redhat.com>

On 24/07/2024 11.47, Daniel P. Berrangé wrote:
> The current TLS session I/O APIs just return a synthetic errno
> value on error, which has been translated from a gnutls error
> value. This looses a large amount of valuable information that
> distinguishes different scenarios.
> 
> Pushing population of the "Error *errp" object into the TLS
> session I/O APIs gives more detailed error information.
> 
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---

  Hi Daniel!

iotest 233 is failing for me with -raw now, and bisection
points to this commit. Output is:

--- .../qemu/tests/qemu-iotests/233.out
+++ /tmp/qemu/tests/qemu-iotests/scratch/raw-file-233/233.out.bad
@@ -69,8 +69,8 @@
  1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)

  == check TLS with authorization ==
-qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': Failed to read option reply: Cannot read from TLS channel: Software caused connection abort
-qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': Failed to read option reply: Cannot read from TLS channel: Software caused connection abort
+qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': Failed to read option reply: Cannot read from TLS channel: The TLS connection was non-properly terminated.
+qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': Failed to read option reply: Cannot read from TLS channel: The TLS connection was non-properly terminated.

  == check TLS fail over UNIX with no hostname ==
  qemu-img: Could not open 'driver=nbd,path=SOCK_DIR/qemu-nbd.sock,tls-creds=tls0': No hostname for certificate validation
@@ -103,14 +103,14 @@
  qemu-nbd: TLS handshake failed: The TLS connection was non-properly terminated.

  == final server log ==
-qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: Software caused connection abort
-qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: Software caused connection abort
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: The TLS connection was non-properly terminated.
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: The TLS connection was non-properly terminated.
  qemu-nbd: option negotiation failed: Verify failed: No certificate was found.
  qemu-nbd: option negotiation failed: Verify failed: No certificate was found.
  qemu-nbd: option negotiation failed: TLS x509 authz check for DISTINGUISHED-NAME is denied
  qemu-nbd: option negotiation failed: TLS x509 authz check for DISTINGUISHED-NAME is denied
-qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: Software caused connection abort
-qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: Software caused connection abort
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: The TLS connection was non-properly terminated.
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: The TLS connection was non-properly terminated.
  qemu-nbd: option negotiation failed: TLS handshake failed: An illegal parameter has been received.
  qemu-nbd: option negotiation failed: TLS handshake failed: An illegal parameter has been received.
  *** done

Could you please have a look?

  Thanks,
   Thomas

> 
> diff --git a/crypto/tlssession.c b/crypto/tlssession.c
> index 1e98f44e0d..926f19c115 100644
> --- a/crypto/tlssession.c
> +++ b/crypto/tlssession.c
> @@ -441,23 +441,20 @@ qcrypto_tls_session_set_callbacks(QCryptoTLSSession *session,
>   ssize_t
>   qcrypto_tls_session_write(QCryptoTLSSession *session,
>                             const char *buf,
> -                          size_t len)
> +                          size_t len,
> +                          Error **errp)
>   {
>       ssize_t ret = gnutls_record_send(session->handle, buf, len);
>   
>       if (ret < 0) {
> -        switch (ret) {
> -        case GNUTLS_E_AGAIN:
> -            errno = EAGAIN;
> -            break;
> -        case GNUTLS_E_INTERRUPTED:
> -            errno = EINTR;
> -            break;
> -        default:
> -            errno = EIO;
> -            break;
> +        if (ret == GNUTLS_E_AGAIN) {
> +            return QCRYPTO_TLS_SESSION_ERR_BLOCK;
> +        } else {
> +            error_setg(errp,
> +                       "Cannot write to TLS channel: %s",
> +                       gnutls_strerror(ret));
> +            return -1;
>           }
> -        ret = -1;
>       }
>   
>       return ret;
> @@ -467,26 +464,24 @@ qcrypto_tls_session_write(QCryptoTLSSession *session,
>   ssize_t
>   qcrypto_tls_session_read(QCryptoTLSSession *session,
>                            char *buf,
> -                         size_t len)
> +                         size_t len,
> +                         bool gracefulTermination,
> +                         Error **errp)
>   {
>       ssize_t ret = gnutls_record_recv(session->handle, buf, len);
>   
>       if (ret < 0) {
> -        switch (ret) {
> -        case GNUTLS_E_AGAIN:
> -            errno = EAGAIN;
> -            break;
> -        case GNUTLS_E_INTERRUPTED:
> -            errno = EINTR;
> -            break;
> -        case GNUTLS_E_PREMATURE_TERMINATION:
> -            errno = ECONNABORTED;
> -            break;
> -        default:
> -            errno = EIO;
> -            break;
> +        if (ret == GNUTLS_E_AGAIN) {
> +            return QCRYPTO_TLS_SESSION_ERR_BLOCK;
> +        } else if ((ret == GNUTLS_E_PREMATURE_TERMINATION) &&
> +                   gracefulTermination){
> +            return 0;
> +        } else {
> +            error_setg(errp,
> +                       "Cannot read from TLS channel: %s",
> +                       gnutls_strerror(ret));
> +            return -1;
>           }
> -        ret = -1;
>       }
>   
>       return ret;
> @@ -605,9 +600,10 @@ qcrypto_tls_session_set_callbacks(
>   ssize_t
>   qcrypto_tls_session_write(QCryptoTLSSession *sess,
>                             const char *buf,
> -                          size_t len)
> +                          size_t len,
> +                          Error **errp)
>   {
> -    errno = -EIO;
> +    error_setg(errp, "TLS requires GNUTLS support");
>       return -1;
>   }
>   
> @@ -615,9 +611,11 @@ qcrypto_tls_session_write(QCryptoTLSSession *sess,
>   ssize_t
>   qcrypto_tls_session_read(QCryptoTLSSession *sess,
>                            char *buf,
> -                         size_t len)
> +                         size_t len,
> +                         bool gracefulTermination,
> +                         Error **errp)
>   {
> -    errno = -EIO;
> +    error_setg(errp, "TLS requires GNUTLS support");
>       return -1;
>   }
>   
> diff --git a/include/crypto/tlssession.h b/include/crypto/tlssession.h
> index 571049bd0e..291e602540 100644
> --- a/include/crypto/tlssession.h
> +++ b/include/crypto/tlssession.h
> @@ -107,6 +107,7 @@
>   
>   typedef struct QCryptoTLSSession QCryptoTLSSession;
>   
> +#define QCRYPTO_TLS_SESSION_ERR_BLOCK -2
>   
>   /**
>    * qcrypto_tls_session_new:
> @@ -212,6 +213,7 @@ void qcrypto_tls_session_set_callbacks(QCryptoTLSSession *sess,
>    * @sess: the TLS session object
>    * @buf: the plain text to send
>    * @len: the length of @buf
> + * @errp: pointer to hold returned error object
>    *
>    * Encrypt @len bytes of the data in @buf and send
>    * it to the remote peer using the callback previously
> @@ -221,32 +223,45 @@ void qcrypto_tls_session_set_callbacks(QCryptoTLSSession *sess,
>    * qcrypto_tls_session_get_handshake_status() returns
>    * QCRYPTO_TLS_HANDSHAKE_COMPLETE
>    *
> - * Returns: the number of bytes sent, or -1 on error
> + * Returns: the number of bytes sent,
> + * or QCRYPTO_TLS_SESSION_ERR_BLOCK if the write would block,
> + * or -1 on error.
>    */
>   ssize_t qcrypto_tls_session_write(QCryptoTLSSession *sess,
>                                     const char *buf,
> -                                  size_t len);
> +                                  size_t len,
> +                                  Error **errp);
>   
>   /**
>    * qcrypto_tls_session_read:
>    * @sess: the TLS session object
>    * @buf: to fill with plain text received
>    * @len: the length of @buf
> + * @gracefulTermination: treat premature termination as graceful EOF
> + * @errp: pointer to hold returned error object
>    *
>    * Receive up to @len bytes of data from the remote peer
>    * using the callback previously registered with
>    * qcrypto_tls_session_set_callbacks(), decrypt it and
>    * store it in @buf.
>    *
> + * If @gracefulTermination is true, then a premature termination
> + * of the TLS session will be treated as indicating EOF, as
> + * opposed to an error.
> + *
>    * It is an error to call this before
>    * qcrypto_tls_session_get_handshake_status() returns
>    * QCRYPTO_TLS_HANDSHAKE_COMPLETE
>    *
> - * Returns: the number of bytes received, or -1 on error
> + * Returns: the number of bytes received,
> + * or QCRYPTO_TLS_SESSION_ERR_BLOCK if the receive would block,
> + * or -1 on error.
>    */
>   ssize_t qcrypto_tls_session_read(QCryptoTLSSession *sess,
>                                    char *buf,
> -                                 size_t len);
> +                                 size_t len,
> +                                 bool gracefulTermination,
> +                                 Error **errp);
>   
>   /**
>    * qcrypto_tls_session_check_pending:
> diff --git a/io/channel-tls.c b/io/channel-tls.c
> index 67b9700006..9d8bb158d1 100644
> --- a/io/channel-tls.c
> +++ b/io/channel-tls.c
> @@ -277,24 +277,19 @@ static ssize_t qio_channel_tls_readv(QIOChannel *ioc,
>       ssize_t got = 0;
>   
>       for (i = 0 ; i < niov ; i++) {
> -        ssize_t ret = qcrypto_tls_session_read(tioc->session,
> -                                               iov[i].iov_base,
> -                                               iov[i].iov_len);
> -        if (ret < 0) {
> -            if (errno == EAGAIN) {
> -                if (got) {
> -                    return got;
> -                } else {
> -                    return QIO_CHANNEL_ERR_BLOCK;
> -                }
> -            } else if (errno == ECONNABORTED &&
> -                       (qatomic_load_acquire(&tioc->shutdown) &
> -                        QIO_CHANNEL_SHUTDOWN_READ)) {
> -                return 0;
> +        ssize_t ret = qcrypto_tls_session_read(
> +            tioc->session,
> +            iov[i].iov_base,
> +            iov[i].iov_len,
> +            qatomic_load_acquire(&tioc->shutdown) & QIO_CHANNEL_SHUTDOWN_READ,
> +            errp);
> +        if (ret == QCRYPTO_TLS_SESSION_ERR_BLOCK) {
> +            if (got) {
> +                return got;
> +            } else {
> +                return QIO_CHANNEL_ERR_BLOCK;
>               }
> -
> -            error_setg_errno(errp, errno,
> -                             "Cannot read from TLS channel");
> +        } else if (ret < 0) {
>               return -1;
>           }
>           got += ret;
> @@ -321,18 +316,15 @@ static ssize_t qio_channel_tls_writev(QIOChannel *ioc,
>       for (i = 0 ; i < niov ; i++) {
>           ssize_t ret = qcrypto_tls_session_write(tioc->session,
>                                                   iov[i].iov_base,
> -                                                iov[i].iov_len);
> -        if (ret <= 0) {
> -            if (errno == EAGAIN) {
> -                if (done) {
> -                    return done;
> -                } else {
> -                    return QIO_CHANNEL_ERR_BLOCK;
> -                }
> +                                                iov[i].iov_len,
> +                                                errp);
> +        if (ret == QCRYPTO_TLS_SESSION_ERR_BLOCK) {
> +            if (done) {
> +                return done;
> +            } else {
> +                return QIO_CHANNEL_ERR_BLOCK;
>               }
> -
> -            error_setg_errno(errp, errno,
> -                             "Cannot write to TLS channel");
> +        } else if (ret < 0) {
>               return -1;
>           }
>           done += ret;



  reply	other threads:[~2024-08-12 15:39 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-24  9:46 [PULL 00/11] Crypto patches Daniel P. Berrangé
2024-07-24  9:46 ` [PULL 01/11] crypto: Remove 'crypto-tls-x509-helpers.h' from crypto-tls-psk-helpers.c Daniel P. Berrangé
2024-07-24  9:46 ` [PULL 02/11] crypto: Restrict pkix_asn1_tab[] to crypto-tls-x509-helpers.c Daniel P. Berrangé
2024-07-24  9:46 ` [PULL 03/11] crypto: Allow building with GnuTLS but without Libtasn1 Daniel P. Berrangé
2024-07-24  9:46 ` [PULL 04/11] docs/devel: Add introduction to LUKS volume with detached header Daniel P. Berrangé
2024-07-24  9:47 ` [PULL 05/11] meson.build: fix libgcrypt detection on system without libgcrypt-config Daniel P. Berrangé
2024-07-24  9:47 ` [PULL 06/11] qapi: drop unused QCryptoBlockCreateOptionsLUKS.detached-header Daniel P. Berrangé
2024-07-24  9:47 ` [PULL 07/11] meson: build chardev trace files when have_block Daniel P. Berrangé
2024-07-24  9:47 ` [PULL 08/11] chardev: add tracing of socket error conditions Daniel P. Berrangé
2024-07-24  9:47 ` [PULL 09/11] crypto: drop gnutls debug logging support Daniel P. Berrangé
2024-07-24  9:47 ` [PULL 10/11] crypto: push error reporting into TLS session I/O APIs Daniel P. Berrangé
2024-08-12 15:38   ` Thomas Huth [this message]
2024-08-12 15:42     ` Daniel P. Berrangé
2024-08-27  7:05       ` Markus Armbruster
2024-08-28  8:32         ` Thomas Huth
2024-08-29 11:03           ` Daniel P. Berrangé
2024-07-24  9:47 ` [PULL 11/11] crypto: propagate errors from TLS session I/O callbacks Daniel P. Berrangé
2024-07-24 23:53 ` [PULL 00/11] Crypto patches Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=25ea7357-99e1-4fdf-9ef8-885cb7e75f47@redhat.com \
    --to=thuth@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=eblake@redhat.com \
    --cc=hreitz@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lvivier@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=yong.huang@smartx.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.