Spec URL: http://copr-dist-git.fedorainfracloud.org/cgit/npmccallum/clevis/clevis.git/plain/clevis.spec SRPM URL: https://copr-be.cloud.fedoraproject.org/results/npmccallum/clevis/fedora-rawhide-x86_64/00476674-clevis/clevis-1-1.fc26.src.rpm Description: Automated decryption framework Fedora Account System Username:
%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