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

Diff for /www/Attic/porting.html between version 1.14 and 1.15

version 1.14, 1998/12/07 23:06:48 version 1.15, 1998/12/20 17:08:45
Line 1 
Line 1 
 <html>  <html>
  <head>   <head>
   <meta http-equiv="Content-Type"    <meta http-equiv="Content-Type"
         content="text/html; charset=iso-8859-1">          content="text/html; charset=iso-8859-1">
   <meta name="resource-type"    <meta name="resource-type"
         content="document">          content="document">
   <meta name="description"    <meta name="description"
         CONTENT="How to make an OpenBSD port">          CONTENT="How to make an OpenBSD port">
   <meta name="keywords"    <meta name="keywords"
         content="openbsd,ports">          content="openbsd,ports">
   <meta name="distribution"    <meta name="distribution"
         content="global">          content="global">
   <meta name="copyright"    <meta name="copyright"
         content="This document copyright 1997 by the OpenBSD project">          content="This document copyright 1997 by the OpenBSD project">
   <title>Building an OpenBSD port</title>    <title>Building an OpenBSD port</title>
   <link rev="made" HREF="mailto:www@openbsd.org">    <link rev="made" HREF="mailto:www@openbsd.org">
  </head>   </head>
Line 50 
Line 50 
        <a href="http://www.freebsd.org/handbook/porting.html">FreeBSD         <a href="http://www.freebsd.org/handbook/porting.html">FreeBSD
        Handbook</a>.  This is the FreeBSD porting bible.         Handbook</a>.  This is the FreeBSD porting bible.
    <li>OpenBSD porting <a href="checklist.html">checklist</a>.     <li>OpenBSD porting <a href="checklist.html">checklist</a>.
         <li><a href="audio-port.html">Porting audio applications to OpenBSD</a>.          <li><a href="audio-port.html">Porting audio applications to OpenBSD</a>.
    <li>The OpenBSD ports mailing list,     <li>The OpenBSD ports mailing list,
        <a href="mailto:ports@openbsd.org">ports@OpenBSD.ORG</a>.         <a href="mailto:ports@openbsd.org">ports@OpenBSD.ORG</a>.
   </ul>    </ul>
Line 58 
Line 58 
   <ul>    <ul>
    <li>OpenBSD does NOT use /usr/local/etc/rc.d.<br>     <li>OpenBSD does NOT use /usr/local/etc/rc.d.<br>
        <code>/usr/local</code> is often shared between several machines         <code>/usr/local</code> is often shared between several machines
          thanks to NFS.  For this reason, configuration files that are specific           thanks to NFS.  For this reason, configuration files that are specific
          to a given machine can't be stored under <code>/usr/local</code>,           to a given machine can't be stored under <code>/usr/local</code>,
          <code>/etc</code> is the central repository for per machine           <code>/etc</code> is the central repository for per machine
          configuration files.  Moreover, OpenBSD policy is to never update           configuration files.  Moreover, OpenBSD policy is to never update
          files under <code>/etc</code> automatically.  Ports that need some           files under <code>/etc</code> automatically.  Ports that need some
          specific boot setup should advise the administrator about what to do           specific boot setup should advise the administrator about what to do
          instead of blindly installing files.           instead of blindly installing files.
    <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>.
Line 99 
Line 99 
        conditions where you don't have proper control. For instance, an attacker         conditions where you don't have proper control. For instance, an attacker
        who already has user privileges on your machines may replace files in         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>/tmp</code> with symbolic links to more strategic files, such as
        <code>/etc/passwd</code>.  For instance, the bsd linker warns about         <code>/etc/passwd</code>.
        <code>mktemp</code> uses.  <strong>These must be fixed</strong>.  
        This is not quite as simple as <code>s/mktemp/mkstemp/g</code>.     <li>For instance, one very common problem is the <code>mktemp</code>
          function. Head 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     <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,         of this nature was the <code>startx</code> problem.  As a setuid program,
Line 111 
Line 120 
        Pretty handy to grab the first line of a shadow passwd file, considering         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         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         an <code>fstat</code> on the open descriptor to check if you should have
        been able to open it (or the attacked will play with /dev/rst0 and rewind         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.         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     <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>.         your privileges. This includes <code>popen</code> and
          <code>system</code>.
        Use <code>fork</code>, <code>pipe</code> and <code>execve</code> instead.         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     <li>Pass open descriptors instead of filenames to other programs to
        conditions.  Even if a program does not accept file descriptors, you can         avoid race conditions.  Even if a program does not accept file
        still use <code>/dev/fd/0</code>.         descriptors, you can still use <code>/dev/fd/0</code>.
   
    <li>Access rights are attached to file descriptors.  If you need setuid rights     <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         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         access the open descriptor, but you have less to worry about. This is
        double-edged: even after dropping privileges, you should still watch out         double-edged: even after dropping privileges, you should still watch out
        for those descriptors.         for those descriptors.
   
    <li>Avoid root setuid as much as you can. Basically, root can do anything,     <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         but root rights are very rarely needed, except maybe to create
        a number under 1024.  It is arguably better to keep that under <code>inetd</code>         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>.         control and just add the relevant entries to <code>inetd.conf</code>.
        You must know the appropriate magic for writing daemons to achieve that.         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         It could be argued that you have no business writing setuid programs
        know how to do that.         if you don't know how to do that.
   
    <li>Use setgid instead of setuid.  Apart from those specific files needed by setgid     <li>Use setgid instead of setuid.  Apart from those specific files needed
        programs, most files are not group-writable. Hence, a security problem in a setgid         by setgid programs, most files are not group-writable. Hence, a
        program won't compromise your system as much: with only group rights, the worst         security problem in a setgid program won't compromise your system as
        an intruder will be able to do is hack a games score table or some such.         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.         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     <li>Don't trust group-writable files.  Even though they are audited,
        are not perceived as important potential security holes. Hence stuff they can tamper         setgid programs are not perceived as important potential security
        with shouldn't be considered sensitive information.         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>     <li>Don't trust your environment ! This involves simple things such as
        (never use <code>system</code> with an unqualified name), but also more subtle items         your <code>PATH</code> (never use <code>system</code> with an
        such as your locale, timezone, termcap, and so on.  Be aware of transitivity: even though you're         unqualified name, avoid <code>execvp</code>), but also more subtle
        taking full precautions, programs you call directly won't necessarily. <strong>Never</strong>         items such as your locale, timezone, termcap, and so on.
        use <code>system</code> in privileged programs, build your command line, a controlled environment,         Be aware of transitivity: even though you're taking full precautions,
        and call <code>execvp</code> directly. The <code>perlsec</code> man page is a good tutorial on         programs you call directly won't necessarily. <strong>Never</strong>
        such problems.         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     <li>Never used setuid shell-scripts.  These are inherently insecure.
        that ensures a proper environment.   On the other hand, OpenBSD features secure perl scripts.         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     <li>Beware the dynamic loader. If you are running setuid, it will only
        that were scanned with ldconfig.  Setgid is not enough.         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     <li>Dynamic libraries are tricky. C++ code sets a similar problem.
        some action based upon your environment before your main program even gets to check its setuid         Basically, libraries may take some action based upon your environment
        status.   OpenBSD <code>issetugid</code> addresses this problem, from the library writer point         before your main program even gets to check its setuid status.
        of view.  Don't try to port libraries unless you understand this issue thoroughly.         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>    <h3><font color=#0000e0>Generic porting hints</font></h3>
   <ul>    <ul>
Line 189 
Line 208 
            #endif             #endif
        </pre>         </pre>
    <li>Test for features, not for specific OSes. In the long run, it is much     <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         better to test whether <code>tcgetattr</code> works than whether
        under BSD 4.3 or later, or SystemVR4.  These kind of tests just confuse the         you're running under BSD 4.3 or later, or SystemVR4.  These kind of
        issue. The way to go about it is, for instance, to test for one particular         tests just confuse the issue. The way to go about it is, for instance,
        system, set up a slew of <code>HAVE_TCGETATTR</code> defines, then proceed to         to test for one particular system, set up a slew of
        the next system.  This technique separates features tests from specific OSes.         <code>HAVE_TCGETATTR</code> defines, then proceed to the next system.
        In a hurry, another porter can just add the whole set of <code>-DHAVE_XXX</code>         This technique separates features tests from specific OSes.
        defines to the Makefile.  One may also write or add to a configure script to check for         In a hurry, another porter can just add the whole set of
        that feature and add it automatically.  As an example not to follow, check nethack 3.2.2         <code>-DHAVE_XXX</code> defines to the Makefile.  One may also write
        source: it assumes loads of things based on the system type.  Most of these assumptions         or add to a configure script to check for that feature and add it
        are obsolete and no longer reflect reality: POSIX functions are more useful than older         automatically.  As an example not to follow, check nethack 3.2.2
        BSD versus SystemV differences, to the point that some traditional bsd functions are         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.         now only supported through compatibility libraries.
   
    <li>Avoid include files that include other includes that... First, because     <li>Avoid include files that include other includes that... First, because
        this is inefficient. Your project will end up including a file that includes         this is inefficient. Your project will end up including a file that
        everything.  Also, because it makes some problems difficult to correct. It         includes everything.  Also, because it makes some problems difficult
        becomes harder to <em>not</em> include one particular file at a given point.         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     <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         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.         from an include file is also a bad idea: compilation modes should be
        If you want POSIX behavior, say so, and <code>#define POSIX_C_SOURCE</code>         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.         throughout the whole project, not when you feel like it.
   
    <li>Don't ever write system function prototypes.  All modern systems,     <li>Don't ever write system function prototypes.  All modern systems,
        OpenBSD included, have a standard location for these prototypes. Likely         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>.         places include <code>unistd.h</code>, <code>fcntl.h</code> or
        The man page frequently states where the prototype lies.  You might need         <code>termios.h</code>.
        another slew of <code>HAVE_XXX</code> macros to procure the right file.         The man page frequently states where the prototype can be found.
        Don't worry about including the same file twice, include files have guards         You might need another slew of <code>HAVE_XXX</code> macros to
        that prevent all kinds of nastiness.<br>         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         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         on all other systems. Roll-your-own prototypes will break because they
        use types that are equivalent on your system, but are not portable to other         may use types that are equivalent on your system, but are not portable
        systems (<code>unsigned long</code> instead of <code>size_t</code>), or get some         to other systems (<code>unsigned long</code> instead of
        <code>const</code> status wrong. Also, some compilers, such as OpenBSD's own gcc,         <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         are able to do a better job with some very frequent functions such as
        <code>strlen</code> if you include the right header file.         <code>strlen</code> if you include the right header file.
   
    <li>Don't use the name of a standard system function for anything else.     <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         If you want to write your own function, give it its own name, and
        function everywhere.  If you wish to revert to the default system function,         call that function everywhere.  If you wish to revert to the
        you just need to comment your code out, and define your own name to the         default system function, you just need to comment your code out,
        system function. Don't do it the other way round. Code should look like this         and define your own name to the system function. Don't do it the
          other way round. Code should look like this
 <pre>  <pre>
        /* prototype part */         /* prototype part */
        #ifdef USE_OWN_GCVT         #ifdef USE_OWN_GCVT
Line 248 
Line 275 
        #ifdef USE_OWN_GCVT         #ifdef USE_OWN_GCVT
        char *foo_gcvt(double number, size_t ndigit, char *buf)         char *foo_gcvt(double number, size_t ndigit, char *buf)
           {            {
           /* proper definition */            /* proper definition */
           }            }
   
        /* typical use */         /* typical use */
        s = foo_gcvt(n, 15, b);         s = foo_gcvt(n, 15, b);
Line 257 
Line 284 
   </ul>    </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>Recent versions of <code>bsd.port.mk</code> set the installers
        <code>/usr/X11R6/bin</code> is in the installers path.  A good         path. Specifically, they set <code>/usr/bin</code> and
        way to verify this is to create and install your port while         <code>/bin</code> to be searched <em>before</em>
        running as <code>root</code> with only <code>/bin</code> and         <code>/usr/local/bin</code> and <code>/usr/X11R6/bin</code>.
        <code>/usr/bin</code> in your path.     <li>Do <em>NOT</em> generate shared libraries for <code>${MACHINE_ARCH} ==
    <li>Do NOT generate shared libraries for <code>${MACHINE_ARCH} ==  
        alpha</code>         alpha</code>
    <li>In OpenBSD <code>curses.h/libcurses/libtermlib</code> are the     <li>In OpenBSD <code>curses.h/libcurses/libtermlib</code> are the
        ``new curses''.  Change:<br>         ``new curses''.  Change:<br>
        <code>ncurses.h ==> curses.h</code><br>         <code>ncurses.h ==&gt; curses.h</code><br>
        <code>-lncurses ==> -lcurses</code><br>         <code>-lncurses ==&gt; -lcurses</code><br>
        ``old (BSD) curses'' is available by defining <code>_USE_OLD_CURSES_</code>         ``old (BSD) curses'' is available by defining
          <code>_USE_OLD_CURSES_</code>
        before including <code>curses.h</code> (usually in a Makefile) and         before including <code>curses.h</code> (usually in a Makefile) and
        linking with <code>-lcurses</code>.         linking with <code>-locurses</code>.
    <li>In OpenBSD, terminal discipline has been upgraded from the older BSD     <li>In OpenBSD, terminal discipline has been upgraded from the older BSD
        <code>sgtty</code> to the newer POSIX <code>tcgetattr</code> family.         <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>         Avoid the older style in new code.  Some code may define
        to be a synonym for the older <code>sgtty</code>, but this is at best a stopgap         <code>tcgetattr</code> to be a synonym for the older
        measure on OpenBSD.  The <code>xterm</code> source code is a very good example of         <code>sgtty</code>, but this is at best a stopgap measure on OpenBSD.
        what not to do.         The <code>xterm</code> source code is a very good example of
        Try to get your system functionality right: you want a type that remembers         what not to do.  Try to get your system functionality right: you
        the state of your terminal (possible typedef), you want a function that         want a type that remembers the state of your terminal
        extracts the current state, and a function that sets the new state.         (possible typedef), you want a function that extracts the current
        Functions that modify this state are more difficult, as they tend to vary         state, and a function that sets the new state.
        depending upon the system.  Also, don't forget that you will have to handle         Functions that modify this state are more difficult, as they tend
        cases where you are not connected to the terminal, and that you need to         to vary depending upon the system.  Also, don't forget that you will
        handle signals: not only termination, but also getting put in the background         have to handle cases where you are not connected to a terminal,
        you should leave your terminal in a sane state.  Do your tests under an         and that you need to handle signals: not only termination, but
        older shell, such as sh, which does not reset the terminal in any way at         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.         program's termination.
    <li>The newer termcap/terminfo and curses, as included with OpenBSD, include standard sequences     <li>The newer termcap/terminfo and curses, as included with OpenBSD,
        for controlling color terminals.  You should use these if possible, reverting         include standard sequences for controlling color terminals.  You
        to standard ANSI color sequences on other systems.  However, some terminal descriptions         should use these if possible, reverting to standard ANSI color
        have not been updated yet, and you may need to be able to specify these sequences manually.         sequences on other systems.  However, some terminal descriptions
        This is the way vim5.1 handles it.  This is not strictly necessary. Except for privileged         have not been updated yet, and you may need to be able to specify
        programs, it is generally possible to override a termcap definition through the         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.         <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>     <li>Signal semantics are tricky, and vary from one system to another.
        to ensure a specific semantics, along with other system calls referenced in its manpage.         Use <code>sigaction</code> to ensure a specific semantics, along
          with other system calls referenced in the corresponding  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.14  
changed lines
  Added in v.1.15