Changeset 284451 in webkit
- Timestamp:
- Oct 19, 2021, 7:27:17 AM (3 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r284448 r284451 1 2021-10-19 Michael Catanzaro <mcatanzaro@gnome.org> 2 3 Update seccomp filters with latest changes from flatpak 4 https://bugs.webkit.org/show_bug.cgi?id=231479 5 6 Reviewed by Adrian Perez de Castro. 7 8 Additionally, let's fix a minor inconsistency in our error-handling code: all but one of 9 our codepaths carefully free and close resources, but the process is about to crash so 10 there's not really any reason to do so. The code is slightly simpler if we don't bother. 11 12 The seemingly-extraneous include order changes are required to placate the style checker. 13 14 * UIProcess/Launcher/glib/BubblewrapLauncher.cpp: 15 (WebKit::seccompStrerror): 16 (WebKit::setupSeccomp): 17 * UIProcess/Launcher/glib/Syscalls.h: Added. 18 1 19 2021-10-19 Martin Robinson <mrobinson@igalia.com> 2 20 -
trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp
r284156 r284451 26 26 #include <seccomp.h> 27 27 #include <sys/ioctl.h> 28 #include <sys/mman.h> 28 29 #include <unistd.h> 29 30 #include <wtf/FileSystem.h> … … 32 33 #include <wtf/glib/GUniquePtr.h> 33 34 35 #if !defined(MFD_ALLOW_SEALING) && HAVE(LINUX_MEMFD_H) 36 #include <linux/memfd.h> 37 #endif 38 39 #include "Syscalls.h" 40 34 41 #if PLATFORM(GTK) 35 42 #include "WaylandCompositor.h" … … 42 49 #endif 43 50 44 #include <sys/mman.h> 45 46 #ifndef MFD_ALLOW_SEALING 47 48 #if HAVE(LINUX_MEMFD_H) 49 50 #include <linux/memfd.h> 51 #if !defined(MFD_ALLOW_SEALING) && HAVE(LINUX_MEMFD_H) 51 52 52 53 // These defines were added in glibc 2.27, the same release that added memfd_create. … … 67 68 return syscall(__NR_memfd_create, name, flags); 68 69 } 69 #endif // #if HAVE(LINUX_MEMFD_H) 70 71 #endif // #ifndef MFD_ALLOW_SEALING 70 #endif // #if !defined(MFD_ALLOW_SEALING) && HAVE(LINUX_MEMFD_H) 72 71 73 72 namespace WebKit { … … 623 622 })); 624 623 } 624 } 625 626 // Translate a libseccomp error code into an error message. libseccomp 627 // mostly returns negative errno values such as -ENOMEM, but some 628 // standard errno values are used for non-standard purposes where their 629 // strerror() would be misleading. 630 static const char* seccompStrerror(int negativeErrno) 631 { 632 RELEASE_ASSERT_WITH_MESSAGE(negativeErrno < 0, "Non-negative error value from libseccomp?"); 633 RELEASE_ASSERT_WITH_MESSAGE(negativeErrno > INT_MIN, "Out of range error value from libseccomp?"); 634 635 switch (negativeErrno) { 636 case -EDOM: 637 return "Architecture-specific failure"; 638 case -EFAULT: 639 return "Internal libseccomp failure (unknown syscall?)"; 640 case -ECANCELED: 641 return "System failure beyond the control of libseccomp"; 642 } 643 644 // e.g. -ENOMEM: the result of strerror() is good enough 645 return g_strerror(-negativeErrno); 625 646 } 626 647 … … 652 673 // https://git.gnome.org/browse/linux-user-chroot 653 674 // in src/setup-seccomp.c 675 // 676 // Other useful resources: 677 // https://github.com/systemd/systemd/blob/HEAD/src/shared/seccomp-util.c 678 // https://github.com/moby/moby/blob/HEAD/profiles/seccomp/default.json 654 679 655 680 #if defined(__s390__) || defined(__s390x__) || defined(__CRIS__) … … 665 690 struct { 666 691 int scall; 692 int errnum; 667 693 struct scmp_arg_cmp* arg; 668 694 } syscallBlockList[] = { 669 695 // Block dmesg 670 { SCMP_SYS(syslog), nullptr },696 { SCMP_SYS(syslog), EPERM, nullptr }, 671 697 // Useless old syscall. 672 { SCMP_SYS(uselib), nullptr },698 { SCMP_SYS(uselib), EPERM, nullptr }, 673 699 // Don't allow disabling accounting. 674 { SCMP_SYS(acct), nullptr },700 { SCMP_SYS(acct), EPERM, nullptr }, 675 701 // 16-bit code is unnecessary in the sandbox, and modify_ldt is a 676 702 // historic source of interesting information leaks. 677 { SCMP_SYS(modify_ldt), nullptr },703 { SCMP_SYS(modify_ldt), EPERM, nullptr }, 678 704 // Don't allow reading current quota use. 679 { SCMP_SYS(quotactl), nullptr },705 { SCMP_SYS(quotactl), EPERM, nullptr }, 680 706 681 707 // Don't allow access to the kernel keyring. 682 { SCMP_SYS(add_key), nullptr },683 { SCMP_SYS(keyctl), nullptr },684 { SCMP_SYS(request_key), nullptr },708 { SCMP_SYS(add_key), EPERM, nullptr }, 709 { SCMP_SYS(keyctl), EPERM, nullptr }, 710 { SCMP_SYS(request_key), EPERM, nullptr }, 685 711 686 712 // Scary VM/NUMA ops 687 { SCMP_SYS(move_pages), nullptr },688 { SCMP_SYS(mbind), nullptr },689 { SCMP_SYS(get_mempolicy), nullptr },690 { SCMP_SYS(set_mempolicy), nullptr },691 { SCMP_SYS(migrate_pages), nullptr },713 { SCMP_SYS(move_pages), EPERM, nullptr }, 714 { SCMP_SYS(mbind), EPERM, nullptr }, 715 { SCMP_SYS(get_mempolicy), EPERM, nullptr }, 716 { SCMP_SYS(set_mempolicy), EPERM, nullptr }, 717 { SCMP_SYS(migrate_pages), EPERM, nullptr }, 692 718 693 719 // Don't allow subnamespace setups: 694 { SCMP_SYS(unshare), nullptr }, 695 { SCMP_SYS(mount), nullptr }, 696 { SCMP_SYS(pivot_root), nullptr }, 697 { SCMP_SYS(clone), &cloneArg }, 720 { SCMP_SYS(unshare), EPERM, nullptr }, 721 { SCMP_SYS(setns), EPERM, nullptr }, 722 { SCMP_SYS(mount), EPERM, nullptr }, 723 { SCMP_SYS(umount), EPERM, nullptr }, 724 { SCMP_SYS(umount2), EPERM, nullptr }, 725 { SCMP_SYS(pivot_root), EPERM, nullptr }, 726 { SCMP_SYS(chroot), EPERM, nullptr }, 727 { SCMP_SYS(clone), EPERM, &cloneArg }, 698 728 699 729 // Don't allow faking input to the controlling tty (CVE-2017-5226) 700 { SCMP_SYS(ioctl), &ttyArg }, 730 { SCMP_SYS(ioctl), EPERM, &ttyArg }, 731 732 // seccomp can't look into clone3()'s struct clone_args to check whether 733 // the flags are OK, so we have no choice but to block clone3(). 734 // Return ENOSYS so user-space will fall back to clone(). 735 // (GHSA-67h7-w3jq-vh4q; see also https://github.com/moby/moby/commit/9f6b562d) 736 { SCMP_SYS(clone3), ENOSYS, nullptr }, 737 738 // New mount manipulation APIs can also change our VFS. There's no 739 // legitimate reason to do these in the sandbox, so block all of them 740 // rather than thinking about which ones might be dangerous. 741 // (GHSA-67h7-w3jq-vh4q) 742 { SCMP_SYS(open_tree), ENOSYS, nullptr }, 743 { SCMP_SYS(move_mount), ENOSYS, nullptr }, 744 { SCMP_SYS(fsopen), ENOSYS, nullptr }, 745 { SCMP_SYS(fsconfig), ENOSYS, nullptr }, 746 { SCMP_SYS(fsmount), ENOSYS, nullptr }, 747 { SCMP_SYS(fspick), ENOSYS, nullptr }, 748 { SCMP_SYS(mount_setattr), ENOSYS, nullptr }, 701 749 702 750 // Profiling operations; we expect these to be done by tools from outside 703 751 // the sandbox. In particular perf has been the source of many CVEs. 704 { SCMP_SYS(perf_event_open), nullptr },752 { SCMP_SYS(perf_event_open), EPERM, nullptr }, 705 753 // Don't allow you to switch to bsd emulation or whatnot. 706 { SCMP_SYS(personality), nullptr },707 { SCMP_SYS(ptrace), nullptr }754 { SCMP_SYS(personality), EPERM, nullptr }, 755 { SCMP_SYS(ptrace), EPERM, nullptr } 708 756 }; 709 757 … … 713 761 714 762 for (auto& rule : syscallBlockList) { 715 int scall = rule.scall;716 763 int r; 717 764 if (rule.arg) 718 r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO( EPERM),scall, 1, *rule.arg);765 r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(rule.errnum), rule.scall, 1, *rule.arg); 719 766 else 720 r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(EPERM), scall, 0); 721 if (r == -EFAULT) { 722 seccomp_release(seccomp); 723 g_error("Failed to add seccomp rule"); 724 } 767 r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(rule.errnum), rule.scall, 0); 768 // EFAULT means "internal libseccomp error", but in practice we get 769 // this for syscall numbers added via Syscalls.h (flatpak-syscalls-private.h) 770 // when trying to filter them on a non-native architecture, because 771 // libseccomp cannot map the syscall number to a name and back to a 772 // number for the non-native architecture. 773 if (r == -EFAULT) 774 g_info("Unable to block syscall %d: syscall not known to libseccomp?", rule.scall); 775 else if (r < 0) 776 g_error("Failed to block syscall %d: %s", rule.scall, seccompStrerror(r)); 725 777 } 726 778 727 779 int tmpfd = memfd_create("seccomp-bpf", 0); 728 if (tmpfd == -1) { 729 seccomp_release(seccomp); 780 if (tmpfd == -1) 730 781 g_error("Failed to create memfd: %s", g_strerror(errno)); 731 } 732 733 if (seccomp_export_bpf(seccomp, tmpfd)) { 734 seccomp_release(seccomp); 735 close(tmpfd); 736 g_error("Failed to export seccomp bpf"); 737 } 782 783 if (int r = seccomp_export_bpf(seccomp, tmpfd)) 784 g_error("Failed to export seccomp bpf: %s", seccompStrerror(r)); 738 785 739 786 if (lseek(tmpfd, 0, SEEK_SET) < 0)
Note:
See TracChangeset
for help on using the changeset viewer.