Skip to content

Conversation

@tyhicks
Copy link
Contributor

@tyhicks tyhicks commented Oct 3, 2017

Important: This PR is a work in progress. The snapd tests need updating since this patch changes the default seccomp confinement from "kill" to "return an errno". @mvo5 asked me to go ahead and propose the merge and that the Snap folks could help see it to completion.

Two new seccomp logging features, introduced in Linux 4.14, allow for better snap confinement:

  1. SECCOMP_FILTER_FLAG_LOG allows for all actions taken by a filter, except for SECCOMP_RET_ALLOW, to be logged. Previously, only SECCOMP_RET_KILL actions were logged. This kept snap confinement from using SECCOMP_RET_ERRNO because applications would experience errors returned from illegal system calls but users and application developers would not have visibility into the decision making of when system calls should be denied. This new filter flag allows us to use the SECCOMP_RET_ERRNO action to return -1 with errno set to EPERM rather than killing snap processes that make illegal system calls.
  1. SECCOMP_RET_LOG is a new action that logs the syscall and then allows it. This was the missing piece that prevented would-be seccomp denials from being logged in devmode. Previously, enabling devmode simply meant that a seccomp filter would not be loaded due to the lack of this feature. Now we can load a filter that defaults to SECCOMP_RET_LOG for any system calls that aren't white listed.

The corresponding upstream libseccomp pull request has been merged. The corresponding upstream libseccomp-golang pull request is still pending final review. Upstream libseccomp and libseccomp-golang requested more complex, ABI friendly features but we can move forward with minimal changes to libseccomp and libseccomp-golang and then take advantage of the more robust "API level" checks in the future once the new versions of libseccomp and libseccomp-golang are released.

I've SRUed a minimal libseccomp change in Ubuntu Artful (2.3.1-2.1ubuntu2) and Ubuntu Zesty (2.3.1-2.1ubuntu2~17.04.1). The Ubuntu Xenial libseccomp SRU is still pending in xenial-proposed (2.3.1-2.1ubuntu2~16.04.1). I've proposed a minimal libseccomp-golang change to @mvo5's fork of libseccomp-golang, as that's what snapd is using.

To be clear, you can apply the patches in this PR today and test out the new seccomp features in Ubuntu Artful or Zesty.

Known issues that need to be addressed before this can be merged:

  • The tests need to be updated to take into account the new default seccomp action of SECCOMP_RET_ERRNO
  • The seccomp BPF files, for each snap installed in devmode, should be recompiled if the user boots into an older kernel that doesn't support the new SECCOMP_RET_LOG action. The kernel treats unknown actions as SECCOMP_RET_KILL which is appropriate from a security standpoint but is far from ideal considering that many devmode snaps would no longer work. The snap-seccomp change falls back to SECCOMP_RET_ALLOW when SECCOMP_RET_LOG is not supported by the currently running kernel.
  • libseccomp 2.3.1-2.1ubuntu2~16.04.1 needs to migrate from xenial-proposed to xenial-updates

The seccomp policy has historically used SECCOMP_RET_KILL to forcefully
kill a snap process that bumps into the walls of the sandbox. However,
killing the snap is not very user friendly. Changing the policy to use
SECCOMP_RET_ERRNO to return -1 with errno set to EPERM has been desired
but the kernel would not log those denials which could leave users and
developers confused about why their applications were experiencing
errors.

The 4.14 Linux kernel contains new seccomp logging controls which allows
snapd to request SECCOMP_RET_ERRNO to be logged. This patch makes use of
the new logging controls and switches the default action of the seccomp
policy to SECCOMP_RET_ERRNO so that snaps aren't killed when the perform
an illegal system call.

Signed-off-by: Tyler Hicks <[email protected]>
No seccomp policy was loaded for snaps installed in devmode since
seccomp didn't have the concept of "allow but log". The 4.14 Linux
kernel now has that functionality with the SECCOMP_RET_LOG action. This
patch changes the seccomp policy for devmode to log and allow any system
calls that would not be allowed if the snap was installed in jailmode.

Fixes: https://launchpad.net/bugs/1567597
Signed-off-by: Tyler Hicks <[email protected]>
@chipaca
Copy link
Contributor

chipaca commented Oct 3, 2017

squee!

Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

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

Everything looks good. Note that we have a convention to use curly braces around if / else statements to ensure there's no chance of mistaking the nesting.

While not strictly could we also take the change to kill the entire process rather than just the offending thread of execution? This would help with "mysterious" problems in multi-threaded applications. AFAIK the kernel has this feature now.

Copy link

@jdstrand jdstrand left a comment

Choose a reason for hiding this comment

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

This PR is following the agreements between the snapd and security teams and looks good on the whole. Thanks! Please see comments inline though.

I'm going to leave this as 'Request changes' for now so I can review the final PR.

debug("kernel doesn't support the seccomp(2) syscall");
else if (errno == EINVAL)
debug("kernel may not support the SECCOMP_FILTER_FLAG_LOG flag");

Copy link

Choose a reason for hiding this comment

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

This seems to be where the intended future check could be better (ie, using 'may'). What I was hoping for was that if SECCOMP_FILTER_FLAG_LOG is not available, then snapd would log that seccomp is mediating with EPERM but without logging so people understand the behavior change. Before, commands run under strict mode confinement with access violations would be killed with logging, but now on systems without SECCOMP_FILTER_FLAG_LOG support, they will be returned EPERM and continue to run with no logging, which may be confusing since the new denied behavior looks more like the previous allowed behavior than the previous denied behavior.

All that said, logging the fallback behavior IMO should happen at the snapd level once per snapd invocation since logging in snap-seccomp or in snap-confine would be way too chatty. @mvo5 - I suspect this would be more for whoever picks this up than for Tyler.

Copy link
Contributor Author

@tyhicks tyhicks Oct 3, 2017

Choose a reason for hiding this comment

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

That's a good point that logging the fallback shouldn't happen in snap-seccomp or snap-confine as it would be spammy in the logs.

libseccomp upstream was against exporting a function specifically for checking the validity of a filter flag or action. Applications linking against libseccomp will have the option to check the validity of the SECCOMP_FILTER_FLAG_LOG flag indirectly but using an "API level" based check that is currently being implemented. However, that check lumps together multiple features and, in this case, a single API level will be used to represent SECCOMP_FILTER_FLAG_LOG, SECCOMP_RET_LOG, and the unrelated SECCOMP_RET_KILL_PROCESS. That means that the kernel, libseccomp, and libseccomp-golang will all have to be in sync for libseccomp to report that the API level is supported.

Therefore, I think snapd would want to directly use the seccomp(2) syscall for checking if a filter flag is supported. Snapd could just use the technique that libseccomp is going to be using behind the scenes. I added a kernel selftest for the technique so that we can be sure that the kernel doesn't violate the agreement with userspace about how to check if a filter flag is supported. You can see the kernel selftest change here. Calling seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_LOG, NULL) should return -1 with errno set to EFAULT if the flag is supported by the kernel. Other errno values mean other things such as EINVAL meaning that the flag is not supported and ENOSYS meaning that the seccomp(2) syscall isn't even supported (so there's no way to even specify a filter flag).

return err
}

