(Add libntirpc) |
(Add deutsch-c++) |
||
Line 159: | Line 159: | ||
Many instances of md5.c<ref>There are multiple md5 implementations. The ones that have an actual library (libnss, libgcrypt, openssl, libmd, etc) are not covered by this exception. The ones that are copied from other applications are.</ref> | Many instances of md5.c<ref>There are multiple md5 implementations. The ones that have an actual library (libnss, libgcrypt, openssl, libmd, etc) are not covered by this exception. The ones that are copied from other applications are.</ref> | ||
</td><td> | </td><td> | ||
bundled(md5-$IMPLEMENTATION)<ref>Change $IMPLEMENTATION depending on which implementation of md5 is being bundled. The ones known so far are Peter Deutsch's version: [[Media:Deutsch-md5.c| bundled(md5-deutsch)]], Colin Plumb's [[Media:Plumb-md5.c| bundled(md5-plumb)]], Alexander Peslyak's [http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 bundled(md5-peslyak)], Ulrich Drepper's [http://git.jankratochvil.net/?p=gdb.git;a=blob;f=libiberty/md5.c;h=0db8fc8936f30c76e020a96736182d481c147f20;hb=master bundled(md5-gcc)] and John Polstra's [[Media:Polstra-md5.c | bundled(md5-polstra)]].</ref> | bundled(md5-$IMPLEMENTATION)<ref>Change $IMPLEMENTATION depending on which implementation of md5 is being bundled. The ones known so far are Peter Deutsch's version: [[Media:Deutsch-md5.c| bundled(md5-deutsch)]], a C++ port of Peter Deutsch's version: [http://sourceforge.net/p/sidplay-residfp/code/HEAD/tree/branches/libsidplayfp-1.1/utils/MD5/| bundled(md5-deutsch-c++)], Colin Plumb's [[Media:Plumb-md5.c| bundled(md5-plumb)]], Alexander Peslyak's [http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 bundled(md5-peslyak)], Ulrich Drepper's [http://git.jankratochvil.net/?p=gdb.git;a=blob;f=libiberty/md5.c;h=0db8fc8936f30c76e020a96736182d481c147f20;hb=master bundled(md5-gcc)] and John Polstra's [[Media:Polstra-md5.c | bundled(md5-polstra)]].</ref> | ||
</td><td> | </td><td> | ||
copylib | copylib |
Revision as of 18:15, 5 December 2013
Why no Bundled Libraries
Although you can request an exception from FPC there are many reasons not to grant one. These are the reasons that it's painful for us to have bundled libraries in the distribution. An exception should only be granted if the value of bundling exceeds these costs.
Security
- When a security flaw is discovered in a library and bundling is not allowed, The library can be fixed in a single package, that package rebuilt, and when users download it, all the applications that use it are immediately protected. When bundling is allowed, the distribution has to find all the packages that the library occurs in by auditing source code or running a special tool over all elf files in all packages, then all of those packages have to be fixed, all of those packages have to be built, and users have to download and update each of the ones that they are using on their system before they are protected. There is much more work involved when bundled libraries are involved.
- With security issues, people want to remove as much lag as they can between announcement of a problem and the fix being available for users. When libraries are unbundled, tools like vendor-sec can be used to alert distributions of problems that need patching in their packages before the announcement is made and then they can fix them with zero days of vulnerability. If bundling of libraries occurs, then the problem becomes how to get fixes out to all affected packages. If the distribution patches those packages, they must be careful to not leak the fact that there is a security vulnerability before they are allowed (which means they need to be careful who they share the information and what information they share with others). OTOH, if they do not patch the packages bundling libraries, then those packages are not protected on zero day, but only afterwards.
- When a security flaw appears, the program has to either update to a non-affected version of the library or backport a fix. This can be problematic when the code of the library has undergone many API and code changes since the version that is being bundled and the security fixing patch is very widespread. Many conflicts can arise that need time to fix when trying to backport the fixes but porting the application code to the new API version can also take a lot of time.
- We cannot implicitly trust an upstream application to be on top of security issues that are released in the packages that they care about. What happens if you are not following boost development and don't know that a security release has been made? What happens if the developer that is responsible for watching boost development goes on vacation or quits your project? What happens if your application ceases active development? What happens if boost stops active development and security fixes start originating with distro patches?
Forking
Forking is occurring. Once an application starts bundling libraries, it's easy for the project to include local patches to the library to add features that upstream doesn't have or fix bugs that upstream hasn't addressed. This has several negative effects.
- When a security issue appears, it becomes harder to fix the application bundling the library. If you attempt to upgrade to a newer version, you have to make sure your important local modifications get ported to the new version. If you attempt to backport, you have to merge the upstream fix to your own code-base which may have conflicts with the local modifications.
- When working with the library that comes from upstream, there is a community of people who are interested in that library to fall back on for help. When working on your own private copy that community may not be interested in helping you work on your modified sources since they don't have control or knowledge of what your modified sources do.
- Forking dilutes one of the strengths of open-source development. Instead of a project getting stronger with more people supplying patches to help drive the project and build a bigger community, the community of people interested in it are splintering, developing more and more divergent code-bases, solving the same problem over and over in different ways in different private copies of the library. Instead of everyone benefiting, everyone has to pay.
Bugfixes
Bugfixes are usually of lesser importance from security issues but share the same issues of hanging onto lingering problems that have been fixed in the main package.
Old Code
- Old versions of code linger on. If the application can bundle its own version of a library, the incentive to port to newer versions of the library are reduced. This exacerbates the problems of security and bugfix issues. Instead of progressively porting to newer versions of a library as time goes on, porting to newer versions becomes a chore that has to be performed at the same time as addressing a security flaw. This puts time pressure on the project when the work could have been spread out over a longer period if only the porting had been done all along.
Licensing
Although licensing issues can crop up in any project, projects which bundle code from different sources together are a special source of concern. They make auditing for license issues a larger project.
When a Bundled Library is Discovered Post-Review
Bundling of libraries is a serious problem. If a package that is in the distribution is discovered to have bundled libraries we need to fix it. First, open a bug report against the package. Then add the bug to the Duplicate libraries tracker. Once that's done, if help is needed fixing the bug ask on the mailing list.
Exceptions
Exceptions are granted on a case-by-case basis by FPC. You can look in the following section for help on making a case for why an exception should be granted. You should open up a ticket in the FPC's trac with information asked for below.
Standard questions
You must have answers to these standard questions before seeking an exception.
- Has the library behaviour been modified? If so, how has it been modified? If the library has been modified in ways that change the API or behaviour then there may be a case for copying. Note that fixing bugs is not grounds to copy. If the library has not been modified (ie: it can be used verbatim in the distro) there's little chance of an exception.
- Why haven't the changes been pushed to the upstream library? If no attempt has been made to push the changes upstream, we shouldn't be supporting people forking out of laziness.
- Have the changes been proposed to the Fedora package maintainer for the library? In some cases it may make sense for our package to take the changes despite upstream not taking them (for instance, if upstream for the library is dead).
- Could we make the forked version the canonical version within Fedora? For instance, if upstream for the library is dead, is the package we're working on that bundles willing to make their fork a library that others can link against?
- Are the changes useful to consumers other than the bundling application? If so why aren't we proposing that the library be released as a fork of the upstream library?
- Is upstream keeping the base library updated or are they continuously one or more versions behind the latest upstream release?
- What is the attitude of upstream towards bundling? (Are they eager to remove the bundled version? are they engaged with the upstream for the library? Do they have a history of bundling? Are they argumentative?)
- Overview of the security ramifications of bundling
- Does the maintainer of the Fedora package of the library being bundled have any comments about this?
- Is there a plan for unbundling the library at a later time? Include things like what features would need to be added to the upstream library, a timeline for when those features would be merged, how we're helping to meet those goals, etc.
- Please include any relevant documentation -- mailing list links, bug reports for upstream or the bundled library, etc.
Some reasons you might be granted an exception
This section lists some reasons that might convince FPC that you have a valid reason to be granted an exception. Exceptions are granted on a case by case basis and satisfying the rationale here is not a guarantee of an exception but it's a place to start building your case for why the package you work on is exceptional.
Kernel
If you're packaging the kernel and need to bundle a library you have a blanket exception. The kernel is allowed to bundle libraries as it cannot use user space libraries. Additionally, the kernel has a unique exemption from the requirement to note what code is being bundled with comments and Virtual Provides. This has several reasons:
- The code bundled by the kernel is stripped down to the bare minimum and sometimes modified in other ways so that it is significantly different from the upstream code.
- The kernel code is scrutinized for security issues at a level that often exceeds the upstreams it is bundling.
- Due to the modifications to the code that is bundled into the kernel, once the code is included it evolves separately from upstream.
- There are many people working on the kernel capable and concerned with coding fixes for security issues, within Fedora, Red Hat, and the community at large.
The kernel maintainers are free to add virtual provides if they think it would be helpful to track security issues in the code in question but this is left to their discretion.
Copylibs
The definition of a copylib is somewhat amorphous. At its basic level, the upstream for the library intends for you to copy the source code of the library into your program, modify it to suit your needs, and then release your software with continuous, forked modifications to that source. Just because you think you're dealing with a copylib does not guarantee that you will be granted an exception. In particular, the programming practice that is common in some java, mono, and scripting language circles of copying external libraries that are otherwise from a separate upstream into the program's source and distributing them together is not allowed. Programs which bundle libraries whose upstream is dead and make bugfixes to the bundled copy is not allowed. As much as possible we want to have a single copy of a library in the distribution which everyone links to.
Some of the criteria that FPC uses to evaluate the copylib case are:
- Does the upstream library make actual releases? If they do, then it is likely not a copylib.
- Does upstream define what they put together as a library or as reusable code snippets that are to be modified and incorporated as source in individual packages? If the latter, it's more likely that the library is a copylib under this definition.
Needing unreleased features
When an application needs unreleased features of a library and that library has committed to those features (usually, the changes are checked into the trunk branch of the upstream's revision control system) but the library has not yet made a release that has that code an exception may be granted to bundle that library until the Fedora packages contain the necessary extra features. Note that for this we would definitely want the standard questions regarding why the Fedora maintainer of the library feels we cannot include a backport of the feature/pre-release snapshot in our package, the timeline for the change to be merged and unbundling to occur to be answered so that we can make sure this is fixed should the package maintainer disappear or get busy with other things.
Modified beyond a certain extent
Modification of a library should not be the only reason given to justify a bundled copy as the two questions come up: why can't these changes go back to the upstream for the library? Why isn't this library forked and released in such a way that others can benefit from the changes as well? However, it can be one of the factors considered. To provide a solid foundation for a bundling exception you should be able to answer those two questions. An explanation that tells why the changes are only useful for the application that's bundling them, for instance.
- Example: recoll bundles unac but unac changed the API of unac and those changes were judged to only be of use to recoll and thus the bundling was allowed.
- Counter example: rsync bundles zlib. However, the modified zlib is useful to others as the modified zlib is necessary in order to implement the rsync protocol. In particular, the program zsync needs to have a similarly modified zlib in order to be of use.
Reverse Bundling
Reverse bundling when a portion of an upstream codebase has been forked into its own, separate library package. These are then packaged in a separate package for Fedora.
When done for purposes of adding a backwards compat API for use by other packages this is okay (For instance, taking a module out of a newer version of the python stdlib and packaging it as a separate python module for use on older versions of python). Be sure to keep the forked code up to date with regard to the package it comes from. Apply to the FPC for a virtual Provide to use for tracking purposes.
When done for other purposes (for instance, splitting a useful utility function from a large monolithic upstream into its own package ) this may be a factor in deciding if the bundling is allowed but it may not be sufficient on its own.
Requirement if you bundle
- You must note that the library has been granted an exception in a spec file comment with a link to the FPC ticket where the exception was granted.
- If you bundle a library, you are required to add a virtual provide to your spec file to note that you are bundling. This allows us to search for packages that may be affected by bugs or security issues in older versions of the library. The notation should look like this:
Provides: bundled(zlib) = 1.1.14
bundled()
denotes that this is a bundled library virtual provide rather than something that other packages would want to depend on. Inside the paranthesis, the binary package that provides the library is listed. (For instance, zlib
, bind-libs
, NetworkManager-glib
, libpng
). The version notes which version of the library was bundled. If there's been a lot of incomplete backporting of changes from newer versions of the library, it can be hard to establish what version to use here. A very general rule of thumb is to use the oldest version that seems reasonable as the reason we're doing this is to tell when a library contains issues that have been fixed in newer upstream versions.
Packages granted exceptions
Library |
Provide |
Reason |
---|---|---|
Any binc |
bundled(binc) |
copylib |
Any egglib |
bundled(egglib) |
copylib - use this link in spec: https://fedorahosted.org/fpc/ticket/174 |
Any gnulib |
bundled(gnulib) |
copylib - use this link in spec: https://fedorahosted.org/fpc/ticket/174 |
Any libiberty |
bundled(libiberty) |
copylib - use this link in spec: https://fedorahosted.org/fpc/ticket/174 |
Many instances of md5.c[1] |
bundled(md5-$IMPLEMENTATION)[2] |
copylib |
time-api's use of timex from openjdk8 |
bundled(openjdk8-javax-time) |
Reverse bundling providing a backwards compat API |
unac's recoll |
bundled(recoll) |
this recoll has changes that are not applicable to other applications. |
TexStudio's qcodeedit |
bundled(qcodeedit) |
TexStudio contains a forked copy of qcodeedit 2, which is at least two years dead. Since TexStudio is the only user, there is no benefit to a separated library, and permission to bundle has been granted. |
binutils libraries (libbfd, libcpu, libopcodes, libdecnumber) |
bundled(binutils)[3] |
If the package in question shares the same upstream as binutils (sourceware.org), they may bundle these libraries. This is because the libraries are developed by the application authors as common functionality shared between several applications. Being developers of both, they'll be intimately aware of both issues that arise in the libraries and know how to port to newer versions of the library as needed. Note that, at the moment, all of these applications and libraries come from sourceware.org but not all of them are used in binutils. The name was chosen as it seemed to be the more permanent and recognizable name. |
Spring RTS's lua implementation |
bundled(lua) |
Spring RTS includes a forked and bundled copy of Lua which has Spring RTS specific patches applied, must link to streflop, and is configured differently from stock Lua (most importantly it needs lua_Number to be a float and not a double). Lua is particularly important because parts of the game code may be written in it, which must yield exactly identical results (also floating point operations!) on all platforms. |
Any okjson |
bundled(okjson) |
copylib[4] |
libreplace in samba libraries |
bundled(libreplace) |
If the package in question shares the same upstream as samba, they may bundle the libreplace library. This is because the libreplace library is developed by the application authors as common functionality shared between several applications. Being developers of both, they'll be intimately aware of both issues that arise in the libraries and know how to port to newer versions of the library as needed. |
boost in passenger |
bundled(boost) |
A bundling exception for boost within mod_passenger was granted, due to the intrusive nature of the forked changes, the efforts of the maintainer to merge as many of them as possible into the upstream boost source tree, and the visible efforts of the upstream to keep the bundled copy of boost in sync with the current boost releases. This exception was contingent on a specific packager, wako666 being maintainer or comaintainer due to his efforts to redesign and merge the boost patches back to upstream boost. https://fedorahosted.org/fpc/ticket/160 |
pyPdf in calibre |
bundled(pyPdf) |
A bundling exception for calibre's forked copy of pyPdf was granted, due to the intrusive nature of the forked changes, the specificity of the changes to calibre, and the fact that pyPdf seems to be abandoned upstream. https://fedorahosted.org/fpc/ticket/167 |
libtidy in sigul |
bundled(libtidy) |
libtidy was allowed to bundle libtidy due to libtidy being dead upstream and the code being modified to handle epub instead of html. https://fedorahosted.org/fpc/ticket/219 |
objectweb-asm in byteman |
bundled(objectweb-asm) |
Due to the specific nature of how byteman works, a special kind of exception was granted for byteman to bundle objectweb-asm. See the ticket for details: https://fedorahosted.org/fpc/ticket/226 |
java_cup in byteman |
bundled(java_cup) |
Due to the specific nature of how byteman works, a special kind of exception was granted for byteman to bundle java_cup. See the ticket for details: https://fedorahosted.org/fpc/ticket/226 |
- ↑ There are multiple md5 implementations. The ones that have an actual library (libnss, libgcrypt, openssl, libmd, etc) are not covered by this exception. The ones that are copied from other applications are.
- ↑ Change $IMPLEMENTATION depending on which implementation of md5 is being bundled. The ones known so far are Peter Deutsch's version: bundled(md5-deutsch), a C++ port of Peter Deutsch's version: bundled(md5-deutsch-c++), Colin Plumb's bundled(md5-plumb), Alexander Peslyak's bundled(md5-peslyak), Ulrich Drepper's bundled(md5-gcc) and John Polstra's bundled(md5-polstra).
- ↑ The version for binutils provides should be the date that the binutils checkout was made
- ↑ This exception was granted because the upstream explicitly intends for this library to be "vendored" and copied directly into any projects which use it. The Fedora Packaging Committee has a general feeling of distaste for this behavior.
Packages granted temporary exceptions
Library |
Provide |
Reason |
---|---|---|
t4k_common's liblinebreak |
bundled(liblinebreak) |
t4k_common contains a forked copy of an older version of liblinebreak. This is a temporary exception granted until the t4k_common upstream is able to port their code to use the newer system copy of liblinebreak. |
boost-atomic in supercollider |
bundled(boost-atomic) |
A bundling exception for supercollider's forked copy of boost-atomic was granted through Fedora 20. For Fedora 21 and beyond, supercollider will either use versions present in boost itself or the library will be built as a separate, public subpackage that supercollider dynamically links to. https://fedorahosted.org/fpc/ticket/225 |
boost-lockfree in supercollider |
bundled(boost-lockfree) |
A bundling exception for supercollider's forked copy of boost-lockfree was granted through Fedora 20. For Fedora 21 and beyond, supercollider will either use versions present in boost itself or the library will be built as a separate, public subpackage that supercollider dynamically links to. https://fedorahosted.org/fpc/ticket/225 |
lua in nmap |
bundled(lua) |
A bundling exception for nmap's newer version of lua was granted through Fedora 19. For Fedora 20 and beyond, lua will need to be unbundled. https://fedorahosted.org/fpc/ticket/255 |
libntirpc in nfs-ganesha |
bundled(libntirpc) |
A bundling exception for nfs-ganesha to bundle libntirpc was granted through F23. The nfs-ganesha authors are working to release libntirpc as its own package (its a fork of libtiprc). This exception is to allow them the time to get that fork released separately. |
Other distributions
As this is a place where we have to convince upstream that there's a problem, it's good to be able to point out that this is a problem for all distributions, not just Fedora. Here's links to other distribution's policies::
- Debian -- http://www.debian.org/doc/debian-policy/ch-source.html#s-embeddedfiles
- Talk given at pycon with a large section on not bundling libraries http://pycon.blip.tv/file/2072580/