-
Notifications
You must be signed in to change notification settings - Fork 165
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
update(driver): handle processes sending open file descriptors via SCM_RIGHTS #1400
Conversation
Please double check driver/API_VERSION file. See versioning. /hold |
Signed-off-by: Lorenzo Susini <[email protected]>
…ern bpf Signed-off-by: Lorenzo Susini <[email protected]>
Signed-off-by: Lorenzo Susini <[email protected]>
…e descriptors of a process from procfs Signed-off-by: Lorenzo Susini <[email protected]>
7d9bb8d
to
f3082b7
Compare
4fca071
to
537b173
Compare
Signed-off-by: Lorenzo Susini <[email protected]>
…meter in recvmsg Signed-off-by: Lorenzo Susini <[email protected]>
Signed-off-by: Lorenzo Susini <[email protected]>
70c3c92
to
2c318a4
Compare
Signed-off-by: Lorenzo Susini <[email protected]>
if(etype == PPME_SOCKET_RECVMSG_X && evt->get_num_params() >= 5) | ||
{ | ||
parinfo = evt->get_param(4); | ||
if(parinfo->m_len > sizeof(struct cmsghdr)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure there is room for the header and some more payload. In that case, SCM_RIGHTS could effectively have passed open file descriptors from one process to another
if(parinfo->m_len > sizeof(struct cmsghdr)) | ||
{ | ||
struct cmsghdr *cmsg = (struct cmsghdr *)parinfo->m_val; | ||
if(cmsg->cmsg_type == SCM_RIGHTS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using SCM_RIGHTS, we expect to have just one header, like in the example at the end of this page: https://linux.die.net/man/3/cmsg
struct msghdr msg = {0};
struct cmsghdr *cmsg;
int myfds[NUM_FD]; /* Contains the file descriptors to pass. */
char buf[CMSG_SPACE(sizeof myfds)]; /* ancillary data buffer */
int *fdptr;
msg.msg_control = buf;
msg.msg_controllen = sizeof buf;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
/* Initialize the payload: */
fdptr = (int *) CMSG_DATA(cmsg);
memcpy(fdptr, myfds, NUM_FD * sizeof(int));
/* Sum of the length of all control messages in the buffer: */
msg.msg_controllen = cmsg->cmsg_len;
This is because SCM_RIGHTS offers natively the possibility to pass an array of file descriptors, so we won't need multiple headers. A quick check on the kernel source code also confirmed this.
|
||
/* Parameter 2: size (type: PT_UINT32) */ | ||
evt_test->assert_numeric_param(2, (uint32_t)FULL_MESSAGE_LEN); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add the check for parameter 4 here. Something like this:
evt_test->assert_tuple_unix_param(4, PPM_AF_UNIX, UNIX_SERVER);
The problem is that this only works with the modern bpf probe at the moment. I would be curious to solve this for the other two drivers. I think this is part of a bigger discussion, but the way we are constructing the tuple for UNIX sockets it's kind of wrong in my opinion:
/* Pack the tuple info: |
|
||
snprintf(proc_dir, sizeof(proc_dir), "%s/proc/%d/", scap_get_host_root(), tinfo->pid); | ||
|
||
return scap_fd_scan_fd_dir(linux_platform, &platform->m_proclist, proc_dir, tinfo, &sockets_by_ns, &num_fds_ret, lasterr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the function that is responsible for calling the sinsp proc callbacks for the tinfo and each scanned fd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -65,6 +66,7 @@ struct scap_platform_vtable | |||
bool (*is_thread_alive)(struct scap_platform*, int64_t pid, int64_t tid, const char* comm); | |||
int32_t (*get_global_pid)(struct scap_platform*, int64_t *pid, char *error); | |||
int32_t (*get_threadlist)(struct scap_platform* platform, struct ppm_proclist_info **procinfo_p, char *lasterr); | |||
int32_t (*get_fdlist)(struct scap_platform* platform, struct scap_threadinfo *tinfo, char *lasterr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @gnosek about scap platform new method
I triggered a run of kernel testing framework against HEAD of the branch: https://github.com/falcosecurity/libs/actions/runs/6493764036 EDIT: ops, wrong; i need to push an upstream branch first. |
Pushed upstream branch to test: https://github.com/falcosecurity/libs/commits/PR1400; new run: https://github.com/falcosecurity/libs/actions/runs/6493859950 |
Thanks Fede! |
No new issues (same as on master!) Arm64:
amd64:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing work!
…remove useless forward decl Signed-off-by: Lorenzo Susini <[email protected]>
/milestone next-driver |
Looks like the test on |
… tests Signed-off-by: Lorenzo Susini <[email protected]>
0dd985c
to
73ad7c5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/approve
LGTM label has been added. Git tree hash: 867e8603ae65d8adbb184f842155c5f79276ee57
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/approve
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: Andreagit97, FedeDP, loresuso The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/hold cancel |
What type of PR is this?
/kind feature
Any specific area of the project related to this PR?
/area driver-kmod
/area driver-bpf
/area driver-modern-bpf
/area libscap
/area libsinsp
Does this PR require a change in the driver versions?
What this PR does / why we need it:
When using unix sockets, processes can pass open file descriptors to one another by using
sendmsg
andrecmsg
syscalls. This PR attempts to reflect this in the sinsp state. Whenever the recvmsg contains ancillary data, it checks for SCM_RIGHTS. If so, we proceed with a proc scan of the file descriptors of the receiving process, since it will have new open file descriptors that we missed.Since we only want to update the file descriptors, this PR introduces a new platform API to scan only that and avoid parsing information about the receiving process that we already have in the sinsp state. This, plus the fact that we can consider the frequency of SCM_RIGHTS messages pretty low, should mean that we are not introducing a big performance penalty.
Which issue(s) this PR fixes:
#1364
Fixes #
Special notes for your reviewer:
Does this PR introduce a user-facing change?: