[BACK]Return to porting.html CVS log [TXT][DIR] Up to [local] / www

Diff for /www/Attic/porting.html between version 1.9 and 1.10

version 1.9, 1998/08/12 22:13:02 version 1.10, 1998/08/13 23:11:18
Line 67 
Line 67 
    <li>OpenBSD does NOT compress man pages.     <li>OpenBSD does NOT compress man pages.
    <li>OpenBSD does NOT require <code>-lcrypt</code>.<br>     <li>OpenBSD does NOT require <code>-lcrypt</code>.<br>
        DES encryption is part of the standard <code>libc</code>.         DES encryption is part of the standard <code>libc</code>.
    <li>OpenBSD requests all <code>mktemp</code> warnings to be fixed.     <li>OpenBSD is strongly security-oriented. You should read and understand
        This is not as simple as <code>s/mktemp/mkstemp/g</code>.  If         this page's <a href="#security">security section</a>.
      <li>Be sure to add the <code>$</code><code>OpenBSD$</code> CVS tag to
          the Makefile.  If importing a port from another system be sure to
          leave their tag in the Makefile, too.  However, replace the FreeBSD
          <code>$</code><code>Id$</code> tag with the
          <code>$</code><code>FreeBSD$</code> tag.
      <li>The goal is to get all ported applications to support OpenBSD.  To
          achieve this goal you <strong>must</strong> feed any OpenBSD patches
          back to the application maintainer.
     </ul>
     <a name=security>
     <h3><font color=#0000e0>Security recommendations</font></h3>
     There are many security problems to worry about. If
        you are not absolutely sure of what you are doing please request         you are not absolutely sure of what you are doing please request
        help from the <a href="mailto:ports@openbsd.org">ports</a> mailing         help from the <a href="mailto:ports@openbsd.org">ports</a> mailing
        list.         list.
   
     <ul>
      <li>Do <emph>not</emph> use alpha or beta code when preparing a port.  Use the
          latest regular or patch release.
   
    <li>Any software to be installed as a server should be scanned     <li>Any software to be installed as a server should be scanned
        for buffer overflows, especially unsafe use of         for buffer overflows, especially unsafe use of
        <code>strcat/strcpy/strcmp/sprintf</code>.  In general,         <code>strcat/strcpy/strcmp/sprintf</code>.  In general,
        <code>sprintf</code> should be replaced with <code>snprintf</code>.         <code>sprintf</code> should be replaced with <code>snprintf</code>.
    <li>Be sure to add the <code>$</code><code>OpenBSD$</code> CVS tag to  
        the Makefile.  If importing a port from another system be sure to     <li>Never use filenames when you need security.   There are numerous race
        leave their tag in the Makefile, too.  However, replace the FreeBSD         conditions where you don't have proper control. For instance, an attacker
        <code>$</code><code>Id$</code> tag with the         who already has user privileges on your machines may replace files in
        <code>$</code><code>FreeBSD$</code> tag.         <code>/tmp</code> with symbolic links to more strategic files, such as
    <li>Do NOT use alpha or beta code when preparing a port.  Use the         <code>/etc/passwd</code>.  For instance, the bsd linker warns about
        latest regular or patch release.         <code>mktemp</code> uses.  <strong>These must be fixed</strong>.
    <li>The goal is to get all ported applications to support OpenBSD.  To         This is not quite as simple as <code>s/mktemp/mkstemp/g</code>.
        achieve this goal you MUST feed any OpenBSD patches back to the  
        application maintainer.     <li>Just because you can read it doesn't mean you should. A well-known hole
          of this nature was the <code>startx</code> problem.  As a setuid program,
          you could launch startx with any file as a script. If the file was not
          a valid shell script, a syntax error message would follow, along with the
          first line of the offending file, without any further permission check.
          Pretty handy to grab the first line of a shadow passwd file, considering
          these often start with root entry.   Once again, don't trust filenames:
          open your file, and do an <code>fstat</code> on the open descriptor to
          check the actual rights.
   
      <li>Don't use anything that forks a shell in setuid programs before dropping
          your privileges. This includes <code>popen</code> and <code>system</code>.
          Use <code>fork</code>, <code>pipe</code> and <code>execve</code> instead.
   
      <li>Pass open descriptors instead of filenames to other programs to avoid race
          conditions.  Even if a program does not accept file descriptors, you can
          still use <code>/dev/fd/0</code>.
   
      <li>Access rights are attached to file descriptors.  If you need setuid rights
          to open a file, open that file, then drop your privileges. You can still
          access the open descriptor, but you have less to worry about. This is
          double-edged: even after dropping privileges, you should still watch out
          for those descriptors.
   
      <li>Avoid root setuid as much as you can. Basically, root can do anything,
          but root rights are very rarely needed, except maybe to create socket ports with
          a number under 1024.  It is arguably better to keep that under <code>inetd</code>
          control and just add the relevant entries to <code>inetd.conf</code>.
          You must know the appropriate magic for writing daemons to achieve that.
          It could be argued that you have no business writing setuid programs if you don't
          know how to do that.
   
      <li>Use setgid instead of setuid.  Apart from those specific files needed by setgid
          programs, most files are not group-writable. Hence, a security problem in a setgid
          program won't compromise your system as much: with only group rights, the worst
          an intruder will be able to do is hack a games score table or some such.
          See the <code>xkobo</code> port for an instance of such a change.
   
      <li>Don't trust group-writable files.  Even though they are audited, setgid programs
          are not perceived as important potential security holes. Hence stuff they can tamper
          with shouldn't be considered sensitive information.
   
      <li>Don't trust your environment ! This involves simple things such as your <code>PATH</code>
          (never use <code>system</code> with an unqualified name), but also more subtle items
          such as your locale, timezone, termcap, and so on.  Be aware of transitivity: even though you're
          taking full precautions, programs you call directly won't necessarily. <strong>Never</strong>
          use <code>system</code> in privileged programs, build your command line, a controlled environment,
          and call <code>execvp</code> directly. The <code>perlsec</code> man page is a good tutorial on
          such problems.
   
      <li>Never used setuid shell-scripts.  These are inherently insecure. Wrap them into some C code
          that ensures a proper environment.   On the other hand, OpenBSD features secure perl scripts.
   
      <li>Beware the dynamic loader. If you are running setuid, it will only use trusted libraries
          that were scanned with ldconfig.  Setgid is not enough.
   
      <li>Dynamic libraries are tricky. C++ code sets a similar problem. Basically, libraries may take
          some action based upon your environment before your main program even gets to check its setuid
          status.   OpenBSD <code>issetugid</code> addresses this problem, from the library writer point
          of view.  Don't try to port libraries unless you understand this issue thoroughly.
   </ul>    </ul>
     <h3><font color=#0000e0>Generic porting hints</font></h3>
     <ul>
      <li><code>__OpenBSD__</code> should be used sparingly, if at all.
          Constructs that look like
          <pre>
               #if defined(__NetBSD__) || defined(__FreeBSD__)
          </pre>
          are often inappropriate. Don't add blindly <code>__OpenBSD__</code>
          to it. Instead, try to figure out what's going on, and what actual
          feature is needed.   Manual pages are often useful, as they include
          historic comments, stating when a particular feature was incorporated
          into BSD.  Checking the numeric value of <code>BSD</code> against known
          releases is often the right way. See
          <a href="http://www.netbsd.org/Documentation/netbsd/Packages.txt">the NetBSD package guide</a>
          for more information.
      <li>Defining <code>BSD</code> is a bad idea. Try to include <code>sys/param.h</code>.
          This not only defines <code>BSD</code>, it also gives it a proper value.
          The right code fragment should look like:
          <pre>
              #if (defined(__unix__) || defined(unix)) && !defined(USG)
              #include &lt;sys/param.h&gt;
              #endif
          </pre>
      <li>Test for features, not for specific OSes. In the long run, it is much
          better to test whether <code>tcgetattr</code> works than whether you're running
          under BSD 4.3 or later, or SystemVR4.  These kind of tests just confuse the
          issue. The way to go about it is, for instance, to test for one particular
          system, set up a slew of <code>HAVE_TCGETATTR</code> defines, then proceed to
          the next system.  This technique separates features tests from specific OSes.
          In a hurry, another porter can just add the whole set of <code>-DHAVE_XXX</code>
          defines to the Makefile.  One may also write or add to a configure script to check for
          that feature and add it automatically.  As an example not to follow, check nethack 3.2.2
          source: it assumes loads of things based on the system type.  Most of these assumptions
          are obsolete and no longer reflect reality: POSIX functions are more useful than older
          BSD versus SystemV differences, to the point that some traditional bsd functions are
          now only supported through compatibility libraries.
   
      <li>Avoid include files that include other includes that... First, because
          this is inefficient. Your project will end up including a file that includes
          everything.  Also, because it makes some problems difficult to correct. It
          becomes harder to <em>not</em> include one particular file at a given point.
   
      <li>Avoid bizarre macro tricks.  Undefining a macro that was defined by a
          header file is a bad idea.  Defining macros to get some specific behavior
          from an include file is also a bad idea: compilation modes should be global.
          If you want POSIX behavior, say so, and <code>#define POSIX_C_SOURCE</code>
          throughout the whole project, not when you feel like it.
   
      <li>Don't ever write system function prototypes.  All modern systems,
          OpenBSD included, have a standard location for these prototypes. Likely
          places include <code>unistd.h</code>, <code>fcntl.h</code> or <code>termios.h</code>.
          The man page frequently states where the prototype lies.  You might need
          another slew of <code>HAVE_XXX</code> macros to procure the right file.
          Don't worry about including the same file twice, include files have guards
          that prevent all kinds of nastiness.<br>
          If some broken system needs you to write the prototype, don't impose
          on all other systems. Roll-your-own prototypes will break because they may
          use types that are equivalent on your system, but are not portable to other
          systems (<code>unsigned long</code> instead of <code>size_t</code>), or get some
          <code>const</code> status wrong. Also, some compilers, such as OpenBSD's own gcc,
          are able to do a better job with some very frequent functions such as
          <code>strlen</code> if you include the right header file.
   
      <li>Don't use the name of a standard system function for anything else.
          If you want to write your own function, give it its own name, and call that
          function everywhere.  If you wish to revert to the default system function,
          you just need to comment your code out, and define your own name to the
          system function. Don't do it the other way round. Code should look like this
   <pre>
          /* prototype part */
          #ifdef USE_OWN_GCVT
          char *foo_gcvt(double number, size_t ndigit, char *buf);
          #else
          /* include correct file */
          #include &lt;stdlib.h&gt;
          /* use system function */
          #define foo_gcvt  gcvt
          #endif
   
          /* definition part */
          #ifdef USE_OWN_GCVT
          char *foo_gcvt(double number, size_t ndigit, char *buf)
             {
             /* proper definition */
             }
   
          /* typical use */
          s = foo_gcvt(n, 15, b);
          </pre>
     </ul>
   <h3><font color=#0000e0>Other Helpful Hints</font></h3>    <h3><font color=#0000e0>Other Helpful Hints</font></h3>
   <ul>    <ul>
    <li>Do not assume <code>/usr/local/bin</code> or     <li>Do not assume <code>/usr/local/bin</code> or
Line 101 
Line 267 
        <code>ncurses.h ==> curses.h</code><br>         <code>ncurses.h ==> curses.h</code><br>
        <code>-lncurses ==> -lcurses</code><br>         <code>-lncurses ==> -lcurses</code><br>
        ``Old curses'' is available as <code>ocurses.h/libocurses</code>.         ``Old curses'' is available as <code>ocurses.h/libocurses</code>.
      <li>In OpenBSD, terminal discipline has been upgraded from the older <code>sgtty</code>
          standard BSD <code>fcntl</code> to the newer POSIX <code>tcgetattr</code> family.
          Avoid the older style in new code.  Some code may define <code>tcgetattr</code>
          to be a synonym for the older <code>fcntl</code>, but this is at best a stopgap
          measure on OpenBSD.  The <code>xterm</code> source code is a very good example of
          what not to do.
          Try to get your system functionality right: you want a type that remembers
          the state of your terminal (possible typedef), you want a function that
          extracts the current state, and a function that sets the new state.
          Functions that modify this state are more difficult, as they tend to vary
          depending upon the system.  Also, don't forget that you will have to handle
          cases where you are not connected to the terminal, and that you need to
          handle signals: not only termination, but also getting put in the background
          you should leave your terminal in a sane state.  Do your tests under an
          older shell, such as sh, which does not reset the terminal in any way at
          program's termination.
      <li>The newer termcap and curses, as included with OpenBSD, include standard sequences
          for controlling color terminals.  You should use these if possible, reverting
          to standard ANSI color sequences on other systems.  However, some terminal descriptions
          have not been updated yet, and you may need to be able to specify these sequences manually.
          This is the way vim5.1 handles it.  This is not strictly necessary. Except for privileged
          programs, it is generally possible to override a termcap definition through the
          <code>TERMCAP</code> variable and get it to work properly.
      <li>Signal semantics are tricky, and vary from one system to another. Use <code>sigaction</code>
          to ensure a specific semantics, along with other system calls referenced in its manpage.
   </ul>    </ul>
   <hr>    <hr>
   <a href="index.html"><img height=24 width=24 src=back.gif border=0 alt=OpenBSD></a>    <a href="index.html"><img height=24 width=24 src=back.gif border=0 alt=OpenBSD></a>

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10