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

File: [local] / www / Attic / porting.html (download) (as text)

Revision 1.19, Sat Feb 27 16:37:29 1999 UTC (25 years, 3 months ago) by rohee
Branch: MAIN
Changes since 1.18: +8 -5 lines

Some precisions and updates

<html>
 <head>
  <meta http-equiv="Content-Type"
        content="text/html; charset=iso-8859-1">
  <meta name="resource-type"
        content="document">
  <meta name="description"
        CONTENT="How to make an OpenBSD port">
  <meta name="keywords"
        content="openbsd,ports">
  <meta name="distribution"
        content="global">
  <meta name="copyright"
        content="This document copyright 1997 by the OpenBSD project">
  <title>Building an OpenBSD port</title>
  <link rev="made" HREF="mailto:www@openbsd.org">
 </head>
 <body text="#000000" bgcolor="#FFFFFF" link="#23238E">
  <img height=30 width=141 src=images/smalltitle.gif alt="[OpenBSD]" >

  <h2><font color=#e00000>Building an OpenBSD port</font></h2>

   So you've just compiled your favorite software package on your
   OpenBSD machine and you want to share your effort by turning
   it into a standard port.  What to do?
  <p>
   First look at the porting information on this page.  Then check
   out the referenced documents, especially the OpenBSD porting
   <a href="checklist.html">checklist</a>.
  <p>
   Test, then re-test, and finally test again!
  <p>
   Submit the port.  Create a gzipped tarball of the port directory.
   You can then either place it on a public FTP or HTTP server, sending
   its address to <a href=mailto:ports@openbsd.org>ports@openbsd.org</a>
   or send the port mime encoded to the same address.  Pick whichever
   method works best for you.
  <p>
  <h3><font color=#0000e0>Available Porting Information</font></h3>
  <ul>
   <li>The file <code>/usr/share/mk/bsd.port.mk</code>.  This is the
       system ports makefile included at the end of each individual
       port makefile.  Read the comments at the start of the makefile.
       They do a good job of describing the available make options.
   <li>The
       <a href="http://www.netbsd.org/Documentation/software/packages.html">
       NetBSD Package System</a> documentation.  This document describes
       NetBSD's version of the FreeBSD ports system and is quite helpful.
   <li>Section 19.2.5 of the
       <a href="http://www.freebsd.org/handbook/porting.html">FreeBSD
       Handbook</a>.  This is the FreeBSD porting bible.
   <li>OpenBSD porting <a href="checklist.html">checklist</a>.
        <li><a href="audio-port.html">Porting audio applications to OpenBSD</a>.
   <li>The OpenBSD ports mailing list,
       <a href="mailto:ports@openbsd.org">ports@OpenBSD.ORG</a>.
  </ul>
  <h3><font color=#0000e0>OpenBSD Porting Policy</font></h3>
  <ul>
   <li>OpenBSD does NOT use /usr/local/etc/rc.d.<br>
       <code>/usr/local</code> is often shared between several machines 
         thanks to NFS.  For this reason, configuration files that are specific
         to a given machine can't be stored under <code>/usr/local</code>,
         <code>/etc</code> is the central repository for per machine
         configuration files.  Moreover, OpenBSD policy is to never update 
         files under <code>/etc</code> automatically.  Ports that need some
         specific boot setup should advise the administrator about what to do
         instead of blindly installing files.
   <li>OpenBSD does NOT compress man pages.
   <li>OpenBSD does NOT require <code>-lcrypt</code>.<br>
       DES encryption is part of the standard <code>libc</code>.
   <li>OpenBSD is strongly security-oriented. You should read and understand
       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
       help from the <a href="mailto:ports@openbsd.org">ports</a> mailing
       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
       for buffer overflows, especially unsafe use of
       <code>strcat/strcpy/strcmp/sprintf</code>.  In general,
       <code>sprintf</code> should be replaced with <code>snprintf</code>.

   <li>Never use filenames instead of true security. There are numerous race
       conditions where you don't have proper control. For instance, an attacker
       who already has user privileges on your machines may replace files in 
       <code>/tmp</code> with symbolic links to more strategic files, such as
       <code>/etc/master.passwd</code>.  

   <li>For instance, both <code>fopen</code> and <code>freopen</code>
       <strong>create a new file or open an existing file</strong> for
       writing. An attacker may create a symbolic link from
       <code>/etc/master.passwd</code> to <code>/tmp/addrpool_dump</code>. The
       instant you open it, your password file is hosed. Yes, even with
       an <code>unlink</code> right before. You only narrow the window
       of opportunity.  Use <code>open</code> with
       <code>O_CREAT|O_EXCLUDE</code> and <code>fdopen</code> instead.
                 
   <li>Another very common problem is the <code>mktemp</code>
       function. Heed the warnings of the bsd linker about its uses.  
       <strong>These must be fixed</strong>.
       This is not quite as simple as <code>s/mktemp/mkstemp/g</code>.  <br>
       Refer to the <code>mktemp(3)</code> man page of OpenBSD current 
       for more indications.
       Correct code using <code>mkstemp</code> includes the source to
       <code>ed</code> or <code>mail</code>.
       A rare instance of code that uses <code>mktemp</code> correctly 
       can be found in the <code>rsync</code> port.

   <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.   Do not open your file, and then do
       an <code>fstat</code> on the open descriptor to check if you should have
       been able to open it (or the attacker will play with /dev/rst0 and rewind
       your tape) -- open it with the correct uid/gid/grouplist set.

   <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, avoid <code>execvp</code>), 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>execve</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>
  <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="ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/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 fix. 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 can be found.  
       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>
  <ul>
   <li>Recent versions of <code>bsd.port.mk</code> set the installers
       path. Specifically, they set <code>/usr/bin</code> and
       <code>/bin</code> to be searched <em>before</em>
       <code>/usr/local/bin</code> and <code>/usr/X11R6/bin</code>.
   <li>Do <em>NOT</em> generate shared libraries if
       <code>${NO_SHARED_LIBS}</code> is defined.
   <li>If you rely on a feature that appeared in a recent version of
       <code>bsd.port.mk</code> don't forget to add a line
       <code>NEED_VERSION = x.yy</code> in the Makefile.
   <li>In OpenBSD <code>curses.h/libcurses/libtermlib</code> are the
       ``new curses''.  Change:<br>
       <code>ncurses.h ==&gt; curses.h</code><br>
       <code>-lncurses ==&gt; -lcurses</code><br>
       ``old (BSD) curses'' is available by defining 
       <code>_USE_OLD_CURSES_</code>
       before including <code>curses.h</code> (usually in a Makefile) and
       linking with <code>-locurses</code>.
   <li>In OpenBSD, terminal discipline has been upgraded from the older BSD
       <code>sgtty</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>sgtty</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 a terminal, 
       and that you need to handle signals: not only termination, but 
       also background (<code>SIGTSTP</code>). You should always leave 
       the 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/terminfo 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 vim 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 the corresponding  manpage.
  </ul>
  <hr>
  <a href="index.html"><img height=24 width=24 src=back.gif border=0 alt=OpenBSD></a> 
  <a href=mailto:www@openbsd.org>www@openbsd.org</a>
  <br><small>$OpenBSD: porting.html,v 1.19 1999/02/27 16:37:29 rohee Exp $</small>
 </body>
</html>