if fallback {
Copy link

Choose a reason for hiding this comment

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

Can you add a comment here stating that this fallback is resorting to the old pre-logging behavior of just allowing everything?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, good idea.

} else if line == "@complain" {
var fallback bool = false

secFilter, err = seccomp.NewFilter(seccomp.ActLog)
Copy link

Choose a reason for hiding this comment

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

While it would be a bug in the policy to have '@complain' in it more than once, the previous code stopped processing rules as soon as it found '@complain', but this code will add a NewFilter for every '@complain'. I think we should simply skip (perhaps logging with debug) additional '@complain' lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is no different than if one or more white listed system calls are placed above the first @complain directive. In that case, a new filter would be allocated when @complain was encountered and all the previously white listed system calls would be forgotten.

If we're going to handle multiple @complain directives, we should handle the case that I described, too. Unfortunately, libseccomp doesn't allow us to change the default action of an existing filter via seccomp_attr_set(..., SCMP_FLTATR_ACT_DEFAULT, SCMP_ACT_LOG) so an entirely new filter must be allocated.

What is your preferred solution here?

  1. Don't worry about the case that I mentioned. Address your concern by skipping NewFilter() when libseccomp-golang's GetDefaultAction() returns ActLog.
  2. Treat both situations as an error. (I don't know what it means to error out of the compile() function.)

Copy link

@jdstrand jdstrand Oct 4, 2017

Choose a reason for hiding this comment

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

What snap-confine would do before the move to snap-seccomp is it would preprocess the file, looking for @unrestricted or @complain. The rewrite took a shortcut and simply says "forget anything I did before if I find either of these". That was fine before when they were equivalent. Profile authors will sometimes put these directives anywhere in the file, so I think we need to account for that.

Instead of the two listed options, I suggest the previous behavior: preprocess the file, if @unrestricted found 1 or more times, store that off, if @complain found 1 or more times, store that off. Eg something along the lines of:

// Preprocess to allow @unrestricted and @complain to appear anywhere in the profile
unrestricted, complain := preprocess()
if unrestricted {
    seccomp.NewFilter(seccomp.ActAllow)
} else if complain {
    seccomp.NewFilter(seccomp.ActLog)
} else {
    seccomp.NewFilter(seccomp.ActErrno.SetReturnCode(C.EPERM))
}

addSecondaryArches(secFilter)
if not unrestricted {
    for scanner.Scan() {
        line := strings.TrimSpace(scanner.Text())
        parseLine(line, secFilter)
        ...
    }
}
...

This has the added benefit of adding the secondary arch in one spot.

@mvo5 - what do you think about preprocessing?

UPDATE: I adjusted the logic to be only 'if not unrestricted' after noticing the error

@tyhicks
Copy link
Contributor Author

tyhicks commented Oct 3, 2017

While not strictly could we also take the change to kill the entire process rather than just the offending thread of execution? This would help with "mysterious" problems in multi-threaded applications. AFAIK the kernel has this feature now.

@zyga I agree that the new SECCOMP_RET_KILL_PROCESS action would have been nice when the default action was to kill instead of returning an errno but I don't see the need for it at this point since we're changing the default action to SECCOMP_RET_ERRNO. It would require quite a bit of work to backport the kernel changes and then implement and backport the libseccomp and libseccomp-golang changes (nobody has started work on the userspace changes) so I'd like to better understand how we'd use SECCOMP_RET_KILL_PROCESS.

@kyrofa
Copy link
Contributor

kyrofa commented Oct 3, 2017

\o/ thanks @tyhicks, very pleased to see this!

It isn't immediately clear why seccomp rule compilation must end
immediately after falling back to ActAllow as the default action for
devmode. Leave a comment for easier code reading.

Signed-off-by: Tyler Hicks <[email protected]>
@mvo5
Copy link
Contributor

mvo5 commented Oct 5, 2017

I started looking into updating the tests. This will require some serious work because right now the tests are a bit naive. They rely on the fact that the kernel kills a process that violates the confinement. With the change to errno the syscallRunner and the tests itself need to be smater at identifying why a syscall has an error result (i.e. was it bogus input data which we give right now in most tests or was it a permission denied).

mvo5 added 6 commits October 5, 2017 16:57
The pervious tests simply checked if the process got killed when
doing an invalid syscall. The new seccomp behaviour is to use
EPERM as the errno for a denied syscall. This is now reflected
in the tests as well.
We no longer use main.SeccompRetKill in the seccomp code and the
name in the tests is misleading. Instead use {Allow,Deny}.
@mvo5
Copy link
Contributor

mvo5 commented Oct 6, 2017

This is now failing only because fedora uses the official libseccomp-golang branch - so once the ActLog bits are in the upstream libseccomp-golang fedora should be unblocked.

@pedronis pedronis changed the title snap-confine, snap-seccomp: Utilize new seccomp logging features snap-confine, snap-seccomp: utilize new seccomp logging features Oct 25, 2017
@niemeyer
Copy link
Contributor

@tyhicks This is lingering for quite a long time. Should we close it until the work is ready to be reviewed and merged?

@niemeyer
Copy link
Contributor

@mvo What do you think? (just now noticed you've pushed changes too)

@tyhicks
Copy link
Contributor Author

tyhicks commented Nov 10, 2017

@niemeyer @mvo5 I was told that that the Snappy team would take this PR over from here so I don't have plans to do any further work on it.

I would hate for the PR to be closed since the final dependency piece (libseccomp SRU in Ubuntu 16.04) should land next week (it is currently in xenial-proposed if anyone would like to test with it).

@zyga zyga added the Decaying label Nov 29, 2017
@tyhicks
Copy link
Contributor Author

tyhicks commented Jan 2, 2018

@mvo5 is there anything else that you need me to do for this pull request?

From an Ubuntu distro standpoint, the libseccomp SRU in Xenial still needs to go through. There's been renewed progress in verifying that SRU and it should happen very soon.

I don't believe that there's anything else that I need to do in this pull request but I'd like to confirm that.

@tyhicks
Copy link
Contributor Author

tyhicks commented Jan 2, 2018

libseccomp 2.3.1-2.1ubuntu2~16.04.1 has now migrated to xenial-updates.

@mvo5
Copy link
Contributor

mvo5 commented Jan 16, 2018

Sorry for the delay. We indeed waited for the sru update initially and missed when it happend. I updated the PR again and resolved conflicts, fixed build failures.

One challange is how to make fedora work with this PR. Fedora uses the upstream seccomp-golang (not our version which contains your patches already). So this means that upstream needs to merge your patches and the package in fedora needs updating to fully support this. Or we need to write the code in seccomp.go in such a way that it deals with a missing "seccomp.ActLog".

@jdstrand
Copy link

@mvo5 - we have a fallback mechanism to use KILL if the kernel doesn't support the new features. I wonder if we can detect at build time if we have the necessary api or if we can pass a build time flag and conditionally build this, falling back to the old method if the seccomp-golang doesn't support it.

@jdstrand
Copy link

Upstream doesn't seemed to have moved forward. I continue to see questions about setpriority and chown'ing to oneself in the forum. Did anything came from the idea of runtime detection of golang feature support as asked in #3998?

@tyhicks
Copy link
Contributor Author

tyhicks commented Feb 22, 2018

We could potentially split up this PR into two separate PRs. The split would happen in correspondence to the two features described in the description for this PR:

  1. Use SECCOMP_RET_ERRNO instead of SECCOMP_RET_KILL in strict mode
  2. Use SECCOMP_RET_LOG in dev mode

The first feature can be landed without any dependencies on libseccomp or libseccomp-golang since we only need to set the SECCOMP_FILTER_FLAG_LOG flag when snap-confine loads the filter using the seccomp() system call.

The second feature is what has a dependency on libseccomp and libseccomp-golang.

Of course, it may be much easier to conditionalize the use of seccomp.ActLog based on whether or not libseccomp-golang defines that constant but I'm not sure how to do that in Go.

@tyhicks
Copy link
Contributor Author

tyhicks commented Feb 26, 2018

Or we need to write the code in seccomp.go in such a way that it deals with a missing "seccomp.ActLog".

@mvo5 do you have ideas or examples you could link to regarding how this could be done?

tyhicks added 2 commits March 2, 2018 03:53
Allow some distros to make use of the ActLog action for devmode, despite
the upstream libseccomp-golang project not yet cutting a release, by
guessing at the const value. The guess is validated by looking at the
string representation of the action to make sure that it is the expected
string for ActLog.

This is possible because the mvo5 github fork of libseccomp-golang
contains the minimal changes necessary to support ActLog. The system
must also have a new enough libseccomp and kernel to support the log
action.

Signed-off-by: Tyler Hicks <[email protected]>
@tyhicks
Copy link
Contributor Author

tyhicks commented Mar 2, 2018

@mvo5 I've pushed a new commit that conditionally uses ActLog for devmode if libseccomp-golang is new enough to know about ActLog. It is a somewhat hacky way of detection but it should be very reliable.

Important: You need to merge mvo5/libseccomp-golang#2 into your libseccomp-golang fork before pulling in this PR. In fact, the snapd tests should be restarted once that mvo5/libseccomp-golang PR is merged in order to accurately test this change on Ubuntu.

@Conan-Kudo
Copy link
Contributor

Conan-Kudo commented Mar 2, 2018

@tyhicks Will this hard-require @mvo5's fork of libseccomp-golang? I'd rather stick with the upstream one for Fedora if I can...

EDIT: Ah, I see, you're still working on upstreaming it...

@tyhicks
Copy link
Contributor Author

tyhicks commented Mar 3, 2018

@Conan-Kudo this change lets consumers of @mvo5's fork of libseccomp-golang to make use of the new features. Those using older/unpatched libseccomp-golang, libseccomp, and/or kernels will continue to get the old behavior of not logging seccomp denials that would occur if the snap was running under strict confinement. This patch makes it so that snapd works in either environment.

@codecov-io
Copy link

codecov-io commented Mar 5, 2018

Codecov Report

Merging #3998 into master will increase coverage by 0.02%.
The diff coverage is 86.44%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #3998      +/-   ##
=========================================
+ Coverage   78.78%   78.8%   +0.02%     
=========================================
  Files         471     472       +1     
  Lines       34156   34198      +42     
=========================================
+ Hits        26911   26951      +40     
- Misses       5068    5070       +2     
  Partials     2177    2177
Impacted Files Coverage Δ
interfaces/system_key.go 63.63% <100%> (+1.13%) ⬆️
release/seccomp.go 100% <100%> (ø)
interfaces/seccomp/backend.go 76.38% <100%> (+0.67%) ⬆️
cmd/snap-seccomp/main.go 56.6% <78.37%> (+3.47%) ⬆️
overlord/hookstate/hookmgr.go 72% <0%> (-1.15%) ⬇️
wrappers/binaries.go 83.33% <0%> (+5.55%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 822f672...4bf7516. Read the comment docs.

@jdstrand jdstrand removed the Decaying label Mar 5, 2018
Copy link

@jdstrand jdstrand left a comment

Choose a reason for hiding this comment

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

The code changes look fine with some nitpicks from me regarding comments. I'll push those up.

We are also lacking unit tests for ActLog. It would be nice to have spread tests for complain mode and fallback, but that is going to be tricky since it isn't easily mocked and is dependent on the host.

I did blackbox test the changes and found that this is working as per design of the feature for strict mode. Ie,

  • on 16.04 with the updated kernel, libseccomp and snapd (with updated golang-seccomp) strict mode snap receives EPERM instead of kill and the denial is logged
  • on 16.04 with non-updated kernel but updated libseccomp/snapd, strict snap receives EPERM instead of kill with no logging
  • on 16.04 with updated kernel/snap but non-updated libseccomp, strict snap receives EPERM instead of kill with logging (this is expected due to the ifndef in snap-confine)
  • on 16.04 with updated snapd but non-updated libseccomp/kernel, strict snap receives EPERM instead of kill with no logging

This also works correctly with complain mode:

  • on a 16.04 with updated kernel, libseccomp and snapd/golang-seccomp, devmode snap policy violation correctly logs
  • on 16.04 with non-updated kernel but updated libseccomp/snapd, devmode snap policy violation receives seccomp KILL until seccomp policy is recompiled (since the kernel doesn't ActLog. This is Tyler's second bulletpoint that needs addressing). After recompile, policy violation is allowed with no logging
  • on 16.04 with updated kernel/snap but non-updated libseccomp, devmode snap policy violation correctly logs (this is expected due to the ifndef in snap-confine)
  • on 16.04 with updated snapd but non-updated libseccomp/kernel, devmode snap policy violation receives seccomp KILL until seccomp policy is recompiled (since the kernel doesn't ActLog. This is Tyler's second bulletpoint that needs addressing). After recompile, policy violation is allowed with no logging

At this point, we need to incorporate a check for ActLog in system-key so devmode snaps aren't receiving kill rebooting into kernels without ActLog from kernels with ActLog

};
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) != 0) {
die("cannot apply seccomp profile");
if (seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_LOG, &prog)) {
Copy link

Choose a reason for hiding this comment

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

We typically like to use '!= 0' as part of the coding style (see prctl call below).

return actLog
}

return seccomp.ActAllow
Copy link

Choose a reason for hiding this comment

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

A comment here for why returning seccomp.AcctAllow would be nice.

Copy link

Choose a reason for hiding this comment

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

Done


if complainAct == seccomp.ActAllow {
unrestricted = true
}
Copy link

Choose a reason for hiding this comment

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

If complainAct evaluated to seccomp.ActAllow and seccomp.NewFIlter() completed without error, then we set unrestricted to true here, but didn't write '@unrestricted' to the buffer like we do in the previous case statement. This is done this way to fallback to the old behavior. A comment here would be nice. Eg:

// Set unrestricted to 'true' to fallback to the pre-ActLog behavior of
// simply setting the allow filter without adding any rules.

Copy link

Choose a reason for hiding this comment

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

Done

syscall(l[0], l[1], l[2], l[3], l[4], l[5], l[6]);
syscall(SYS_exit, 0, 0, 0, 0, 0, 0);
syscall_ret = syscall(l[0], l[1], l[2], l[3], l[4], l[5], l[6]);
if (syscall_ret < 0 && errno == 911) {
Copy link

Choose a reason for hiding this comment

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

A comment that 911 is the mocked value would be nice.

Copy link

Choose a reason for hiding this comment

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

Done

}
l := strings.Split(string(output), "\n")
return fmt.Sprintf("Showing last 10 lines of dmesg:\n%s", strings.Join(l[len(l)-10:], "\n"))
}
Copy link

Choose a reason for hiding this comment

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

It isn't clear why you dropped this since it is meant to only assist with debug output in the event of unexpected failure or success.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To be clear, this is a question for @mvo5 since this change was made in c09d060

@jdstrand
Copy link

jdstrand commented Mar 6, 2018

FYI, I implemented the system-key bits so that devmode snaps have their policy recompiled when booting into a kernel without logging support.

@jdstrand
Copy link

jdstrand commented Mar 6, 2018

@tyhicks - can you review my commits to this PR which adds some complain mode testing and the rebooting into devmode? I retested all scenarios and this is working as expected.

}

// SecCompActions returns a sorted list of seccomp actions like
// []string{"allow", "errno", "kill", "log", "trace", "trap"}.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is worth pointing out that the following kernel commit changes kill to kill_thread (in 4.14 and newer):

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fd76875ca289a3d4722f266fd2d5532a27083903

This means that seccomp policy will be recompiled when booting between a kernel older than 4.14 and a kernel equal to or newer than 4.14. However, I think that's generally a good process to follow when such a low level kernel seccomp change is detected.

@tyhicks
Copy link
Contributor Author

tyhicks commented Mar 6, 2018

@tyhicks - can you review my commits to this PR which adds some complain mode testing and the rebooting into devmode? I retested all scenarios and this is working as expected.

