| Summary: | Review Request: clevis - Automated decryption framework | ||
|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | Nathaniel McCallum <npmccallum> |
| Component: | Package Review | Assignee: | Zbigniew Jędrzejewski-Szmek <zbyszek> |
| Status: | CLOSED CURRENTRELEASE | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | rawhide | CC: | package-review, zbyszek |
| Target Milestone: | --- | Flags: | zbyszek:
fedora-review+
|
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2019-09-17 15:48:49 UTC | Type: | --- |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
|
Description
Nathaniel McCallum
2016-11-14 21:42:46 UTC
%description
Clevis is a framework for automated decryption.
→ great, but please provide some detail here. Automated decryption of what? Is this another jack the ripper clone?
make %{?_smp_mflags} V=1
make %{?_smp_mflags} check
→ %make_build V=1
%make_build check
rm -rf $RPM_BUILD_ROOT
→ please no [https://fedoraproject.org/wiki/Packaging:Guidelines#Tags_and_Sections]
Fedora review says:
Issues:
=======
- Package installs a %{name}.desktop using desktop-file-install or desktop-
file-validate if there is such a file.
- Package uses hardened build flags if required to.
Note: suid files: clevis-luks-udisks2 and not %global _hardened_build
See:
http://fedoraproject.org/wiki/Packaging:Guidelines?rd=Packaging/Guidelines#Compiler_flags
rpmlint:
clevis-udisks2.x86_64: W: non-conffile-in-etc /etc/xdg/autostart/clevis-luks-udisks2.desktop
Spec: http://copr-dist-git.fedorainfracloud.org/cgit/npmccallum/clevis/clevis.git/plain/clevis.spec SRPM: https://copr-be.cloud.fedoraproject.org/results/npmccallum/clevis/fedora-rawhide-x86_64/00477086-clevis/clevis-1-1.fc26.src.rpm I'm not precisely sure what you want me to do with the .desktop file. This is not a general purpose application but a user session daemon. I should have pasted a link to the guidelines: https://fedoraproject.org/wiki/Packaging:Guidelines#Desktop_files You must either use desktop-file-install of desktop-file-validate. Also, I'm still stumped a bit by the %description... Imagine that you're a user who looks and 'dnf info' output: Clevis is a framework for automated decryption. It allows you to encrypt data using sophisticated unlocking policies which enable decryption to occur automatically. It doesn't say *what* is being decrypted. It also gives no hint what those "sophisticated unlocking policies" might be. A package should not be a black box... Please make this a bit easier to understand. (In reply to Zbigniew Jędrzejewski-Szmek from comment #5) > Also, I'm still stumped a bit by the %description... Imagine that you're a > user who looks and 'dnf info' output: > Clevis is a framework for automated decryption. It allows you to encrypt > data using sophisticated unlocking policies which enable decryption to > occur automatically. > > It doesn't say *what* is being decrypted. It also gives no hint what those > "sophisticated unlocking policies" might be. A package should not be a black > box... Please make this a bit easier to understand. Anything is being encrypted/decrypted. You're asking for more specificity in the description of a subpackage that is the enabling technology for other subpackages. The clevis package provides basic encryption/decryption policy support. Users can use this directly. But most commonly, it will be used as a building block for other packages. For example, you can install clevis-dracut (which depends on clevis and clevis-luks) to perform automated root volume decryption. Simply put, the clevis package is the core functionality and is intentionally vague. (In reply to Zbigniew Jędrzejewski-Szmek from comment #4) > I should have pasted a link to the guidelines: > https://fedoraproject.org/wiki/Packaging:Guidelines#Desktop_files > You must either use desktop-file-install of desktop-file-validate. As I stated above, this is not a usual .desktop file. It is not an application, but a user session daemon. I do not believe these requirements apply in this situation. There's nothing in the guidelines that says that desktop file validation should not be performed in this case. This file is installed into the same directory as many other .desktop files, so it'll be loaded by various tools, so I think it should be validated. desktop-file-validate prints no warnings for clevis-luks-udisks2.desktop, so I don't see any reason to not validate it according to the guidelines.
> The clevis package provides basic encryption/decryption policy support. Users can use this directly. But most commonly, it will be used as a building block for other packages, [for example to automatically decrypt LUKS volumes using a passphrase received over the network, including the root volume, see clevis-lukus and clevis-dracut packages].
OK, great, I think that if this is appended to current %description, it gives a reasonable idea what this package does.
I saw the that one of the files is suid, so I decided to have a look at the code... Two issues pop out: 1. memset(key, 0, strlen(key)); is going to be optimized away. If you are doing that to decrease chances of the key leaking out, this will not work. See https://github.com/systemd/systemd/blob/493fd52f1ada36bfe63301d4bb50f7fd2b38c670/src/basic/string-\ util.c#L834 for a way (cribbed from openssl), for a way around that. 2. I don't think using the relative path like as in snprintf(path, pathl, "%s/../bin/clevis-decrypt", dirname(tmp)) is safe. If the user is able to call the binary under a different path where they control the ../bin prefix, it will allow them to call arbitrary binary as root. I don't think it's directly exploitable in the default configuration, but it's not hard to contrive some scenario where it would be: - fs.protected_hardlinks=0 This is the kernel default, which is overridden by systemd-sysctl after boot. If systemd-sysctl is prevented from running, for example by broken configuration, clevis-luks-udisks2 becomes immediately exploitable a la CVE-2009-1894. - some scenario where the fs containing the suid binary is mounted below a user writable directory (for example the administrator temporarily mounts the fs under /var/tmp for backup purposes). - some manipulation using mount namespaces. I don't see an exploit, but relying on the binary always being visible only under the correct path seems very brittle. It'd seem much better to substitute the real absolute path during build. (In reply to Zbigniew Jędrzejewski-Szmek from comment #9) > I saw the that one of the files is suid, so I decided to have a look > at the code... > > Two issues pop out: > 1. memset(key, 0, strlen(key)); is going to be optimized away. If you > are doing that to decrease chances of the key leaking out, this will > not work. See > https://github.com/systemd/systemd/blob/ > 493fd52f1ada36bfe63301d4bb50f7fd2b38c670/src/basic/string-\ > util.c#L834 > for a way (cribbed from openssl), for a way around that. > > 2. I don't think using the relative path like as in > snprintf(path, pathl, "%s/../bin/clevis-decrypt", dirname(tmp)) > is safe. If the user is able to call the binary under a different > path where they control the ../bin prefix, it will allow them to call > arbitrary binary as root. The clevis-decrypt binary is not executed as root. We drop privileges much earlier than that. See: https://github.com/latchset/clevis/blob/master/clevis-luks-udisks2.c#L384 However, your concern is still valid because we pass information obtained as root to that process. So it still represents a security concern. I'd love to chat with you on IRC to discuss some of my concerns with my own code if you have time. > I don't think it's directly exploitable in > the default configuration, but it's not hard to contrive some scenario > where it would be: > > - fs.protected_hardlinks=0 > This is the kernel default, which is overridden by systemd-sysctl > after boot. If systemd-sysctl is prevented from running, for > example by broken configuration, clevis-luks-udisks2 becomes > immediately exploitable a la CVE-2009-1894. > > - some scenario where the fs containing the suid binary is mounted > below a user writable directory (for example the administrator > temporarily mounts the fs under /var/tmp for backup purposes). > > - some manipulation using mount namespaces. > > I don't see an exploit, but relying on the binary always being visible > only under the correct path seems very brittle. It'd seem much better > to substitute the real absolute path during build. Yeah, I agree. The main reason I haven't done this is because it makes in-tree unit testing (after build, before install) more difficult. Suggestions welcome. (In reply to Nathaniel McCallum from comment #10) > The clevis-decrypt binary is not executed as root. We drop privileges much > earlier than that. See: > https://github.com/latchset/clevis/blob/master/clevis-luks-udisks2.c#L384 > > However, your concern is still valid because we pass information obtained as > root to that process. So it still represents a security concern. I'd love to > chat with you on IRC to discuss some of my concerns with my own code if you > have time. Yeah, I think it's a concern, also because the program uses the information received *from* the other binary. Please ping me on IRC when you're around. I saw your ping yesterday after I returned home, but you were already gone... > Yeah, I agree. The main reason I haven't done this is because it makes > in-tree unit testing (after build, before install) more difficult. > Suggestions welcome. I'd add a C define with the full path (using AC_DEFINE or similar), and allow overriding it using a shell variable in non-suid process. const char *p = secure_getenv("CLEVIS_HELPER_PATH"); if (p) return p; else return HELPER_PATH; I've fixed most issues upstream. Unfortunately, I also discovered a GCC bug which effects clevis. I've added a reference to that bug here. Once it is resolved, I'll get a new SRPM ready for testing. SPEC: http://copr-dist-git.fedorainfracloud.org/cgit/npmccallum/clevis/clevis.git/plain/clevis.spec SRPM: https://copr-be.cloud.fedoraproject.org/results/npmccallum/clevis/fedora-rawhide-x86_64/00478613-clevis/clevis-2-1.fc26.src.rpm This includes the new upstream release (v2) which works around the GCC code generation issue. It also runs "clevis decrypt" as root, so the key is protected (though running network code as root is somewhat less than ideal; this can be addressed in future releases). Package Review
==============
Legend:
[x] = Pass, [!] = Fail, [-] = Not applicable, [?] = Not evaluated
===== MUST items =====
C/C++:
[x]: Package does not contain kernel modules.
[x]: Package contains no static executables.
[x]: Header files in -devel subpackage, if present.
[x]: Package does not contain any libtool archives (.la)
[x]: Rpath absent or only used for internal libs.
Generic:
[x]: Package is licensed with an open-source compatible license and meets
other legal requirements as defined in the legal section of Packaging
Guidelines.
GPLv3+
[x]: License field in the package spec file matches the actual license.
Note: Checking patched sources after %prep for licenses. Licenses
found: "MIT/X11 (BSD like)", "GPL (v3 or later)", "Unknown or
generated". 9 files have unknown license. Detailed output of
licensecheck in /var/tmp/1394962-clevis/licensecheck.txt
[x]: License file installed when any subpackage combination is installed.
Yes, all packages transitively depend on clevis.rpm which has the license.
[!]: Package requires other packages for directories it uses.
Note: No known owner of /usr/lib/dracut/modules.d/60clevis
[!]: Package must own all directories that it creates.
Note: Directories without known owners:
/usr/lib/dracut/modules.d/60clevis
Please add %dir /usr/lib/dracut/modules.d/60clevis to %files.
[x]: %build honors applicable compiler flags or justifies otherwise.
[x]: Package contains no bundled libraries without FPC exception.
[x]: Changelog in prescribed format.
[x]: Sources contain only permissible code or content.
[-]: Development files must be in a -devel package
[x]: Package uses nothing in %doc for runtime.
[x]: Package consistently uses macros (instead of hard-coded directory
names).
[x]: Package is named according to the Package Naming Guidelines.
[x]: Package does not generate any conflict.
[x]: Package obeys FHS, except libexecdir and /usr/target.
[-]: If the package is a rename of another package, proper Obsoletes and
Provides are present.
[x]: Requires correct, justified where necessary.
[x]: Spec file is legible and written in American English.
[x]: Useful -debuginfo package or justification otherwise.
[x]: Package is not known to require an ExcludeArch tag.
[x]: Package complies to the Packaging Guidelines
[x]: Package successfully compiles and builds into binary rpms on at least
one supported primary architecture.
[x]: Package installs properly.
[x]: Rpmlint is run on all rpms the build produces.
Note: There are rpmlint messages (see attachment).
[x]: If (and only if) the source package includes the text of the
license(s) in its own file, then that file, containing the text of the
license(s) for the package is included in %license.
[x]: Package does not own files or directories owned by other packages.
[x]: All build dependencies are listed in BuildRequires, except for any
that are listed in the exceptions section of Packaging Guidelines.
[x]: Package uses either %{buildroot} or $RPM_BUILD_ROOT
[x]: Package does not run rm -rf %{buildroot} (or $RPM_BUILD_ROOT) at the
beginning of %install.
[x]: Package uses hardened build flags if required to.
Note: suid files: clevis-luks-udisks2
[x]: Macros in Summary, %description expandable at SRPM build time.
[x]: Package contains desktop file if it is a GUI application.
[x]: Package installs a %{name}.desktop using desktop-file-install or
desktop-file-validate if there is such a file.
[x]: Dist tag is present.
[x]: Package does not contain duplicates in %files.
[x]: Package use %makeinstall only when make install DESTDIR=... doesn't
work.
[x]: Package is named using only allowed ASCII characters.
[x]: Package does not use a name that already exists.
[x]: Package is not relocatable.
[x]: Sources used to build the package match the upstream source, as
provided in the spec URL.
[x]: Spec file name must match the spec package %{name}, in the format
%{name}.spec.
[x]: Package contains systemd file(s) if in need.
[x]: File names are valid UTF-8.
[x]: Large documentation must go in a -doc subpackage. Large could be size
(~1MB) or number of files.
Note: Documentation size is 0 bytes in 0 files.
[x]: Packages must not store files under /srv, /opt or /usr/local
===== SHOULD items =====
Generic:
[-]: If the source package does not include license text(s) as a separate
file from upstream, the packager SHOULD query upstream to include it.
[x]: Final provides and requires are sane (see attachments).
[x]: Fully versioned dependency in subpackages if applicable.
Note: No Requires: %{name}%{?_isa} = %{version}-%{release} in clevis-
dracut , clevis-udisks2 , clevis-debuginfo
clevis-dracut -> clevis-luks -> clevis
clevis-udisks2 -> clevis-luks -> clevis
[-]: Package functions as described.
Not checked. I don't have a server set up that clevis could talk to.
[x]: Latest version is packaged.
[x]: Package does not include license text files separate from upstream.
[-]: Description and summary sections in the package spec file contains
translations for supported Non-English languages, if available.
[x]: Package should compile and build into binary rpms on all supported
architectures.
[x]: %check is present and all tests pass.
[x]: Packages should try to preserve timestamps of original installed
files.
[x]: Reviewer should test that the package builds in mock.
[x]: Buildroot is not present
[x]: Package has no %clean section with rm -rf %{buildroot} (or
$RPM_BUILD_ROOT)
[x]: No file requires outside of /etc, /bin, /sbin, /usr/bin, /usr/sbin.
[x]: Packager, Vendor, PreReq, Copyright tags should not be in spec file
[x]: Sources can be downloaded from URI in Source: tag
[x]: SourceX is a working URL.
[x]: Spec use %global instead of %define unless justified.
===== EXTRA items =====
Generic:
[x]: Rpmlint is run on debuginfo package(s).
Note: No rpmlint messages.
[x]: Rpmlint is run on all installed packages.
Note: There are rpmlint messages (see attachment).
[x]: Large data in /usr/share should live in a noarch subpackage if package
is arched.
[x]: Spec file according to URL is the same as in SRPM.
Rpmlint
-------
Checking: clevis-2-1.fc26.x86_64.rpm
clevis-luks-2-1.fc26.x86_64.rpm
clevis-dracut-2-1.fc26.x86_64.rpm
clevis-udisks2-2-1.fc26.x86_64.rpm
clevis-debuginfo-2-1.fc26.x86_64.rpm
clevis-2-1.fc26.src.rpm
clevis.x86_64: W: spelling-error %description -l en_US luks -> looks, lurks, lucks
clevis.x86_64: W: spelling-error %description -l en_US dracut -> Dracula
clevis.x86_64: W: no-documentation
clevis-luks.x86_64: W: spelling-error %description -l en_US unlocker -> unlocked, unlock er, unlock-er
clevis-luks.x86_64: W: spelling-error %description -l en_US dracut -> Dracula
clevis-luks.x86_64: W: no-documentation
clevis-dracut.x86_64: W: only-non-binary-in-usr-lib
clevis-dracut.x86_64: W: no-documentation
clevis-udisks2.x86_64: W: spelling-error %description -l en_US storaged -> storage, storage d, stored
clevis-udisks2.x86_64: W: no-documentation
clevis.src: W: spelling-error %description -l en_US luks -> looks, lurks, lucks
All OK.
clevis.x86_64: W: no-manual-page-for-binary clevis
More docs would be nice ;)
clevis-udisks2.x86_64: E: setuid-binary /usr/libexec/clevis-luks-udisks2 root 4755
clevis-udisks2.x86_64: E: non-standard-executable-perm /usr/libexec/clevis-luks-udisks2 4755
OK.
clevis-udisks2.x86_64: W: non-conffile-in-etc /etc/xdg/autostart/clevis-luks-udisks2.desktop
Despite the location, this is not a config file. Not using %config
matches what other packages which install files there are doing.
Somebody should move the whole lot to /usr.
clevis.src:90: E: hardcoded-library-path in %{_prefix}/lib/dracut/modules.d/60%{name}/module-setup.sh
clevis.src:91: E: hardcoded-library-path in %{_prefix}/lib/dracut/modules.d/60%{name}/%{name}-hook.sh
That's OK too, I think.
6 packages and 0 specfiles checked; 4 errors, 13 warnings.
Rpmlint (debuginfo)
-------------------
Checking: clevis-debuginfo-2-1.fc26.x86_64.rpm
1 packages and 0 specfiles checked; 0 errors, 0 warnings.
Requires
--------
clevis-debuginfo (rpmlib, GLIBC filtered):
clevis-udisks2 (rpmlib, GLIBC filtered):
clevis-luks(x86-64)
libc.so.6()(64bit)
libcryptsetup.so.4()(64bit)
libcryptsetup.so.4(CRYPTSETUP_1.0)(64bit)
libgio-2.0.so.0()(64bit)
libglib-2.0.so.0()(64bit)
libgobject-2.0.so.0()(64bit)
libhttp_parser.so.2()(64bit)
libluksmeta.so.0()(64bit)
libpthread.so.0()(64bit)
libudisks2.so.0()(64bit)
rtld(GNU_HASH)
clevis-luks (rpmlib, GLIBC filtered):
/bin/bash
clevis(x86-64)
cryptsetup
luksmeta
clevis (rpmlib, GLIBC filtered):
/bin/bash
coreutils
libc.so.6()(64bit)
libcrypto.so.1.1()(64bit)
libcrypto.so.1.1(OPENSSL_1_1_0)(64bit)
libgcc_s.so.1()(64bit)
libgcc_s.so.1(GCC_3.0)(64bit)
libgcc_s.so.1(GCC_3.3.1)(64bit)
libhttp_parser.so.2()(64bit)
libjansson.so.4()(64bit)
libjose-openssl.so.0()(64bit)
libjose-zlib.so.0()(64bit)
libjose.so.0()(64bit)
libpthread.so.0()(64bit)
rtld(GNU_HASH)
clevis-dracut (rpmlib, GLIBC filtered):
/bin/bash
clevis-luks(x86-64)
dracut-network
nc
Provides
--------
clevis-debuginfo:
clevis-debuginfo
clevis-debuginfo(x86-64)
clevis-udisks2:
clevis-udisks2
clevis-udisks2(x86-64)
clevis-luks:
clevis-luks
clevis-luks(x86-64)
clevis:
clevis
clevis(x86-64)
clevis-dracut:
clevis-dracut
clevis-dracut(x86-64)
Package is APPROVED. Please fix the directory ownership issue when uploading.
Package request has been approved: https://admin.fedoraproject.org/pkgdb/package/rpms/clevis |