@@ -4073,42 +4073,6 @@ FILLER(sys_socket_bind_x, true) {
40734073 return bpf_push_s64_to_ring (data , (int64_t )fd );
40744074}
40754075
4076- static __always_inline int f_sys_recv_x_common (struct filler_data * data , long retval ) {
4077- unsigned long bufsize ;
4078- unsigned long val ;
4079- int res ;
4080-
4081- /*
4082- * res
4083- */
4084- res = bpf_push_s64_to_ring (data , retval );
4085- CHECK_RES (res );
4086-
4087- /*
4088- * data
4089- */
4090- if (retval < 0 ) {
4091- /*
4092- * The operation failed, return an empty buffer
4093- */
4094- val = 0 ;
4095- bufsize = 0 ;
4096- } else {
4097- val = bpf_syscall_get_argument (data , 1 );
4098-
4099- /*
4100- * The return value can be lower than the value provided by the user,
4101- * and we take that into account.
4102- */
4103- bufsize = retval ;
4104- }
4105-
4106- data -> fd = bpf_syscall_get_argument (data , 0 );
4107- res = __bpf_val_to_ring (data , val , bufsize , PT_BYTEBUF , -1 , true, USER );
4108-
4109- return res ;
4110- }
4111-
41124076FILLER (sys_recv_x , true) {
41134077 /* Parameter 1: res (type: PT_ERRNO) */
41144078 long retval = bpf_syscall_get_retval (data -> ctx );
@@ -4162,8 +4126,8 @@ FILLER(sys_recv_x, true) {
41624126
41634127FILLER (sys_recvfrom_e , true) {
41644128 /* Parameter 1: fd (type: PT_FD) */
4165- int32_t fd = (int32_t )bpf_syscall_get_argument (data , 0 );
4166- int res = bpf_push_s64_to_ring (data , ( int64_t ) fd );
4129+ int64_t fd = (int32_t )bpf_syscall_get_argument (data , 0 );
4130+ int res = bpf_push_s64_to_ring (data , fd );
41674131 CHECK_RES (res );
41684132
41694133 /* Parameter 2: size (type: PT_UINT32) */
@@ -4172,79 +4136,92 @@ FILLER(sys_recvfrom_e, true) {
41724136}
41734137
41744138FILLER (sys_recvfrom_x , true) {
4175- struct sockaddr * usrsockaddr ;
4176- unsigned long val ;
4177- uint16_t size = 0 ;
4178- long retval ;
4179- int addrlen = 0 ;
4180- int err = 0 ;
4181- int res ;
4182- int fd ;
4183- bool push = true;
4184- bool from_usr = false;
4185-
4186- /*
4187- * Push the common params to the ring
4188- */
4189- retval = bpf_syscall_get_retval (data -> ctx );
4190- res = f_sys_recv_x_common (data , retval );
4139+ /* Parameter 1: res (type: PT_ERRNO) */
4140+ long retval = bpf_syscall_get_retval (data -> ctx );
4141+ int res = bpf_push_s64_to_ring (data , retval );
41914142 CHECK_RES (res );
41924143
4193- if (retval >= 0 ) {
4194- /*
4195- * Get the fd
4196- */
4197- fd = bpf_syscall_get_argument (data , 0 );
4144+ /* Extract fd and size parameters */
4145+ int64_t fd = (int64_t )(int32_t )bpf_syscall_get_argument (data , 0 );
4146+ uint32_t size = (uint32_t )bpf_syscall_get_argument (data , 2 );
41984147
4199- /*
4200- * Get the address
4201- */
4202- usrsockaddr = (struct sockaddr * )bpf_syscall_get_argument (data , 4 );
4148+ if (retval < 0 ) {
4149+ /* Parameter 2: data (type: PT_BYTEBUF) */
4150+ bpf_push_empty_param (data );
42034151
4204- /*
4205- * Get the address len
4206- */
4207- val = bpf_syscall_get_argument (data , 5 );
4152+ /* Parameter 3: tuple (type: PT_SOCKTUPLE) */
4153+ bpf_push_empty_param (data );
42084154
4209- if ( usrsockaddr && val != 0 ) {
4210- if ( bpf_probe_read_user ( & addrlen , sizeof ( addrlen ), ( void * ) val ))
4211- return PPM_FAILURE_INVALID_USER_MEMORY ;
4155+ /* Parameter 4: fd (type: PT_FD) */
4156+ res = bpf_push_s64_to_ring ( data , fd );
4157+ CHECK_RES ( res ) ;
42124158
4213- /*
4214- * Copy the address
4215- */
4216- err = bpf_addr_to_kernel (usrsockaddr , addrlen , (struct sockaddr * )data -> tmp_scratch );
4217- if (err >= 0 ) {
4218- /*
4219- * Convert the fd into socket endpoint information
4220- */
4221- from_usr = true;
4222- } else {
4223- // Do not send any socket endpoint info.
4224- push = false;
4225- }
4159+ /* Parameter 5: size (type: PT_UINT32) */
4160+ return bpf_push_u32_to_ring (data , size );
4161+ }
4162+
4163+ /* Handle successful system call path. */
4164+
4165+ /* Parameter 2: data (type: PT_BYTEBUF) */
4166+ const unsigned long bytes_to_read = retval ;
4167+ const unsigned long received_data_pointer = bpf_syscall_get_argument (data , 1 );
4168+ data -> fd = fd ;
4169+ res = __bpf_val_to_ring (data , received_data_pointer , bytes_to_read , PT_BYTEBUF , -1 , true, USER );
4170+
4171+ /* Get the address */
4172+ struct sockaddr __user * usrsockaddr =
4173+ (struct sockaddr __user * )bpf_syscall_get_argument (data , 4 );
4174+
4175+ /* Get the address len pointer */
4176+ void * usrsockaddr_len_pointer = (void * )bpf_syscall_get_argument (data , 5 );
4177+
4178+ /* Evaluate socktuple, leveraging the user-provided address if possible */
4179+ struct sockaddr * ksockaddr = (struct sockaddr * )data -> tmp_scratch ;
4180+ bool use_sockaddr_user_data = false;
4181+ bool push_socktuple = true;
4182+ unsigned long usrsockaddr_len = 0 ;
4183+ if (usrsockaddr != NULL && usrsockaddr_len_pointer != NULL ) {
4184+ /* Copy address len into kernel memory */
4185+ if (bpf_probe_read_user (& usrsockaddr_len ,
4186+ sizeof (usrsockaddr_len ),
4187+ usrsockaddr_len_pointer )) {
4188+ return PPM_FAILURE_INVALID_USER_MEMORY ;
42264189 }
4227- if (push ) {
4228- /*
4229- * Get socket endpoint information from fd if the user-provided *sockaddr is NULL
4230- */
4231- size = bpf_fd_to_socktuple (data ,
4232- fd ,
4233- (struct sockaddr * )data -> tmp_scratch ,
4234- addrlen ,
4235- from_usr ,
4236- true,
4237- data -> tmp_scratch + sizeof (struct sockaddr_storage ));
4190+
4191+ /* Copy the address into kernel memory */
4192+ res = bpf_addr_to_kernel (usrsockaddr , usrsockaddr_len , ksockaddr );
4193+ if (likely (res >= 0 )) {
4194+ /* Convert the fd into socket endpoint information */
4195+ use_sockaddr_user_data = true;
4196+ } else {
4197+ /* Do not send any socket endpoint information */
4198+ push_socktuple = false;
42384199 }
42394200 }
42404201
4241- /*
4242- * Copy the endpoint info into the ring
4243- */
4202+ uint32_t socktuple_size = 0 ;
4203+ if (push_socktuple ) {
4204+ /* Convert the fd into socket endpoint information */
4205+ socktuple_size = bpf_fd_to_socktuple (data ,
4206+ fd ,
4207+ ksockaddr ,
4208+ usrsockaddr_len ,
4209+ use_sockaddr_user_data ,
4210+ true,
4211+ data -> tmp_scratch + sizeof (struct sockaddr_storage ));
4212+ }
4213+
4214+ /* Parameter 3: tuple (type: PT_SOCKTUPLE) */
42444215 data -> curarg_already_on_frame = true;
4245- res = __bpf_val_to_ring (data , 0 , size , PT_SOCKTUPLE , -1 , false, KERNEL );
4216+ res = bpf_val_to_ring_len (data , 0 , socktuple_size );
4217+ CHECK_RES (res );
42464218
4247- return res ;
4219+ /* Parameter 4: fd (type: PT_FD) */
4220+ res = bpf_push_s64_to_ring (data , fd );
4221+ CHECK_RES (res );
4222+
4223+ /* Parameter 5: size (type: PT_UINT32) */
4224+ return bpf_push_u32_to_ring (data , size );
42484225}
42494226
42504227FILLER (sys_shutdown_e , true) {
0 commit comments