Your additional commits all look correct to me. Thanks for those!

@jdstrand
Copy link

jdstrand commented Mar 6, 2018

FYI, I looked at sqlite sources and this PR should obviate the need for using the snapcraft-preload for sqlite users. I also found the glib file IO (chown) works too: https://forum.snapcraft.io/t/chown-to-current-user/2831/9 as well as 0ad (setpriority): https://forum.snapcraft.io/t/auto-connecting-the-process-control-interface-for-the-0ad-snap/507/20.

@jdstrand
Copy link

jdstrand commented Mar 7, 2018

FYI, the failing test is weird. It is in interfaces/seccomp/backend_test.go, but in an unrelated test and the failures are only on debian-9 and linode ubuntu 16.04 32bit, but after 3 retries, those two fail consistently. I found this puzzling since there shouldn't be anything in this PR's changes that is specific to those releases that would make them fail AFAICS. Since @zyga wrote the initial tests, I've asked him to take a look too.

@jdstrand
Copy link

jdstrand commented Mar 7, 2018

Also, I tested this with an electron app that had trouble with chown, and this PR makes that snap work too.

@zyga zyga force-pushed the seccomp-logging branch from 51c0d68 to 4bf7516 Compare March 8, 2018 10:35
Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

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

+1 with minor comments


func SecCompSupportsAction(action string) bool {
i := sort.SearchStrings(SecCompActions, action)
if i < len(SecCompActions) && SecCompActions[i] == action {
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: we have strutil.SortedListContains for this

#define SECCOMP_FILTER_FLAG_LOG 2
#endif

#ifndef seccomp
Copy link
Contributor

Choose a reason for hiding this comment

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

Is seccomp defined in the pre-processor usually?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, the seccomp() syscall may not have a glibc wrapper:

https://lwn.net/Articles/655028/

It is important that we wrap it in that situation.

//#endif
//
//#ifndef SECCOMP_RET_LOG
//#define SECCOMP_RET_LOG 0x7ffc0000U
Copy link
Contributor

Choose a reason for hiding this comment

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

@jdstrand
Copy link

jdstrand commented Mar 8, 2018

Thanks @zyga for the rereview, thanks @tyhicks for the patches and thank you to everyone else involved! :)

@jdstrand jdstrand merged commit cf8e065 into canonical:master Mar 8, 2018
jdstrand pushed a commit to jdstrand/snapd that referenced this pull request Mar 8, 2018
…onical#3998)

* snap-confine, snap-seccomp: Default to SECCOMP_RET_ERRNO

The seccomp policy has historically used SECCOMP_RET_KILL to forcefully
kill a snap process that bumps into the walls of the sandbox. However,
killing the snap is not very user friendly. Changing the policy to use
SECCOMP_RET_ERRNO to return -1 with errno set to EPERM has been desired
but the kernel would not log those denials which could leave users and
developers confused about why their applications were experiencing
errors.

The 4.14 Linux kernel contains new seccomp logging controls which allows
snapd to request SECCOMP_RET_ERRNO to be logged. This patch makes use of
the new logging controls and switches the default action of the seccomp
policy to SECCOMP_RET_ERRNO so that snaps aren't killed when the perform
an illegal system call.

Signed-off-by: Tyler Hicks <[email protected]>
@jdstrand
Copy link

jdstrand commented Mar 8, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants