Skip to content
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

RFE: user notification #147

Closed
wants to merge 3 commits into from
Closed

Conversation

tych0
Copy link
Contributor

@tych0 tych0 commented Mar 19, 2019

Here's the user-notification infrastructure, and a test to make sure it really works :)

@pcmoore pcmoore changed the title User notification RFE: user notification Mar 19, 2019
@pcmoore
Copy link
Member

pcmoore commented Mar 19, 2019

Thanks @tych0, although without looking at any of the code, it appears as though you are failing the Travis tests, can you look into that?

@tych0
Copy link
Contributor Author

tych0 commented Mar 19, 2019 via email

@coveralls
Copy link

coveralls commented Mar 20, 2019

Coverage Status

Coverage decreased (-2.2%) to 89.873% when pulling 258505c on tych0:user-notification into e7c97e3 on seccomp:master.

@tych0
Copy link
Contributor Author

tych0 commented Mar 20, 2019

I'm confused,

/home/travis/build/seccomp/libseccomp/src/.libs/libseccomp_la-arch-mips64-syscalls.gcda:cannot open data file, assuming not executed
File 'arch-mips64-syscalls.c'
No executable lines
Removing 'libseccomp_la-arch-mips64-syscalls.gcno##arch-mips64-syscalls.c.gcov'

/home/travis/build/seccomp/libseccomp/src/.libs/libseccomp_la-arch-parisc64.gcno:no functions found
/home/travis/build/seccomp/libseccomp/src/.libs/libseccomp_la-arch-aarch64-syscalls.gcda:cannot open data file, assuming not executed
File 'arch-aarch64-syscalls.c'
No executable lines
Removing 'libseccomp_la-arch-aarch64-syscalls.gcno##arch-aarch64-syscalls.c.gcov'

? I don't really know how the coverage stuff works.

@pcmoore
Copy link
Member

pcmoore commented Mar 20, 2019

Sorry for the delay, between the day job and the kernel development window opening, it's been a busy week.

Looks like it's failing because the Travis kernels don't have this feature yet. I guess there's some feature check/skip mechanism in the test suite for this?

Yes, libseccomp has the concept of "API levels" which determine what is supported. Normally these are determined automatically at runtime, but you can force a particular level if desired. See seccomp_api_get() and seccomp_apt_set() for some more information.

The live test types allow you to specify a minimum API level required for them to run (you can see your current level with tools/scmp_api_level), see tests/47-live-kill_process.tests for an example.

? I don't really know how the coverage stuff works.

It should "just work" from a Travis perspective. There are some makefile targets for doing it locally via gcov/lcov, but that is currently broken with current gcc, although they are "working on it".

Let's not worry about the coverage too much right now, let's get the tests working first, that's most important.

test type: live

# Testname API Result
50-user-notification 5 ZERO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nit, but as a convention, the "live" tests follow the naming format of "-live-<test_name>" where <test_name> uses underscores not hyphens.

@tych0
Copy link
Contributor Author

tych0 commented Mar 20, 2019

Yeah, I figured out the live stuff today, I think all that should be working now.

src/db.c Show resolved Hide resolved
@pcmoore
Copy link
Member

pcmoore commented Apr 12, 2019

I'm currently working my way through these patches, but one nitpick that doesn't lend itself well to the GitHub review mechanism: please make sure the patches have some some of subject prefix (similar to how we do things in kernel land). For example, I would rather "add API support for the SPEC_ALLOW flag" be "api: add support for the SPEC_ALLOW flag". You could probably add an "api:" prefix to the main user notification patch too.

* SECCOMP_RET_USER_NOTIF was added in kernel 5.0. It will not be defined on
* older kernels. This version also added the structures below, so let's define
* those if the header doesn't have this definiton.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generally don't include commentary like this in the libseccomp header file :)

I think it's both appropriate and a good idea to add a one-liner about user notification first appearing in Linux v5.0 but I would leave it at that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I probably wasn't clear enough about this previously, but this is what I was thinking for a comment:

/* User notification bits was added in Linux v5.0 */

@pcmoore
Copy link
Member

pcmoore commented Apr 12, 2019

I would also include a brief explanation of the user notification feature in the commit description so we have some info in the git log about how this is expected to work.

src/api.c Show resolved Hide resolved
src/api.c Outdated
*req = malloc(sizes.seccomp_notif);
if (!*req)
return -ENOMEM;
memset(*req, 0, sizes.seccomp_notif);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We define a malloc wrapper named zmalloc in src/helper.c which does the allocation/zero'ing for you; please use that instead.

src/api.c Outdated
free(req);
return -ENOMEM;
}
memset(*resp, 0, sizes.seccomp_notif_resp);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

src/api.c Outdated
@@ -537,3 +551,64 @@ API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)

return 0;
}

/* NOTE - function header comment in include/seccomp.h */
int seccomp_alloc_notifications(struct seccomp_notif **req,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be prefaced with "API" to ensure the visibility is set correctly.

src/api.c Outdated
static struct seccomp_notif_sizes sizes = {};

if (sizes.seccomp_notif == 0) {
int ret = syscall(__NR_seccomp, SECCOMP_GET_NOTIF_SIZES, 0, &sizes);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be moved to a function in src/system.c and it should make use of _support_seccomp_syscall and sys_chk_seccomp_syscall() to see if it safe/possible to use the seccomp() syscall.

src/api.c Outdated
return -1;
}

*req = malloc(sizes.seccomp_notif);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous malloc() comments.

src/api.c Outdated
return -ENOMEM;
memset(*req, 0, sizes.seccomp_notif);

*resp = malloc(sizes.seccomp_notif_resp);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another one. I'm going to stop pointing these out and just assume you'll change them all :)

src/api.c Outdated
int seccomp_alloc_notifications(struct seccomp_notif **req,
struct seccomp_notif_resp **resp)
{
static struct seccomp_notif_sizes sizes = {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This information should probably live in src/system.c. See the other comments in this function.

@@ -59,6 +59,7 @@ cdef extern from "seccomp.h":
SCMP_FLTATR_API_TSKIP
SCMP_FLTATR_CTL_LOG
SCMP_FLTATR_SPEC_ALLOW
SCMP_FITATR_NEW_LISTENER
Copy link
Member

@pcmoore pcmoore Apr 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"_FLTATR_" not "_FITATR_"

@@ -123,6 +123,20 @@ int main(int argc, char *argv[])
goto out;
}

expected = 1;
rc = seccomp_attr_set(ctx, SCMP_FLTATR_NEW_LISTENER, expected);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my previous comments about this test as well as the missing Python equivalent.

test type: live

# Testname API Result
50-live-user_notification 5 USER_NOTIF
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you need to respin this patch anyway, you might as well rebase to the current master branch and resolve the test number conflict (we now have a test 50).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also should have a Python version of this test.

* loaded. This is only valid after seccomp_load() with
* SCMP_FLTATR_NEW_LISTENER set.
*/
int seccomp_notif_get_fd(const scmp_filter_ctx ctx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just call this seccomp_notif_fd(...)? Or do you see us needing to get/put the FD for some reason in the future?

@pcmoore
Copy link
Member

pcmoore commented Apr 19, 2019

There were a few carryover items that needed to be addressed, and a few new things, but overall I think you're pretty close. I think the biggest thing is you need to provide proper Python tests (and run them), as there was one typo in the Python bindings that would have been caught. There is also the issue of documenting the API and data types in a manpage. If they are documented elsewhere, that's fine, but we need to reference it in the libseccomp specific manpages.

@pcmoore
Copy link
Member

pcmoore commented Apr 19, 2019

One more thing, since the first patch was pretty straight forward, and could stand alone, I went ahead and merged that just now via e7c97e3. Feel free to drop that from future respins.

*/
int seccomp_notif_alloc(struct seccomp_notif **req,
struct seccomp_notif_resp **resp);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these new APIs need to be documented in one or more manpages.

@@ -66,6 +67,7 @@ enum scmp_filter_attr {
SCMP_FLTATR_API_TSKIP = 5, /**< allow rules with a -1 syscall */
SCMP_FLTATR_CTL_LOG = 6, /**< log not-allowed actions */
SCMP_FLTATR_SPEC_ALLOW = 7, /**< disable SSB mitigation */
SCMP_FLTATR_NEW_LISTENER = 8, /**< returns a listener fd */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my previous comment regarding attribute names (my apologies once again). Similar to the last one, this should probably be SCMP_FLTATR_CTL_<blah>.

@tych0
Copy link
Contributor Author

tych0 commented Apr 23, 2019 via email

@tych0
Copy link
Contributor Author

tych0 commented Apr 23, 2019 via email

@pcmoore
Copy link
Member

pcmoore commented Apr 23, 2019

That doesn't work. seccomp_attr_set() -> db_col_attr_set() -> sys_chk_seccomp_flag() -> checks the actual flag. We could switch the implementation of db_col_attr_set() if you want, but then it wouldn't match the other ones.

If you look at sys_chk_seccomp_flag(...) you'll notice that it checks the _support_* variable associated with the flag before calling into _sys_chk_seccomp_flag_kernel(...). It does this to solve exactly the problem you are describing.

@tych0
Copy link
Contributor Author

tych0 commented Apr 23, 2019 via email

@pcmoore
Copy link
Member

pcmoore commented Apr 23, 2019

Hmm, I must have misread this morning. In any case, it still fails for me without this, so something else is being picky.

If you end up getting stuck, let me know.

@pcmoore
Copy link
Member

pcmoore commented Apr 25, 2019

@tych0 I see there are updates to the PR and wanted to check to see if you are ready for us to review them again, or are they still a work in progress? Either approach is fine, I just want to make sure we aren't holding you up.

@tych0
Copy link
Contributor Author

tych0 commented Apr 25, 2019 via email

@drakenclimber
Copy link
Member

I'm out of the office Friday and Monday, but I can look them over on Tuesday.

@tych0
Copy link
Contributor Author

tych0 commented Apr 25, 2019 via email

@pcmoore
Copy link
Member

pcmoore commented Apr 26, 2019

I can only write so much troff at a time :)

Me too. I love projects that have manpages, but I hate writing them :)

FWIW, we do have an issue open (#83) to look into alternate source formats for our manpages to make life easier.

@pcmoore
Copy link
Member

pcmoore commented Apr 26, 2019

I think something may be wrong @tych0 - it doesn't look like I'm seeing all of your updates. As an example, I know you were working on adding the Python tests, but I'm not seeing any additions/changes to the Python tests in this PR.

???

@pcmoore
Copy link
Member

pcmoore commented Apr 30, 2019

The SPEC_ALLOW patch looked good to me so I went ahead and merged it via 11667b4 with a follow patch in a15a87c to rename SCMP_FLTATR_SPEC_ALLOW to SCMP_FLTATR_CTL_SSB as discussed in the review.

Signed-off-by: Tycho Andersen <tycho@tycho.ws>
Kernel 5.0 includes the new user notification return code. Here's all the
infrastructure to handle that.

The idea behind the user notification return code is that the filter stops
the syscall, and forwards it to a "listener fd" that is created when
installing a filter. Then then some userspace task can listen and process
events accordingly by taking some (or no) action in userspace, and then
returning a value from the command.

Signed-off-by: Tycho Andersen <tycho@tycho.ws>
Here's some basic documentation for the seccomp_notif_* family of
functions. I put them all on the same page because that seems to make the
most sense; they'll all be used together.

Signed-off-by: Tycho Andersen <tycho@tycho.ws>
@pcmoore
Copy link
Member

pcmoore commented May 2, 2019

I happened to be in the same room as @tych0 this week, so I offered to pick up this patch to add the missing bits so he could focus on other things. I'm going to close this PR as a result, in favor of a new PR with the updated patches in just a moment.

@pcmoore pcmoore closed this May 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants