| // Licensed to Apache Software Foundation (ASF) under one or more contributor |
| // license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright |
| // ownership. Apache Software Foundation (ASF) licenses this file to you under |
| // the Apache License, Version 2.0 (the "License"); you may |
| // not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include "openssl.h" |
| |
| static __inline void process_openssl_data(struct pt_regs* ctx, __u64 id, __u32 data_direction, struct sock_data_args_t* args, __u32 func_name) { |
| int bytes_count = PT_REGS_RC(ctx); |
| process_write_data(ctx, id, args, bytes_count, data_direction, false, func_name, true); |
| } |
| |
| static int get_fd_symaddr(__u32 tgid, bool read, void* ssl) { |
| struct openssl_fd_symaddr* addr = get_openssl_fd_symaddr(tgid); |
| if (addr == NULL) { |
| return -1; |
| } |
| __u32 bio_offset = read ? addr->bio_read_offset : addr->bio_write_offset; |
| __u32 fd_offset = addr->fd_offset; |
| |
| void *bio = NULL; |
| bpf_probe_read(&bio, sizeof(bio), ssl + bio_offset); |
| __u32 fd; |
| bpf_probe_read(&fd, sizeof(fd), bio + fd_offset); |
| |
| return fd; |
| } |
| |
| static int get_fd(uint32_t tgid, bool read, void* ssl) { |
| int fd = -1; |
| |
| fd = get_fd_symaddr(tgid, read, ssl); |
| if (fd > 2) { |
| return fd; |
| } |
| |
| return -1; |
| } |
| |
| SEC("uprobe/ssl_write") |
| int openssl_write(struct pt_regs* ctx) { |
| __u64 id = bpf_get_current_pid_tgid(); |
| __u32 tgid = id >> 32; |
| |
| void* ssl = (void*)PT_REGS_PARM1(ctx); |
| __u32 fd = get_fd(tgid, false, ssl); |
| bpf_printk("ssl_write fd: %d\n", fd); |
| if (fd < 0) { |
| return 0; |
| } |
| |
| char* buf = (char*)PT_REGS_PARM2(ctx); |
| struct sock_data_args_t data_args = {}; |
| data_args.fd = fd; |
| data_args.buf = buf; |
| bpf_map_update_elem(&openssl_sock_data_args, &id, &data_args, 0); |
| |
| set_conn_as_ssl(ctx, tgid, fd, SOCKET_OPTS_TYPE_SSL_WRITE); |
| return 0; |
| } |
| |
| SEC("uretprobe/ssl_write") |
| int openssl_write_ret(struct pt_regs* ctx) { |
| __u64 id = bpf_get_current_pid_tgid(); |
| struct sock_data_args_t *args = bpf_map_lookup_elem(&openssl_sock_data_args, &id); |
| if (args) { |
| process_openssl_data(ctx, id, SOCK_DATA_DIRECTION_EGRESS, args, SOCKET_OPTS_TYPE_SSL_WRITE); |
| } |
| bpf_map_delete_elem(&openssl_sock_data_args, &id); |
| return 0; |
| } |
| |
| SEC("uprobe/ssl_read") |
| int openssl_read(struct pt_regs* ctx) { |
| __u64 id = bpf_get_current_pid_tgid(); |
| __u32 tgid = id >> 32; |
| |
| void* ssl = (void*)PT_REGS_PARM1(ctx); |
| __u32 fd = get_fd(tgid, true, ssl); |
| bpf_printk("ssl_read fd: %d\n", fd); |
| if (fd < 0) { |
| return 0; |
| } |
| |
| char* buf = (char*)PT_REGS_PARM2(ctx); |
| struct sock_data_args_t data_args = {}; |
| data_args.fd = fd; |
| data_args.buf = buf; |
| bpf_map_update_elem(&openssl_sock_data_args, &id, &data_args, 0); |
| |
| set_conn_as_ssl(ctx, tgid, fd, SOCKET_OPTS_TYPE_SSL_WRITE); |
| return 0; |
| } |
| |
| SEC("uretprobe/ssl_read") |
| int openssl_read_ret(struct pt_regs* ctx) { |
| __u64 id = bpf_get_current_pid_tgid(); |
| struct sock_data_args_t *args = bpf_map_lookup_elem(&openssl_sock_data_args, &id); |
| if (args) { |
| process_openssl_data(ctx, id, SOCK_DATA_DIRECTION_INGRESS, args, SOCKET_OPTS_TYPE_SSL_READ); |
| } |
| bpf_map_delete_elem(&openssl_sock_data_args, &id); |
| return 0; |
| } |