interfaces: simplify snap-confine by just loading pre-generated bpf code #3431

Merged
merged 95 commits into from Jun 22, 2017
Commits
Jump to file or symbol
Failed to load files and symbols.
+1,765 −1,886
Split
View
@@ -22,6 +22,7 @@ package arch
import (
"log"
"runtime"
+ "syscall"
)
// ArchitectureType is the type for a supported snappy architecture
@@ -38,6 +39,9 @@ func SetArchitecture(newArch ArchitectureType) {
arch = newArch
}
+// FIXME: rename all Ubuntu*Architecture() to SnapdArchitecture()
+// (or DpkgArchitecture)
+
// UbuntuArchitecture returns the debian equivalent architecture for the
// currently running architecture.
//
@@ -62,11 +66,62 @@ func ubuntuArchFromGoArch(goarch string) string {
"ppc64le": "ppc64el",
"s390x": "s390x",
"ppc": "powerpc",
+ // available in debian and other distros
+ "ppc64": "ppc64",
@jdstrand

jdstrand Jun 20, 2017

Contributor

I just noticed that arch_test.go is missing s390x and ppc64.

@mvo5

mvo5 Jun 21, 2017

Collaborator

Thanks, added.

}
ubuntuArch := goArchMapping[goarch]
if ubuntuArch == "" {
- log.Panicf("unknown goarch %v", goarch)
+ log.Panicf("unknown goarch %q", goarch)
+ }
+
+ return ubuntuArch
+}
+
+// UbuntuKernelArchitecture return the debian equivalent architecture
+// for the current running kernel. This is usually the same as the
+// UbuntuArchitecture - however there maybe cases that you run e.g.
+// a snapd:i386 on an amd64 kernel.
+func UbuntuKernelArchitecture() string {
+ var utsname syscall.Utsname
+ if err := syscall.Uname(&utsname); err != nil {
+ log.Panicf("cannot get kernel architecture: %v", err)
+ }
+
+ // syscall.Utsname{} is using [65]int8 for all char[] inside it,
+ // this makes converting it so awkward. The alternative would be
+ // to use a unsafe.Pointer() to cast it to a [65]byte slice.
+ // see https://github.com/golang/go/issues/20753
+ kernelArch := make([]byte, 0, len(utsname.Machine))
+ for _, c := range utsname.Machine {
+ if c == 0 {
+ break
+ }
+ kernelArch = append(kernelArch, byte(c))
+ }
+
+ return ubuntuArchFromKernelArch(string(kernelArch))
+}
+
+// ubuntuArchFromkernelArch maps the kernel architecture as reported
+// via uname() to the dpkg architecture
+func ubuntuArchFromKernelArch(utsMachine string) string {
+ kernelArchMapping := map[string]string{
+ // kernel ubuntu
+ "i686": "i386",
+ "x86_64": "amd64",
+ "armv7": "armhf",
+ "aarch64": "arm64",
+ "ppc64le": "ppc64el",
+ "s390x": "s390x",
+ "ppc": "powerpc",
@jdstrand

jdstrand Jun 19, 2017

Contributor

Note that the C code also has ppc64 that in seccomp maps to SCMP_ARCH_PPC64. I realize that ppc64 is not a thing in Ubuntu (so ubuntuArchFromKernelArch understandably doesn't have it), but I wonder about other distros like Fedora, CentOS, Suse, etc. Is ppc64 supported anywhere in cross-distro? ppc64 is a thing in Debian: https://wiki.debian.org/PPC64

@mvo5

mvo5 Jun 19, 2017

Collaborator

Thanks, nice catch. I added it for completeness (with a comment).

+ // available in debian and other distros
+ "ppc64": "ppc64",
@jdstrand

jdstrand Jun 20, 2017

Contributor

I think you need to go fmt for the spacing here.

@mvo5

mvo5 Jun 21, 2017

Collaborator

The comment is the reason why the spacing here is different, go fmt was applied :)

@jdstrand

jdstrand Jun 21, 2017

Contributor

Ah :)

+ }
+
+ ubuntuArch := kernelArchMapping[utsMachine]
+ if ubuntuArch == "" {
+ log.Panicf("unknown kernel arch %q", utsMachine)
}
return ubuntuArch
View
@@ -39,6 +39,8 @@ func (ts *ArchTestSuite) TestUbuntuArchitecture(c *C) {
c.Check(ubuntuArchFromGoArch("arm"), Equals, "armhf")
c.Check(ubuntuArchFromGoArch("arm64"), Equals, "arm64")
c.Check(ubuntuArchFromGoArch("ppc64le"), Equals, "ppc64el")
+ c.Check(ubuntuArchFromGoArch("ppc64"), Equals, "ppc64")
+ c.Check(ubuntuArchFromGoArch("s390x"), Equals, "s390x")
}
func (ts *ArchTestSuite) TestSetArchitecture(c *C) {
View
@@ -150,48 +150,13 @@ decode-mount-opts/decode-mount-opts$(EXEEXT): LIBS += -Wl,-Bstatic $(decode_moun
## snap-confine
##
-all_tests = \
- snap-confine/tests/test_bad_seccomp_filter_args \
- snap-confine/tests/test_bad_seccomp_filter_args_clone \
- snap-confine/tests/test_bad_seccomp_filter_args_mknod \
- snap-confine/tests/test_bad_seccomp_filter_args_null \
- snap-confine/tests/test_bad_seccomp_filter_args_prctl \
- snap-confine/tests/test_bad_seccomp_filter_args_prio \
- snap-confine/tests/test_bad_seccomp_filter_args_quotactl \
- snap-confine/tests/test_bad_seccomp_filter_args_socket \
- snap-confine/tests/test_bad_seccomp_filter_args_termios \
- snap-confine/tests/test_bad_seccomp_filter_length \
- snap-confine/tests/test_bad_seccomp_filter_missing_trailing_newline \
- snap-confine/tests/test_complain \
- snap-confine/tests/test_complain_missed \
- snap-confine/tests/test_noprofile \
- snap-confine/tests/test_restrictions \
- snap-confine/tests/test_restrictions_working \
- snap-confine/tests/test_restrictions_working_args \
- snap-confine/tests/test_restrictions_working_args_clone \
- snap-confine/tests/test_restrictions_working_args_mknod \
- snap-confine/tests/test_restrictions_working_args_prctl \
- snap-confine/tests/test_restrictions_working_args_prio \
- snap-confine/tests/test_restrictions_working_args_quotactl \
- snap-confine/tests/test_restrictions_working_args_socket \
- snap-confine/tests/test_restrictions_working_args_termios \
- snap-confine/tests/test_unrestricted \
- snap-confine/tests/test_unrestricted_missed \
- snap-confine/tests/test_whitelist
-
libexec_PROGRAMS += snap-confine/snap-confine
if HAVE_RST2MAN
dist_man_MANS += snap-confine/snap-confine.5
CLEANFILES += snap-confine/snap-confine.5
endif
EXTRA_DIST += snap-confine/snap-confine.rst
EXTRA_DIST += snap-confine/snap-confine.apparmor.in
-EXTRA_DIST += $(all_tests) snap-confine/tests/common.sh
-if SECCOMP
-if CONFINEMENT_TESTS
-TESTS += $(all_tests)
-endif
-endif
snap_confine_snap_confine_SOURCES = \
snap-confine/apparmor-support.c \
@@ -116,6 +116,19 @@ static void sc_quirk_create_writable_mimic(const char *mimic_dir,
debug("creating writable mimic directory %s based on %s", mimic_dir,
ref_dir);
sc_quirk_setup_tmpfs(mimic_dir);
+
+ // Now copy the ownership and permissions of the mimicked directory
+ struct stat stat_buf;
+ if (stat(ref_dir, &stat_buf) < 0) {
+ die("cannot stat %s", ref_dir);
+ }
+ if (chown(mimic_dir, stat_buf.st_uid, stat_buf.st_gid) < 0) {
+ die("cannot chown for %s", mimic_dir);
+ }
+ if (chmod(mimic_dir, stat_buf.st_mode) < 0) {
+ die("cannot chmod for %s", mimic_dir);
+ }
+
debug("bind-mounting all the files from the reference directory");
DIR *dirp __attribute__ ((cleanup(sc_cleanup_closedir))) = NULL;
dirp = opendir(ref_dir);
Oops, something went wrong.