Bug #273648 - Document restriction of S to WORKDIR fallback in EAPI 4.
[portage.git] / doc / qa.docbook
1 <part id='qa'>
2 <title>Quality Assurance</title>
3 <chapter id='qa-notices'>
4  <title>QA Notices</title>
5  <para>
6   Here we'll go over each QA notice and what you (as a developer) can do to fix
7   the issue.  If you're a user, you should of course go 
8   <ulink url="http://bugs.gentoo.org/">file a bug</ulink>.  We'll only cover the
9   non-obvious notices here.
10  </para>
11  <para>
12   In pretty much all cases, you should try and get these issues resolved
13   upstream rather than simply fixing them in our ebuilds.
14  </para>
15
16  <sect1 id='qa-scanelf-runpath'>
17   <title>Scanelf: Insecure RUNPATHs</title>
18   <para>
19    <programlisting>
20     QA Notice: The following files contain insecure RUNPATHs
21    </programlisting>
22   </para>
23   <para>
24    Some of the ELFs that would be installed on the system have insecure dynamic
25    RUNPATH tags.  RUNPATH tags are a hardcoded list of filesystem paths that
26    will be searched at runtime when the ELF is executed.  If the ELF has a
27    world accessible directory hardcoded in it, then a malicious person can
28    inject code at runtime by adding their own libraries to the directory.
29   </para>
30   <para>
31    Here are some of the common problems and their solutions.
32    <itemizedlist>
33     <listitem>
34      <para>Libtool - old versions of libtool would use too many -rpath flags</para>
35      <para>Solution: Regenerate the autotool code</para>
36     </listitem>
37     <listitem>
38      <para>Perl - some versions of perl would use incorrect -rpath flags</para>
39      <para>Solution: Upgrade system perl build modules</para>
40     </listitem>
41     <listitem>
42      <para>Crappy build system - the custom build system uses -rpath incorrectly</para>
43      <para>Solution: Review the LDFLAGS in the build system and make them not suck</para>
44     </listitem>
45     <listitem>
46      <para>Crappy ebuild - the ebuild installs ELFs instead of using the package's build system</para>
47      <para>Solution: Fix the crappy ebuild to use the package's build system</para>
48     </listitem>
49    </itemizedlist>
50   </para>
51  </sect1>
52
53  <sect1 id='qa-scanelf-textrel'>
54   <title>Scanelf: Runtime Text Relocations (TEXTRELS)</title>
55   <para>
56    <programlisting>
57     QA Notice: The following files contain runtime text relocations
58    </programlisting>
59   </para>
60   <para>
61    Please see the Gentoo Hardened <ulink url="http://hardened.gentoo.org/pic-fix-guide.xml">PIC Fix Guide</ulink>.
62   </para>
63  </sect1>
64
65  <sect1 id='qa-scanelf-execstack'>
66   <title>Scanelf: Executable Stack (EXECSTACK)</title>
67   <para>
68    <programlisting>
69     QA Notice: The following files contain executable stacks
70    </programlisting>
71   </para>
72   <para>
73    Please see the Gentoo Hardened <ulink url="http://hardened.gentoo.org/gnu-stack.xml">GNU Stack Guide</ulink>.
74   </para>
75  </sect1>
76
77  <sect1 id='qa-scanelf-soname'>
78   <title>Scanelf: Missing Shared Object Name (SONAME)</title>
79   <para>
80    <programlisting>
81     QA Notice: The following shared libraries lack a SONAME
82    </programlisting>
83   </para>
84   <para>
85    A shared library that you would link against lacks an ELF SONAME tag.  With
86    simpler libraries, this can be acceptable, but with any sort of ABI sane
87    setup, you need the SONAME tag.  This tag is how the system linker tells the
88    loader what libraries a program needs at runtime.  With a missing SONAME,
89    the linker needs to guess and with many cases, this guess will not work for
90    long.
91   </para>
92   <para>
93    To fix this issue, make sure the shared library is linked with the proper
94    <option>-Wl,-soname,...</option> flag.  You will need to replace the
95    <replaceable>...</replaceable> part with the actual ABI name.  For example,
96    if the library is named <filename>libfoo.so.1.2.3</filename>, you will
97    probably want to specify <option>-Wl,-soname,libfoo.so.1</option>.
98   </para>
99   <para>
100    Note that this warning only applies to shared libraries that you would link
101    against.  It certainly does not apply to plugins that you would dynamically
102    load.  However, plugins should not exist in the main library directory, but
103    rather an application specific subdirectory in the library directory.  In
104    other words, it should be <filename>/usr/lib/app/plugin.so</filename> rather
105    than <filename>/usr/lib/plugin.so</filename>.
106   </para>
107  </sect1>
108
109  <sect1 id='qa-scanelf-needed'>
110   <title>Scanelf: Missing Needed Entries</title>
111   <para>
112    <programlisting>
113     QA Notice: The following shared libraries lack NEEDED entries
114    </programlisting>
115   </para>
116   <para>
117    This warning comes up when a library does not actually seem to need any
118    other libraries in order to run.  Rarely is this true as almost every
119    library will need at least the system C library.
120   </para>
121   <para>
122    Once you've determined that the library is indeed being generated
123    incorrectly, you will need to dig into the build system to make sure that
124    it pulls in the libraries it needs.  Often times, this is because the
125    build system invokes the system linker (<command>ld</command>) directly
126    instead of the system compiler driver (<command>gcc</command>).
127   </para>
128  </sect1>
129
130  <sect1 id='qa-abs-lib-link'>
131   <title>Absolute Symlink In Library Directory</title>
132   <para>
133    <programlisting>
134     QA Notice: Found an absolute symlink in a library directory
135    </programlisting>
136   </para>
137   <para>
138    If you want to use symlinks in library directories, please use either a
139    relative symlink or a linker script.  This can cause problems when working
140    with cross-compiler systems or when accessing systems in a different ROOT
141    directory.
142   </para>
143   <para>
144    If you have a library installed into <filename>/lib/</filename> and you want
145    to have it accessible in <filename>/usr/lib/</filename>, then you should
146    generate a linker script so that the system toolchain can handle it properly.
147    Please see the <link linkend="qa-missing-ldscript">linker script section</link>
148    for more information.
149   </para>
150  </sect1>
151
152  <sect1 id='qa-missing-ldscript'>
153   <title>Missing Linker Script</title>
154   <para>
155    <programlisting>
156     QA Notice: Missing gen_usr_ldscript
157    </programlisting>
158   </para>
159   <para>
160    If you have a shared library in <filename>/lib/</filename> and a static
161    library in <filename>/usr/lib/</filename>, but no linker script in
162    <filename>/usr/lib/</filename>, then the toolchain will choose the incorrect
163    version when linking.  The system linker will find the static library first
164    and not bother searching for a dynamic version.  To overcome this, you need
165    to use the <command>gen_usr_ldscript</command> function found in the
166    toolchain-funcs.eclass.  Refer to the
167    man page for information on how to use it.  See this
168    <ulink url="http://bugs.gentoo.org/4411">bug report</ulink> for some history
169    on this issue.
170   </para>
171  </sect1>
172
173  <sect1 id='qa-root-cruft'>
174   <title>Excessive Files in /</title>
175   <para>
176    <programlisting>
177     QA Notice: Excessive files found in the / partition
178    </programlisting>
179   </para>
180   <para>
181    You should not store files that are not critical to boot and recovery in
182    the root filesystem.  This means that static libraries and libtool scripts do
183    not belong in the <filename>/lib/</filename> directory.  Fix your ebuild so
184    it does not install there.
185   </para>
186  </sect1>
187
188  <sect1 id='qa-tempdir-libtool'>
189   <title>Portage Tempdir In Libtool Scripts</title>
190   <para>
191    <programlisting>
192     QA Notice: ... appears to contain PORTAGE_TMPDIR paths
193    </programlisting>
194   </para>
195   <para>
196    Older versions of libtool would incorrectly record the build and/or install
197    directory in the libtool script (*.la).  This would lead to problems when
198    building other things against your package as libtool would be confused by
199    the old paths.
200   </para>
201   <para>
202    You may be able to cheat and use the <command>elibtoolize</command> function
203    in the libtool.eclass.  However, if
204    that does not help, you will probably need to regenerate all of the autotool
205    files.
206   </para>
207  </sect1>
208
209  <sect1 id='qa-build-strict-aliasing'>
210   <title>Build Warning: Strict Aliasing</title>
211   <para>
212    <programlisting>
213     QA Notice: Package has poor programming practices which may compile
214                fine but exhibit random runtime failures.
215     ...: warning: dereferencing type-punned pointer will break strict-aliasing rules
216    </programlisting>
217   </para>
218   <para>
219    This warning crops up when code starts casting distinct pointer types and
220    then dereferencing them.  Generally, this is a violation of aliasing rules
221    which are part of the C standard.  Historically, these warnings did not show
222    up as the optimization was not turned on by default.  With gcc-4.1.x and
223    newer though, the -O2 optimization level enables strict aliasing support.
224    For information, please review these links:
225    <ulink url="http://mail-index.netbsd.org/tech-kern/2003/08/11/0001.html">NetBSD Explanation</ulink>,
226    <ulink url="http://thread.gmane.org/gmane.linux.gentoo.devel/39495">Gentoo Dev Thread</ulink>,
227    <ulink url="http://gcc.gnu.org/bugs.html#nonbugs_c">GCC Docs</ulink>
228   </para>
229   <para>
230    To fix this issue, use the methods proposed in the links mentioned earlier.
231    If you're unable to do so, then a work around would be to append the gcc
232    -fno-strict-aliasing flag to CFLAGS in the ebuild.
233   </para>
234  </sect1>
235
236  <sect1 id='qa-build-implicit-decl'>
237   <title>Build Warning: Implicit Declarations</title>
238   <para>
239    <programlisting>
240     QA Notice: Package has poor programming practices which may compile
241                fine but exhibit random runtime failures.
242     ...: warning: implicit declaration of function ...
243     ...: warning: incompatible implicit declaration of built-in function ...
244    </programlisting>
245   </para>
246   <para>
247    Your code is calling functions which lack prototypes.  In C++, this would
248    have been a build failure, but C is lazy so you just get a warning.  This
249    can be a problem as gcc has to guess at what sort of arguments a function
250    takes based upon how it was called and often times, this is not the same
251    as what the function actually takes.  The function return type is also
252    unknown so it's just assumed to be an integer (which is often times wrong).
253    This can get to be a problem when the size of the types guessed do not
254    actually match the size of the types the function expects.  Generally, this
255    corresponds directly to proper coding practices (and the lack thereof).
256    Also, by including proper prototypes, the compiler often helps by checking
257    types used, proper number of arguments passed, etc...
258   </para>
259   <para>
260    To fix this, just include the proper header files for the functions in
261    question.  If the function is a package-specific one, then you may have to
262    create a header/function prototype for it.
263   </para>
264  </sect1>
265
266  <sect1 id='qa-build-uninitialized'>
267   <title>Build Warning: Used Uninitialized</title>
268   <para>
269    <programlisting>
270     QA Notice: Package has poor programming practices which may compile
271                fine but exhibit random runtime failures.
272     ...: warning: is used uninitialized in this function
273    </programlisting>
274   </para>
275   <para>
276    This means code uses a variable without actually setting it first.  In other
277    words, the code is basically using random garbage.
278   </para>
279   <para>
280    The fix here is simple: make sure variables are initialized properly before
281    using them.
282   </para>
283  </sect1>
284
285  <sect1 id='qa-build-math-compare'>
286   <title>Build Warning: Invalid X&lt;=Y&lt;=Z Comparisons</title>
287   <para>
288    <programlisting>
289     QA Notice: Package has poor programming practices which may compile
290                fine but exhibit random runtime failures.
291     ...: warning: comparisons like X&lt;=Y&lt;=Z do not have their mathematical meaning
292    </programlisting>
293   </para>
294   <para>
295    This warning crops up either when the programmer expected the expression
296    to work or they just forgot to use sufficient parentheses.  For example,
297    the following code snippets are wrong (we won't get into the technical
298    argument of this being valid C code; just change the code to not be
299    ambiguous).
300    <programlisting>
301     if (x &lt;= y &lt;= z)
302       ...;
303     if (a &lt; b &lt;= c)
304       ...;
305    </programlisting>
306   </para>
307   <para>
308    To fix this, read the code to figure out what exactly the programmer meant.
309   </para>
310  </sect1>
311
312  <sect1 id='qa-build-non-null'>
313   <title>Build Warning: Non-Null Required</title>
314   <para>
315    <programlisting>
316     QA Notice: Package has poor programming practices which may compile
317                fine but exhibit random runtime failures.
318     ...: warning: null argument where non-null required
319    </programlisting>
320   </para>
321   <para>
322    Many functions take pointers as arguments and require that the pointer never
323    be NULL.  To this end, you can declare function prototypes that instruct the
324    compiler to do simple checks to make sure people do not incorrectly call the
325    function with NULL values.  This warning pops up when someone calls a
326    function and they use NULL when they should not.  Depending on the library,
327    the function may actually crash (they told you not to use NULL after-all, so
328    it's your fault :P).
329   </para>
330   <para>
331    You will need to read the code and fix it so that it does not incorrectly
332    call the relevant functions with NULL values.
333   </para>
334  </sect1>
335
336  <sect1 id='qa-build-pointer-trunc'>
337   <title>Build Warning: Truncating Pointers</title>
338   <para>
339    <programlisting>
340     QA Notice: Package has poor programming practices which may compile
341                but will almost certainly crash on 64bit architectures.
342    </programlisting>
343   </para>
344   <para>
345    A large portion of code in the open source world is developed on the 32bit
346    x86 architecture.  Unfortunately, this has led to many pieces of code not
347    handling pointer types properly.  When compiled and run on a 64bit
348    architecture, the code in question will probably crash horribly.  Some
349    common examples are assuming that an integer type is large enough to hold
350    pointers.  This is true on 32bit architectures (an integer can hold 32bits
351    and a pointer is 32bits big), but not true on 64bit architectures (an
352    integer still holds just 32bits, but a pointer is 64bits big).
353   </para>
354   <para>
355    Since this issue can manifest itself in many ways (as there are many ways to
356    improperly truncate a pointer), you will need to read the source code
357    starting with the displayed warning.  Make sure types are declared, used,
358    and passed properly.  Make sure that all function prototypes are found (see
359    the <link linkend="qa-build-implicit-decl">Implicit Declarations</link>
360    section for more information).  So on and so forth.
361   </para>
362  </sect1>
363 </chapter>
364 </part>