Skip to content

Commit

Permalink
wip: rework using ppm_cmsghdr
Browse files Browse the repository at this point in the history
Signed-off-by: Leonardo Di Giovanna <[email protected]>
  • Loading branch information
ekoops committed Jan 31, 2025
1 parent a2ffa0a commit 4f9cc6a
Showing 1 changed file with 46 additions and 39 deletions.
85 changes: 46 additions & 39 deletions userspace/libsinsp/parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3664,70 +3664,77 @@ void sinsp_parser::parse_fspath_related_exit(sinsp_evt *evt) {

#ifndef _WIN32

// "No aligned" macros definitions. These macros are equivalent to the corresponding variants
// without the "no aligned suffix" but avoid unaligned access to the underlaying data.
extern struct cmsghdr *__cmsg_nxthdr_no_aligned(struct msghdr *__mhdr,
struct cmsghdr *__cmsg) __THROW;
#define CMSG_NXTHDR_NO_ALIGNED(mhdr, cmsg) __cmsg_nxthdr_no_aligned(mhdr, cmsg)
#ifdef __USE_EXTERN_INLINES
#ifndef _EXTERN_INLINE
#define _EXTERN_INLINE __extern_inline
#endif
_EXTERN_INLINE struct cmsghdr *__NTH(__cmsg_nxthdr_no_aligned(struct msghdr *__mhdr,
struct cmsghdr *__cmsg)) {
struct ppm_cmsghdr {
// Length of ppm_cmsghdr structure plus data following it.
size_t cmsg_len;
// Originating protocol.
int cmsg_level;
// Protocol specific type.
int cmsg_type;
};

// PPM_CMSG_* macros definitions. These macros are equivalent to the corresponding variants
// without PPM_* prefix, but they don't depend on msghdr definition as we don't need it at the
// moment.
#define PPM_CMSG_FIRSTHDR(msg_control, msg_controllen) \
((size_t)msg_controllen >= sizeof(struct ppm_cmsghdr) ? (struct ppm_cmsghdr *)msg_control \
: (struct ppm_cmsghdr *)0)

#define PPM_CMSG_UNALIGNED_ACCESS(cmsg, field, dest) \
(memcpy((void *)&(dest), (cmsg) + offsetof(struct ppm_cmsghdr, field), sizeof((cmsg)->field)))

#define PPM_CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & (size_t) ~(sizeof(size_t) - 1))

#define PPM_CMSG_NXTHDR(msg_control, msg_controllen, cmsg) \
__ppm_cmsg_nxthdr(msg_control, msg_controllen, cmsg)
static struct ppm_cmsghdr *__ppm_cmsg_nxthdr(void const *__msg_control,

Check warning on line 3690 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3690

Added line #L3690 was not covered by tests
size_t __msg_controllen,
struct ppm_cmsghdr *__cmsg) {
size_t cmsg_len;
memcpy(&cmsg_len, __cmsg + offsetof(struct cmsghdr, cmsg_len), sizeof(size_t));
if((size_t)cmsg_len < sizeof(struct cmsghdr))
PPM_CMSG_UNALIGNED_ACCESS(__cmsg, cmsg_len, cmsg_len);
if(cmsg_len < sizeof(struct ppm_cmsghdr))

Check warning on line 3695 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3693-L3695

Added lines #L3693 - L3695 were not covered by tests
// The kernel header does this so there may be a reason.
return (struct cmsghdr *)0;
return (struct ppm_cmsghdr *)0;

__cmsg = (struct cmsghdr *)((unsigned char *)__cmsg + CMSG_ALIGN(cmsg_len));
if((unsigned char *)(__cmsg + 1) >
((unsigned char *)__mhdr->msg_control + __mhdr->msg_controllen) ||
((unsigned char *)__cmsg + CMSG_ALIGN(cmsg_len) >
((unsigned char *)__mhdr->msg_control + __mhdr->msg_controllen)))
__cmsg = (struct ppm_cmsghdr *)((unsigned char *)__cmsg + PPM_CMSG_ALIGN(cmsg_len));

Check warning on line 3699 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3699

Added line #L3699 was not covered by tests
if((unsigned char *)(__cmsg + 1) > ((unsigned char *)__msg_control + __msg_controllen) ||
((unsigned char *)__cmsg + PPM_CMSG_ALIGN(cmsg_len) >
((unsigned char *)__msg_control + __msg_controllen)))
// No more entries.
return (struct cmsghdr *)0;
return (struct ppm_cmsghdr *)0;
return __cmsg;
}
#endif // Use `extern inline'.

#if __glibc_c99_flexarr_available
#define CMSG_DATA_NO_ALIGNED(cmsg) (cmsg + offsetof(struct cmsghdr, __cmsg_data))
#else
#define CMSG_DATA_NO_ALIGNED(cmsg) ((unsigned char *)((struct cmsghdr *)(cmsg) + 1))
#endif
#define PPM_CMSG_DATA(cmsg) ((unsigned char *)((struct ppm_cmsghdr *)(cmsg) + 1))

inline void sinsp_parser::process_recvmsg_ancillary_data(sinsp_evt *evt,

Check warning on line 3710 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3710

Added line #L3710 was not covered by tests
sinsp_evt_param const *parinfo) const {
// Create a msg header to be used with CMSG_* macros.
msghdr msgh;
msgh.msg_control = (void *)parinfo->m_val;
msgh.msg_controllen = parinfo->m_len;
// Seek for SCM_RIGHTS control message headers and extract passed file descriptors.
for(cmsghdr *cmsg = CMSG_FIRSTHDR(&msgh); cmsg != nullptr;
cmsg = CMSG_NXTHDR_NO_ALIGNED(&msgh, cmsg)) {
cmsghdr c;
memcpy(&c, cmsg, sizeof(cmsghdr));
int const cmsg_type = c.cmsg_type;
size_t const cmsg_len = c.cmsg_len;
void const *msg_control = (void *)parinfo->m_val;
size_t msg_controllen = parinfo->m_len;

Check warning on line 3714 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3713-L3714

Added lines #L3713 - L3714 were not covered by tests
for(ppm_cmsghdr *cmsg = PPM_CMSG_FIRSTHDR(msg_control, msg_controllen); cmsg != nullptr;
cmsg = PPM_CMSG_NXTHDR(msg_control, msg_controllen, cmsg)) {
int cmsg_type;
PPM_CMSG_UNALIGNED_ACCESS(cmsg, cmsg_type, cmsg_type);

Check warning on line 3718 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3717-L3718

Added lines #L3717 - L3718 were not covered by tests
if(cmsg_type == SCM_RIGHTS) {
char error[SCAP_LASTERR_SIZE];
scap_threadinfo scap_tinfo{};
memset(&scap_tinfo, 0, sizeof(scap_tinfo));
m_inspector->m_thread_manager->thread_to_scap(*evt->get_tinfo(), &scap_tinfo);

Check warning on line 3723 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3720-L3723

Added lines #L3720 - L3723 were not covered by tests
#define SCM_MAX_FD 253 // Taken from kernel.
int fds[SCM_MAX_FD];
size_t cmsg_len;
PPM_CMSG_UNALIGNED_ACCESS(cmsg, cmsg_len, cmsg_len);
unsigned long const data_size = cmsg_len - CMSG_LEN(0);
unsigned long const fds_len = data_size / sizeof(int);

Check warning on line 3729 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3725-L3729

Added lines #L3725 - L3729 were not covered by tests
// Guard against malformed event, by checking that data size is a multiple of
// sizeof(int) (file descriptor size) and the control message doesn't contain more data
// than allowed by kernel constraints.
// sizeof(int) (file descriptor size) and the control message doesn't contain more
// data than allowed by kernel constraints.
if(data_size % sizeof(int) || fds_len > SCM_MAX_FD) {
continue;

Check warning on line 3734 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3734

Added line #L3734 was not covered by tests
}
#undef SCM_MAX_FD
memcpy(&fds, CMSG_DATA_NO_ALIGNED(cmsg), data_size);
memcpy(&fds, PPM_CMSG_DATA(cmsg), data_size);

Check warning on line 3737 in userspace/libsinsp/parsers.cpp

View check run for this annotation

Codecov / codecov/patch

userspace/libsinsp/parsers.cpp#L3737

Added line #L3737 was not covered by tests
for(unsigned long i = 0; i < fds_len; i++) {
if(scap_get_fdinfo(m_inspector->get_scap_platform(), &scap_tinfo, fds[i], error) !=
SCAP_SUCCESS) {
Expand Down

0 comments on commit 4f9cc6a

Please sign in to comment.