-
Notifications
You must be signed in to change notification settings - Fork 186
RFE: add new API to enable addfd support for seccomp notifier #454
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
base: main
Are you sure you want to change the base?
Conversation
|
Hi @realsdx, thanks for the PR :) Unfortunately, it looks like the the CI test are failing because of a missing libseccomp/include/seccomp.h.in Lines 391 to 408 in 7db46d7
|
|
FWIW, if I made the following changes on top of your PR I was able to get everything building: diff --git a/include/seccomp.h.in b/include/seccomp.h.in
index 024aca537f64..568eabaad949 100644
--- a/include/seccomp.h.in
+++ b/include/seccomp.h.in
@@ -406,6 +406,11 @@ struct seccomp_notif_resp {
__u32 flags;
};
+#endif
+
+/* seccomp_notif_addfd and ADDFD_FLAG_SETFD was added in kernel v5.10 */
+#ifndef SECCOMP_ADDFD_FLAG_SETFD
+#define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0)
struct seccomp_notif_addfd {
__u64 id;
__u32 flags;
diff --git a/src/system.h b/src/system.h
index 495050fb2e75..87bf8a6e832d 100644
--- a/src/system.h
+++ b/src/system.h
@@ -180,14 +180,6 @@ struct seccomp_notif_resp {
__u32 flags;
};
-struct seccomp_notif_addfd {
- __u64 id;
- __u32 flags;
- __u32 srcfd;
- __u32 newfd;
- __u32 newfd_flags;
-};
-
#define SECCOMP_IOC_MAGIC '!'
#define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr)
#define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type)
@@ -201,6 +193,24 @@ struct seccomp_notif_addfd {
#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64)
#endif /* SECCOMP_RET_USER_NOTIF */
+/* seccomp_notif_addfd and ADDFD_FLAG_SETFD was added in kernel v5.10 */
+#ifndef SECCOMP_ADDFD_FLAG_SETFD
+#define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0)
+struct seccomp_notif_addfd {
+ __u64 id;
+ __u32 flags;
+ __u32 srcfd;
+ __u32 newfd;
+ __u32 newfd_flags;
+};
+#endif
+
+/* SECCOMP_IOCTL_NOTIF_ADDFD was added in kernel v5.10 */
+#ifndef SECCOMP_IOCTL_NOTIF_ADDFD
+#define SECCOMP_IOCTL_NOTIF_ADDFD SECCOMP_IOW(3, \
+ struct seccomp_notif_addfd)
+#endif
+
/* non-public ioctl number for backwards compat (see system.c) */
#define SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR SECCOMP_IOR(2, __u64) |
|
Another quick comment, we'll likely want to add a new API level to |
The current API levels are based on different Seccomp actions and filter flags. If we add a new level for addfd support, it would be based on IOCTL support. What would be the best way to determine the addfd support at runtime? One issue with probing the IOCTL with notifyfd is that we need a valid notify fd first. Since we cannot uninstall the seccomp filter once it's loaded, is it a good idea to probe for ADDFD IOCTL? |
My apologies, I suspect I was stuck in the thinking that we were doing this through the @drakenclimber do you have any thoughts on this? |
|
Okay, I'm not seeing any good ideas around the runtime detection so let's just go ahead and skip that. Let me take a closer look at the rest of the PR ... |
pcmoore
left a comment
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.
Added some thoughts on the PR, overall it looks good, just a few minor things to polish up :)
|
@realsdx mentioned For reference, |
timscharfenort8
left a comment
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.
Good work
|
This is looking good @realsdx, did you want to do another push to this PR branch with all of the changes discussed and remove the draft flag on this PR? |
src/system.h
Outdated
| __u32 newfd; | ||
| __u32 newfd_flags; | ||
| }; | ||
| #endif |
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.
Since we're defining this in include/seccomp.h we shouldn't need it here, unless I'm misunderstanding something?
src/system.h
Outdated
| /* Addfd and return it, atomically. ADDFD_FLAG_SEND was added in kernel 5.14 */ | ||
| #ifndef SECCOMP_ADDFD_FLAG_SEND | ||
| #define SECCOMP_ADDFD_FLAG_SEND (1UL << 1) | ||
| #endif |
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.
Same thing here, we already define this in include/seccomp.h if the system headers don't define it for us.
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 part I am not quite sure yet, as this whole thing only gets loaded when the kernel's seccomp headers are not available. But why would we need to keep the SECCOMP_IOCTL_NOTIF_ADDFD then?
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.
In the early days of libseccomp it was not uncommon to build the library on a system that was running an older kernel without libseccomp support and the necessary kernel header files. Including the relevant kernel header bits (macros, structure definitions) allows us to build the libseccomp library on a system without libseccomp support, but still have it run as one would expect on a modern system with a Linux kernel that fully supports seccomp.
Does that help?
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.
Okay makes sense. I will remove the duplicate flags and structs. Thanks for clarifying.
|
@drakenclimber aside from the two things mentioned above, what do you think of this? |
I'll look into it this week. Thanks for reminding me :) |
drakenclimber
left a comment
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 think this is a really good first cut. I had a few comments that will require some minor rework, but overall it's solid.
Thanks for the contribution 👍
| /* seccomp_notif_addfd and ADDFD_FLAG_SETFD was added in kernel v5.10 */ | ||
| #ifndef SECCOMP_ADDFD_FLAG_SETFD | ||
| #define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0) | ||
| struct seccomp_notif_addfd { |
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.
Why is the struct seccomp_notif_addfd() definition inside of the #ifndef SECCOMP_ADDFD_FLAG_SETFD? Seems strange to me.
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.
That's a fair question. The seccomp_notif_addfd struct is only used when SECCOMP_ADDFD_FLAG_SETFD is present and supported, so using the presence of SECCOMP_ADDFD_FLAG_SETFD to serve as a proxy for the definition of seccomp_notif_addfd seems like a reasonable thing to do.
I'm definitely open to other ideas and I'm sure @realsdx would be as well.
https://man7.org/linux/man-pages/man2/seccomp_unotify.2.html
src/system.c
Outdated
| if (state.sup_user_notif <= 0) | ||
| return -EOPNOTSUPP; | ||
|
|
||
| int rc = ioctl(fd, SECCOMP_IOCTL_NOTIF_ADDFD, addfd); |
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.
As a convention, we define variables at the start of the function in libseccomp. (Aside - this is a relic of the C89 standard, but it's generally good practice today even though it's no longer required.)
tests/63-live-notify_addfd.c
Outdated
| close(sock_pair[1]); | ||
| exit(bytes_read); // bytes_read should be 0, as it's reading /dev/null | ||
| } else { | ||
| close(sock_pair[1]); // close the child's end |
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 recommend moving the parent code to its own function. This will improve readability and better scope the variables that are only needed by the parent process.
And, as outlined above, it will fix the erroneous goto logic in the child, as you'll have to handle that properly in its own function
tests/63-live-notify_addfd.c
Outdated
| goto out; | ||
| } | ||
|
|
||
| new_fd = openat(AT_FDCWD, "/dev/null", O_RDONLY); |
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.
Does reading /dev/null provide a good test (since it always results in 0 bytes read)? Or would reading /dev/zero be a better test? Reading it could provide a non-zero length.
I don't have a strong preference here - just wondering
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.
The intent is to simulate a behavior, where the supervisee wants to access a 'restricted' file but gets nothing. Let me know if that makes sense.
I don't have any better ideas here either. Bummer. |
24c9882 to
805517e
Compare
|
First of all, apologies for the delay. I was on a long vacation, and then some work piled up. I should’ve replied much sooner! I’ve made several updates to the C test code (refactored the parent and child functions) and cleaned up some of the debug code.
I still have a few doubts regarding the duplicate macros @pcmoore |
I think I just answered those in the code review/comment section, but please let me know if that still doesn't make sense. |
|
Thank you, @pcmoore, for the explanation. It's much clearer to me now. I'll update the code with the remaining changes. |
Add support for the seccomp notify addfd feature in the core API. It allows a caller to install fd in target's fd table. Signed-off-by: Sudipta Pandit <sudpandit@microsoft.com>
Add seccomp notify addfd support to the Python API and update the receive_notify and respond_notify methods to accept user-provided notify fd's as an optional argument. Signed-off-by: Sudipta Pandit <sudpandit@microsoft.com>
Add live test for seccomp_notify_addfd() that verifies fd injection capabilities by intercepting openat() syscalls and replacing the target's file descriptor for it's C and Python API. Signed-off-by: Sudipta Pandit <sudpandit@microsoft.com>
Signed-off-by: Sudipta Pandit <sudpandit@microsoft.com>
Signed-off-by: Sudipta Pandit <sudpandit@microsoft.com>
|
What do you think @drakenclimber ? |
This PR adds a new API to enable
addfdsupport for seccomp notifiers. It introduces changes to theseccomp_notifandseccomp_notif_respstructures to handle theaddfdoperation, allowing file descriptors to be passed through a seccomp notifier.It also adds supporting man page entry and unit regression tests for both C and Python APIs.