Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: SSLDataEvent's fd is 0 Error #642

Merged
merged 9 commits into from
Oct 13, 2024
Merged

fix: SSLDataEvent's fd is 0 Error #642

merged 9 commits into from
Oct 13, 2024

Conversation

yuweizzz
Copy link
Contributor

Fixes: #596

this error happend because application use BIO instead of set socket fd into the SSL layers.

the default fd value in SSLDataEvent struct is 0, When application use SSL_set_fd, the error will not happend, we can get corret fd value.

When application use SSL_set_bio, the fd value in SSLDataEvent struct will keep default value.

App Example:

# curl v7.74.0 lib/vtls/openssl.c
static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) {
......
    if(!SSL_set_fd(backend->handle, (int)sockfd)) {
    /* pass the raw socket into the SSL layers */
    failf(data, "SSL: SSL_set_fd failed: %s",
          ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)));
    return CURLE_SSL_CONNECT_ERROR;
  }

  connssl->connecting_state = ssl_connect_2;

  return CURLE_OK;
}

# curl v7.88.1 lib/vtls/openssl.c
static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) {
......
  backend->bio_method = bio_cf_method_create();
  if(!backend->bio_method)
    return CURLE_OUT_OF_MEMORY;
  bio = BIO_new(backend->bio_method);
  if(!bio)
    return CURLE_OUT_OF_MEMORY;

  BIO_set_data(bio, cf);
#ifdef HAVE_SSL_SET0_WBIO
  /* with OpenSSL v1.1.1 we get an alternative to SSL_set_bio() that works
   * without backward compat quirks. Every call takes one reference, so we
   * up it and pass. SSL* then owns it and will free.
   * We check on the function in configure, since libressl and friends
   * each have their own versions to add support for this. */
  BIO_up_ref(bio);
  SSL_set0_rbio(backend->handle, bio);
  SSL_set0_wbio(backend->handle, bio);
#else
  SSL_set_bio(backend->handle, bio, bio);
#endif
  connssl->connecting_state = ssl_connect_2;

  return CURLE_OK;
}

@yuweizzz yuweizzz marked this pull request as draft September 30, 2024 12:06
@yuweizzz
Copy link
Contributor Author

yuweizzz commented Sep 30, 2024

if we get corret fd value, means we are not in BIO mode.

/* There are the classes of BIOs */
# define BIO_TYPE_DESCRIPTOR     0x0100 /* socket, fd, connect or accept */
# define BIO_TYPE_FILTER         0x0200
# define BIO_TYPE_SOURCE_SINK    0x0400

/* These are the 'types' of BIOs */
# define BIO_TYPE_NONE             0
# define BIO_TYPE_MEM            ( 1|BIO_TYPE_SOURCE_SINK)
# define BIO_TYPE_FILE           ( 2|BIO_TYPE_SOURCE_SINK)

# define BIO_TYPE_FD             ( 4|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
# define BIO_TYPE_SOCKET         ( 5|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
# define BIO_TYPE_NULL           ( 6|BIO_TYPE_SOURCE_SINK)
# define BIO_TYPE_SSL            ( 7|BIO_TYPE_FILTER)
# define BIO_TYPE_MD             ( 8|BIO_TYPE_FILTER)
# define BIO_TYPE_BUFFER         ( 9|BIO_TYPE_FILTER)
# define BIO_TYPE_CIPHER         (10|BIO_TYPE_FILTER)
# define BIO_TYPE_BASE64         (11|BIO_TYPE_FILTER)
# define BIO_TYPE_CONNECT        (12|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
# define BIO_TYPE_ACCEPT         (13|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)

# define BIO_TYPE_NBIO_TEST      (16|BIO_TYPE_FILTER)/* server proxy BIO */
# define BIO_TYPE_NULL_FILTER    (17|BIO_TYPE_FILTER)
# define BIO_TYPE_BIO            (19|BIO_TYPE_SOURCE_SINK)/* half a BIO pair */
# define BIO_TYPE_LINEBUFFER     (20|BIO_TYPE_FILTER)
# define BIO_TYPE_DGRAM          (21|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
# define BIO_TYPE_ASN1           (22|BIO_TYPE_FILTER)
# define BIO_TYPE_COMP           (23|BIO_TYPE_FILTER)
# ifndef OPENSSL_NO_SCTP
#  define BIO_TYPE_DGRAM_SCTP    (24|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
# endif
# define BIO_TYPE_CORE_TO_PROV   (25|BIO_TYPE_SOURCE_SINK)
# define BIO_TYPE_DGRAM_PAIR     (26|BIO_TYPE_SOURCE_SINK)
# define BIO_TYPE_DGRAM_MEM      (27|BIO_TYPE_SOURCE_SINK)

@yuweizzz yuweizzz marked this pull request as ready for review September 30, 2024 13:15
@cfc4n
Copy link
Member

cfc4n commented Sep 30, 2024

if we get corret fd value, means we are not in BIO mode.

If the value of fd is 0, can it be determined that it definitely isn't BIO mode?

Additionally, from the solution you've fixed, if fd is zero, then this result should be disregarded. By doing so, would it miss any messages? Does this imply that all BIO mode information with an fd of 0 can be ignored and will always be overwritten by new event that is not zero?

@cfc4n cfc4n added enhancement New feature or request fix bug fix PR labels Sep 30, 2024
kern/openssl.h Outdated
s32 version = active_ssl_buf_t->version;
bpf_probe_read(&buf, sizeof(const char*), &active_ssl_buf_t->buf);
process_SSL_data(ctx, current_pid_tgid, kSSLRead, buf, fd, version);
process_SSL_data(ctx, current_pid_tgid, kSSLRead, buf, fd, version, is_set_fd);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When is_set_fd is 0, can the event be discarded within the kernel?

@yuweizzz
Copy link
Contributor Author

yuweizzz commented Oct 3, 2024

Hi, @cfc4n, I found a new way to determine BIO type, but this is a huge pull request. Now my dev environment is poor; I will finish this after vacation.

@yuweizzz yuweizzz marked this pull request as draft October 3, 2024 08:44
Copy link

@mooncityorg mooncityorg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# define BIO_TYPE_SOCKET         ( 5|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
# define BIO_TYPE_NULL           ( 6|BIO_TYPE_SOURCE_SINK)
# define BIO_TYPE_SSL            ( 7|BIO_TYPE_FILTER)
# define BIO_TYPE_MD             ( 8|BIO_TYPE_FILTER)
# define BIO_TYPE_BUFFER         ( 9|BIO_TYPE_FILTER)
# define BIO_TYPE_CIPHER         (10|BIO_TYPE_FILTER)

@yuweizzz yuweizzz marked this pull request as ready for review October 9, 2024 03:50
@yuweizzz yuweizzz marked this pull request as draft October 9, 2024 03:50
@yuweizzz yuweizzz marked this pull request as ready for review October 9, 2024 06:48
@yuweizzz yuweizzz requested a review from cfc4n October 9, 2024 16:59
@@ -648,12 +648,13 @@ func (m *MOpenSSLProbe) Dispatcher(eventStruct event.IEventStruct) {
}

func (m *MOpenSSLProbe) dumpSslData(eventStruct *event.SSLDataEvent) {
if eventStruct.Fd <= 0 {
// BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR = 0x0400|0x0100 = 1280
if eventStruct.Fd <= 0 && eventStruct.BioType > 1280 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use constant please.

@@ -68,6 +74,6 @@
#define SSL_ST_RBIO SSL_CONNECTION_ST_RBIO

#include "openssl.h"
#include "openssl_masterkey_3.2.h"
#include "openssl_masterkey_3.3.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did it change from 3.2 to 3.3?
As mentioned in

# openssl 3.3.* 跟 3.2.* 的offset一致。
, both 3.3 and 3.2 use the 3.2 header file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will check it again, maybe it was changed by utils srcipt.

kern/openssl.h Outdated
debug_bpf_printk(
"(OPENSSL) bpf_probe_read ssl_rbio_method_ptr failed, ret: %d\n",
ret);
return 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the method and type of the BIO are not required, then I think it is possible to continue with the following process instead of returning 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those value didn't take effect in SSL_read/SSL_write, we can just make return 0 to // return 0.

kern/openssl.h Outdated
debug_bpf_printk(
"(OPENSSL) bpf_probe_read ssl_wbio_method_ptr failed, ret: %d\n",
ret);
// return 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果ssl_wbio_method_addr 获取失败,应该不能是简单的注释return 0, 下面有使用ssl_wbio_method_addr,逻辑也会影响到,需要把下面的逻辑放到获取成功的逻辑分支里。 针对BIO相关获取,单独剥离一个函数吧,逻辑清晰,也可以更早return。

@yuweizzz
Copy link
Contributor Author

@cfc4n , please check again.

Copy link
Member

@cfc4n cfc4n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Thanks.

@cfc4n cfc4n merged commit 93cfff4 into gojue:master Oct 13, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fix bug fix PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ERR SSLDataEvent's fd is 0 address= fd=0 pid=13617
3 participants