diff --git a/en_US.ISO8859-1/articles/java-tomcat/article.sgml b/en_US.ISO8859-1/articles/java-tomcat/article.sgml
index cbe4aa2fcf..de13705e13 100644
--- a/en_US.ISO8859-1/articles/java-tomcat/article.sgml
+++ b/en_US.ISO8859-1/articles/java-tomcat/article.sgml
@@ -1,615 +1,615 @@
%man;
%trademarks;
]>
&java; and Jakarta Tomcat on FreeBSDVictoriaChanvkchan@kendryl.netHitenPandyahmp@FreeBSD.org200220032004Victoria ChanHiten Pandya$FreeBSD$
&tm-attrib.freebsd;
&tm-attrib.cvsup;
&tm-attrib.linux;
&tm-attrib.microsoft;
&tm-attrib.sun;
&tm-attrib.general;
This document is presented in hopes of making it easier for
anyone that needs to get &java; up and running on FreeBSD, with the
least amount of aggravation. Plan on spending a whole day on such
a project as it will take time to assemble all the pieces and
compile them individually, and then as a whole. It also shows how
to install the famous Jakarta Tomcat Servlet and &jsp; container on
the FreeBSD operating system.IntroductionThe &java; programming language was birthed on May 23rd
1995. One would expect that after all this time, &java;
applications would be easy to install and ready to run from a single
package, or port on FreeBSD, thus making it available for the
masses. This is not the case, unfortunately, as
the &java; distribution is held very closely by Sun Microsystems,
and prohibits re-distribution. All &java; Applets must be compiled
from source code, together with the &java; Development Kit from Sun
Microsystems. All these ingredients must be blended together in
the right order, assembled, and compiled by the end user. With
such distribution philosophies at heart, it is my opinion that
&java; will always be developer or hacker use only. I certainly
found this to be true when I needed to serve up some
.jsp pages for a client on my web server,
and needed to get www/jakarta-tomcat4 to work with
www/apache13 on my FreeBSD
system.The Tomcat portion of the install is very straight forward, but
the difficulty I had was getting &java; Development Kit up and
running for FreeBSD 4.X, as Sun Microsystems only supplies
Binaries for Linux, &solaris;, and &windowsnt;. This means that I
had to compile my own &jdk; for FreeBSD. I began by searching for
documentation on the Internet. I quickly found that there is more
source code than I need along with patches to the source code, but
very little documentation of what to do after obtaining
everything.In this article, you will find how to install the &java;
Development Kit for FreeBSD, and how to get up and running with
Tomcat. A section is also provided for
further reading.The &java; EnvironmentEnsure that you have the current ports collection as
make it will fail if it attempts to build older
source. You can upgrade your entire ports collection by using
CVSup. See Using CVSup section
of the Handbook for more information. You can also download the
ports you need manually from to
get you going.You will need the Linux Emulation
(Linux-ABI) enabled in your kernel configuration. Simply add
the following option to your kernel configuration file and
recompile it. Instructions for building a kernel can be found
in the FreeBSD
Handbook.options COMPAT_LINUXThe above option will add Linux-ABI support to your
kernel, when it is recompiled.The list of dependencies below, are required to be installed
manually in a certain order. Dependencies that are automatically
downloaded are not listed here.java/jdk13java/linux-jdk13You will need to get the following:Download bsd-jdk131-patches-9.tar.gz
from
and place it under /usr/ports/distfiles.Next get out your web browser and head on over to
and find SDK downloads. Click on the continue
button below GNUZIP Tar Shell Script. Be sure
you read every word of the license page before you click on
the Accept button! You will be brought to a
page titled Download Java(TM) 2 SDK, Standard Edition
1.3.1_10. Scroll to the bottom and click on the
HTTP download button. When the File
Download box comes up, be sure to click on the
Open button rather than the Save
button. You will be presented with another File
Download box - this time choose Save
and you will be able to save
j2sdk-1_3_1_10-linux-i386.bin.
Place it in /usr/ports/distfiles.Go to .
In the table under Produce Description,
named Java 2 SDK 1.3.1, go to the
right-hand cell and click download. You will
be taken to the Sign On page, where you must
sign in if you already have an account, or register for
access. Once you have signed on, you will be taken to the
Legal page, where you must accept the license
agreement; scroll down (reading the license) and click on the
Continue button. Next page, is the
Receipt page. This is where you will save your
order number. You will be able to choose the location that is
nearest to you. Click on Java 2 SDK, Standard Edition,
version 1.3.1. Save the
j2sdk-1_3_1-src.tar.gz to the
/usr/ports/distfiles/ directory.It is very important for you to read the License Agreement
which has been issued by Sun Microsystems Corp. There are
several restrictions in place on the use of &java;, which you must
address. The FreeBSD Project does not take any responsibilities
for your actions.Do not discard any of the downloaded files, as they will be
needed for building some of the native ports for FreeBSD, which
are discussed later on.Now that you have assembled all the source files and ports,
you need to start by building java/linux-jdk13:&prompt.root; cd /usr/ports/java/linux-jdk13
&prompt.root; make all install cleanOnce you have built java/linux-jdk13, you need to test it, to
make sure it works as intended. To do that:&prompt.root; cd /usr/local/linux-jdk1.3.1/bin
&prompt.root; ./java -versionThe output of the above command should be as follows:java version "1.3.1_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_10-b02)
Classic VM (build 1.3.1_02-b02, green threads, nojit)If you did not get the correct response, you need to:&prompt.root; cd /usr/ports/java/linux-jdk13
&prompt.root; make deinstallAnd make sure that /usr/local does not
contain a linux-jdk1.3.1 directory. If you
find a fragment of the directory, delete it. Repeat the
build and install process for java/linux-jdk13.To make the native Java Development Kit
1.3.1 for FreeBSD, do the following:Make sure you have the
j2sdk-1_3_1-src.tar.gz file in your
/usr/ports/distfiles. This file is needed
for applying the patch-set discussed below.You will need to download the patch set
for building the port. The patch-set file is called
bsd-jdk131-patches-9.tar.gz. You should
also make sure the integrity of the files by matching it with
the following MD5 checksum.
MD5 (bsd-jdk131-patches-9.tar.gz) = 29c83880d3555abcf74fc7df9db1959fThe patch-set is available from: The last procedure discussed above (building the native
&jdk;) will take some time.Jakarta Tomcat SetupOverview&java; is becoming an even more popular for making diverse
and scalable platform independent solutions. One of the most
growing needs of &java; is in the ASP (Application
Service Provider) market. &java; serves as the perfect
solution for these types of markets, with the following
advantages:Platform IndependenceIndustry Wide CommitmentScalabilityReliable PerformanceDistributed, Multi-threaded, Secure etc.A very important and growing technology which has emerged
from &java; is &jsp; (&javaserver.pages;).&jsp; (&javaserver.pages;) is a server-side
technology introduced by Sun Microsystems
Corp., which provides a quick simple way to generate
dynamic content from within HTML pages. It
uses XML tags along with &java; scriptlets to
encapsulate and separate the logic from the design and display.
When a &jsp; page is invoked, it is dynamically
converted into a Servlet and processed by the server to produce
the resulting HTML/XML page for the client.
When &jsp; is used in conjunction with
JavaBeans, it is possible to produce very diverse and scalable
applications, which may be combined with the strength and
performance of FreeBSD.Tomcat is an open-source
implementation of the &java; Servlets and &javaserver.pages;
technologies, developed under the Jakarta project at the Apache
Software Foundation. Tomcat implements a new Servlet framework
(called Catalina) that is based on completely new architecture
with the Servlet 2.3 and &jsp; 1.2
specifications. It includes many additional features that make
it a useful platform for developing and deploying web
applications and web services. In a nutshell, Tomcat is an
application server written in 100% Pure &java;.Tomcat is used for many purposes, and is not limited to
Application Servers. It provides an open platform to develop
extensible web and content management services. When Tomcat is
used with an optimized FreeBSD system, it can provide highly
reliable and fast pacing services.Please refer to the section for more
information on Tomcat and &jsp;. The next
section will demonstrate how to build the Tomcat
Environment for FreeBSD. The version of Tomcat used in
this guide is 4.0.6. This version contains
major bug fixes, and the following updates/changes:JSP 1.2 SpecificationJava Servlet 2.3 SpecificationFull backward compatibility with the Java Servlet
2.2 and JSP 1.1 SpecificationThe Tomcat environment for FreeBSDIt is very simple to install Tomcat on a FreeBSD machine,
after setting up the necessary &java; environment, which we have
previously completed.In-order to set up Tomcat on FreeBSD, follow the below
procedure:Follow the above steps to set up the necessary &java;
environment.Set an environment variable JAVA_HOME
which, points to the directory where you have installed the
&jdk; (the examples below point to a native build of the
&jdk;). If you are using &man.sh.1; as your shell, you can set
JAVA_HOME with:&prompt.root; export JAVA_HOME="/usr/local/jdk1.3.1"Those who use &man.csh.1; or a compatible shell, must use a
slightly different command:&prompt.root; setenv JAVA_HOME /usr/local/jdk1.3.1This environment variable should be made permanent by
adding it into either .profile or
.cshrc, depending on the shell you are
using. This variable is very crucial for the functioning of
all the &java; based programs, including Tomcat itself.Download the Tomcat binary distribution
from the Jakarta website, which is located at
. The
file to download is called
jakarta-tomcat-4.0.6.tar.gz.The compressed and archived file we downloaded in the
previous step uses special GNU Extensions.
In-order to untar and uncompress the file, we will need to
install GNU Tar (archivers/gtar), by
doing the following:&prompt.root; cd /usr/ports/archivers/gtar && make all install cleanUn-tar and Un-compress the
jakarta-tomcat-4.0.6.tar.gz file into
the /usr/local directory and rename the
directory to tomcat-4.0 for ease of
reference:&prompt.root; cd /usr/local
&prompt.root; gtar zxvf jakarta-tomcat-4.0.6.tar.gz
&prompt.root; ls jakarta*
jakarta-tomcat-4.0.6
&prompt.root; mv jakarta-tomcat-4.0.6 tomcat-4.0You can remove the
jakarta-tomcat-4.0.6.tar.gz at your
preference.Installation by using the source code is currently
out of scope for this document. Please refer to the following
files for addition information on building from source,
available from your Tomcat distribution
directory:/usr/local/tomcat-4.0/README.txt/usr/local/tomcat-4.0/BUILDING.txtOperating Tomcat - BasicsNow that we have finished installing Tomcat. The following
example shows how to start the Tomcat server:&prompt.root; cd /usr/local/tomcat-4.0/bin
&prompt.root; ./startup.sh (for starting Tomcat)You can test if your Tomcat server has started by visiting
the following URL: http://127.0.0.1:8080 or
http://localhost:8080. To stop
Tomcat:&prompt.root; cd /usr/local/tomcat-4.0/bin
&prompt.root; ./shutdown.sh(for stopping Tomcat)The startup.sh and
shutdown.sh are frontends to the
catalina.sh executable script in the same
directory; if you would like to start Tomcat automatically at
boot-time run:&prompt.root; cd /usr/local/etc/rc.d
&prompt.root; ln -s /usr/local/tomcat-4.0/bin/catalina.shEdit the catalina.sh, and add the
following at the beginning of the file (after the comment
box):JAVA_HOME=/usr/local/jdk1.3.1If your port 8080 is occupied by some other
service, you can change it by editing the
server.xml in your Tomcat's
conf/ directory. In the example below, the
port will be changed to 80, assuming there is no service running
on that port.&prompt.root; cd /usr/local/tomcat-4.0/conf
&prompt.root; fgrep -n 8080 server.xml
~65: By default, a non-SSL HTTP/1.1 Connector is established on port 8080.
~89: port="8080" minProcessors="5" maxProcessors="75"
&prompt.root; cat server.xml | sed s/8080/80/ > server.xml.new
&prompt.root; mv server.xml.new server.xmlReference
-
+ The FreeBSD &java; ProjectJavaSoft. Home of &java;The
Sun Community Source Licensing for &java;Jakarta Tomcat HomepageJ2SE
DocumentationFreeBSD Ports - &java;
SectionConclusionFinally, we are at the end of the article and have a working
version of Tomcat. We hope that you have learned the basics of
installing and building the &java; Development Kit on FreeBSD,
along with installation of the Tomcat binary distribution
application server released by the Apache Software Foundation.
The section contains pointers to additional
resources on this topic, some which are in print, some which are
on the World Wide Web, or both.The most important thing is drive space. I suggest having
700MB or more free space in
/usr. I hope this article has helped you
in some small way. For questions, comments, compliments, or
rants, please direct them to the authors.
diff --git a/en_US.ISO8859-1/books/arch-handbook/boot/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/boot/chapter.sgml
index 91c6dc0547..572cc8af4f 100644
--- a/en_US.ISO8859-1/books/arch-handbook/boot/chapter.sgml
+++ b/en_US.ISO8859-1/books/arch-handbook/boot/chapter.sgml
@@ -1,1024 +1,1024 @@
SergeyLyubkaContributed by Bootstrapping and kernel initializationSynopsisThis chapter is an overview of the boot and system
initialization process, starting from the BIOS (firmware) POST,
to the first user process creation. Since the initial steps of
system startup are very architecture dependent, the IA-32
architecture is used as an example.OverviewA computer running FreeBSD can boot by several methods,
although the most common method, booting from a harddisk where
the OS is installed, will be discussed here. The boot process
is divided into several steps:BIOS POSTboot0 stageboot2 stageloader stagekernel initializationThe boot0 and boot2
stages are also referred to as bootstrap stages 1 and
2 in &man.boot.8; as the first steps in FreeBSD's
3-stage bootstrapping procedure. Various information is printed
on the screen at each stage, so you may visually recognize them
using the table that follows. Please note that the actual data
may differ from machine to machine:
-
+ may varyBIOS (firmware) messagesF1 FreeBSD
F2 BSD
F5 Disk 2boot0>>FreeBSD/i386 BOOT
Default: 1:ad(1,a)/boot/loader
boot:boot2This
prompt will appear if the user presses a key just after
selecting an OS to boot at the boot0
stage.BTX loader 1.0 BTX version is 1.01
BIOS drive A: is disk0
BIOS drive C: is disk1
BIOS 639kB/64512kB available memory
FreeBSD/i386 bootstrap loader, Revision 0.8
Console internal video/keyboard
(jkh@bento.freebsd.org, Mon Nov 20 11:41:23 GMT 2000)
/kernel text=0x1234 data=0x2345 syms=[0x4+0x3456]
Hit [Enter] to boot immediately, or any other key for command prompt
Booting [kernel] in 9 seconds..._loaderCopyright (c) 1992-2002 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD 4.6-RC #0: Sat May 4 22:49:02 GMT 2002
devnull@kukas:/usr/obj/usr/src/sys/DEVNULL
Timecounter "i8254" frequency 1193182 HzkernelBIOS POSTWhen the PC powers on, the processor's registers are set
to some predefined values. One of the registers is the
instruction pointer register, and its value
after a power on is well defined: it is a 32-bit value of
0xfffffff0. The instruction pointer register points to code to
be executed by the processor. One of the registers is the
cr1 32-bit control register, and its value
just after the reboot is 0. One of the cr1's bits, the bit PE
(Protected Enabled) indicates whether the processor is running
in protected or real mode. Since at boot time this bit is
cleared, the processor boots in real mode. Real mode means,
among other things, that linear and physical addresses are
identical.The value of 0xfffffff0 is slightly less then 4Gb, so unless
the machine has 4Gb physical memory, it cannot point to a valid
memory address. The computer's hardware translates this address
so that it points to a BIOS memory block.BIOS stands for Basic Input Output
System, and it is a chip on the motherboard that has
a relatively small amount of read-only memory (ROM). This
memory contains various low-level routines that are specific to
the hardware supplied with the motherboard. So, the processor
will first jump to the address 0xfffffff0, which really resides
in the BIOS's memory. Usually this address contains a jump
instruction to the BIOS's POST routines.POST stands for Power On Self Test.
This is a set of routines including the memory check, system bus
check and other low-level stuff so that the CPU can initialize
the computer properly. The important step on this stage is
determining the boot device. All modern BIOS's allow the boot
device to be set manually, so you can boot from a floppy,
CD-ROM, harddisk etc.The very last thing in the POST is the INT
0x19 instruction. That instruction reads 512 bytes
from the first sector of boot device into the memory at address
0x7c00. The term first sector originates
from harddrive architecture, where the magnetic plate is divided
to a number of cylindrical tracks. Tracks are numbered, and
every track is divided by a number (usually 64) sectors. Track
number 0 is the outermost on the magnetic plate, and sector 1,
the first sector (tracks, or, cylinders, are numbered starting
from 0, but sectors - starting from 1), has a special meaning.
It is also called Master Boot Record, or MBR. The remaining
sectors on the first track are never used Some
utilities such as &man.disklabel.8; may store the information in
this area, mostly in the second
sector..boot0 stageTake a look at the file /boot/boot0.
This is a small 512-byte file, and it is exactly what FreeBSD's
installation procedure wrote to your harddisk's MBR if you chose
the bootmanager option at installation time.As mentioned previously, the INT 0x19
instruction loads an MBR, i.e. the boot0
content, into the memory at address 0x7c00. Taking a look at
the file sys/boot/i386/boot0/boot0.s can
give a guess at what is happening there - this is the boot
manager, which is an awesome piece of code written by Robert
Nordier.The MBR, or, boot0, has a special
structure starting from offset 0x1be, called the
partition table. It has 4 records of 16
bytes each, called partition records, which
represent how the harddisk(s) are partitioned, or, in FreeBSD's
terminology, sliced. One byte of those 16 says whether a
partition (slice) is bootable or not. Exactly one record must
have that flag set, otherwise boot0's code
will refuse to proceed.A partition record has the following fields:the 1-byte filesystem typethe 1-byte bootable flagthe 6 byte descriptor in CHS formatthe 8 byte descriptor in LBA formatA partition record descriptor has the information about
where exactly the partition resides on the drive. Both
descriptors, LBA and CHS, describe the same information, but in
different ways: LBA (Logical Block Addressing) has the starting
sector for the partition and the partition's length, while CHS
(Cylinder Head Sector) has coordinates for the first and last
sectors of the partition.The boot manager scans the partition table and prints the
menu on the screen so the user can select what disk and what
slice to boot. By pressing an appropriate key,
boot0 performs the following
actions:modifies the bootable flag for the selected partition to
make it bootable, and clears the previoussaves itself to disk to remember what partition (slice)
has been selected so to use it as the default on the next
bootloads the first sector of the selected partition (slice)
into memory and jumps thereWhat kind of data should reside on the very first sector of
a bootable partition (slice), in our case, a FreeBSD slice? As
you may have already guessed, it is
boot2.boot2 stageYou might wonder, why boot2 comes after
boot0, and not boot1. Actually, there is a
512-byte file called boot1 in the directory
/boot as well. It is used for booting from
a floppy. When booting from a floppy,
boot1 plays the same role as
boot0 for a harddisk: it locates
boot2 and runs it.You may have realized that a file
/boot/mbr exists as well. It is a
simplified version of boot0. The code in
mbr does not provide a menu for the user,
it just blindly boots the partition marked active.The code implementing boot2 resides in
sys/boot/i386/boot2/, and the executable
itself is in /boot. The files
boot0 and boot2 that
are in /boot are not used by the bootstrap,
but by utilities such as boot0cfg.
The actual position for boot0 is in the
MBR. For boot2 it is the beginning of a
bootable FreeBSD slice. These locations are not under the
filesystem's control, so they are invisible to commands like
ls.The main task for boot2 is to load the
file /boot/loader, which is the third stage
in the bootstrapping procedure. The code in
boot2 cannot use any services like
open() and read(),
since the kernel is not yet loaded. It must scan the harddisk,
knowing about the filesystem structure, find the file
/boot/loader, read it into memory using a
BIOS service, and then pass the execution to the loader's entry
point.Besides that, boot2 prompts for user
input so the loader can be booted from different disk, unit,
slice and partition.The boot2 binary is created in special
way:sys/boot/i386/boot2/Makefile
boot2: boot2.ldr boot2.bin ${BTX}/btx/btx
btxld -v -E ${ORG2} -f bin -b ${BTX}/btx/btx -l boot2.ldr \
-o boot2.ld -P 1 boot2.binThis Makefile snippet shows that &man.btxld.8; is used to
link the binary. BTX, which stands for BooT eXtender, is a
piece of code that provides a protected mode environment for the
program, called the client, that it is linked with. So
boot2 is a BTX client, i.e. it uses the
service provided by BTX.The btxld utility is the linker.
It links two binaries together. The difference between
&man.btxld.8; and &man.ld.1; is that
ld usually links object files into a
shared object or executable, while
btxld links an object file with the
BTX, producing the binary file suitable to be put on the
beginning of the partition for the system boot.boot0 passes the execution to BTX's entry
point. BTX then switches the processor to protected mode, and
prepares a simple environment before calling the client. This
includes:virtual v86 mode. That means, the BTX is a v86
monitor. Real mode instructions like pushf, popf, cli, sti, if
called by the client, will work.Interrupt Descriptor Table (IDT) is set up so
all hardware interrupts are routed to the default BIOS's
handlers, and interrupt 0x30 is set up to be the syscall
gate.Two system calls: exec and
exit, are defined:sys/boot/i386/btx/lib/btxsys.s:
.set INT_SYS,0x30 # Interrupt number
#
# System call: exit
#
__exit: xorl %eax,%eax # BTX system
int $INT_SYS # call 0x0
#
# System call: exec
#
__exec: movl $0x1,%eax # BTX system
int $INT_SYS # call 0x1BTX creates a Global Descriptor Table (GDT):sys/boot/i386/btx/btx/btx.s:
gdt: .word 0x0,0x0,0x0,0x0 # Null entry
.word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
.word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
.word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
.word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
.word 0xffff,MEM_USR,0xfa00,0xcf# SEL_UCODE
.word 0xffff,MEM_USR,0xf200,0xcf# SEL_UDATA
.word _TSSLM,MEM_TSS,0x8900,0x0 # SEL_TSSThe client's code and data start from address MEM_USR
(0xa000), and a selector (SEL_UCODE) points to the client's code
segment. The SEL_UCODE descriptor has Descriptor Privilege
Level (DPL) 3, which is the lowest privilege level. But the
INT 0x30 instruction handler resides in a
segment pointed to by the SEL_SCODE (supervisor code) selector,
as shown from the code that creates an IDT: mov $SEL_SCODE,%dh # Segment selector
init.2: shr %bx # Handle this int?
jnc init.3 # No
mov %ax,(%di) # Set handler offset
mov %dh,0x2(%di) # and selector
mov %dl,0x5(%di) # Set P:DPL:type
add $0x4,%ax # Next handlerSo, when the client calls __exec(), the
code will be executed with the highest privileges. This allows
the kernel to change the protected mode data structures, such as
page tables, GDT, IDT, etc later, if needed.boot2 defines an important structure,
struct bootinfo. This structure is
initialized by boot2 and passed to the
loader, and then further to the kernel. Some nodes of this
structures are set by boot2, the rest by the
loader. This structure, among other information, contains the
kernel filename, BIOS harddisk geometry, BIOS drive number for
boot device, physical memory available, envp
pointer etc. The definition for it is:/usr/include/machine/bootinfo.h
struct bootinfo {
u_int32_t bi_version;
u_int32_t bi_kernelname; /* represents a char * */
u_int32_t bi_nfs_diskless; /* struct nfs_diskless * */
/* End of fields that are always present. */
#define bi_endcommon bi_n_bios_used
u_int32_t bi_n_bios_used;
u_int32_t bi_bios_geom[N_BIOS_GEOM];
u_int32_t bi_size;
u_int8_t bi_memsizes_valid;
u_int8_t bi_bios_dev; /* bootdev BIOS unit number */
u_int8_t bi_pad[2];
u_int32_t bi_basemem;
u_int32_t bi_extmem;
u_int32_t bi_symtab; /* struct symtab * */
u_int32_t bi_esymtab; /* struct symtab * */
/* Items below only from advanced bootloader */
u_int32_t bi_kernend; /* end of kernel space */
u_int32_t bi_envp; /* environment */
u_int32_t bi_modulep; /* preloaded modules */
};boot2 enters into an infinite loop waiting
for user input, then calls load(). If the
user does not press anything, the loop brakes by a timeout, so
load() will load the default file
(/boot/loader). Functions ino_t
lookup(char *filename) and int xfsread(ino_t
inode, void *buf, size_t nbyte) are used to read the
content of a file into memory. /boot/loader
is an ELF binary, but where the ELF header is prepended with
a.out's struct exec structure.
load() scans the loader's ELF header, loading
the content of /boot/loader into memory, and
passing the execution to the loader's entry:sys/boot/i386/boot2/boot2.c:
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
MAKEBOOTDEV(dev_maj[dsk.type], 0, dsk.slice, dsk.unit, dsk.part),
0, 0, 0, VTOP(&bootinfo));loader stageloader is a BTX client as well.
I will not describe it here in detail, there is a comprehensive
manpage written by Mike Smith, &man.loader.8;. The underlying
mechanisms and BTX were discussed above.The main task for the loader is to boot the kernel. When
the kernel is loaded into memory, it is being called by the
loader:sys/boot/common/boot.c:
/* Call the exec handler from the loader matching the kernel */
module_formats[km->m_loader]->l_exec(km);Kernel initializationTo where exactly is the execution passed by the loader,
i.e. what is the kernel's actual entry point. Let us take a
look at the command that links the kernel:sys/conf/Makefile.i386:
ld -elf -Bdynamic -T /usr/src/sys/conf/ldscript.i386 -export-dynamic \
-dynamic-linker /red/herring -o kernel -X locore.o \
<lots of kernel .o files>A few interesting things can be seen in this line. First,
the kernel is an ELF dynamically linked binary, but the dynamic
linker for kernel is /red/herring, which is
definitely a bogus file. Second, taking a look at the file
sys/conf/ldscript.i386 gives an idea about
what ld options are used when
compiling a kernel. Reading through the first few lines, the
stringsys/conf/ldscript.i386:
ENTRY(btext)says that a kernel's entry point is the symbol `btext'.
This symbol is defined in locore.s:sys/i386/i386/locore.s:
.text
/**********************************************************************
*
* This is where the bootblocks start us, set the ball rolling...
*
*/
NON_GPROF_ENTRY(btext)First what is done is the register EFLAGS is set to a
predefined value of 0x00000002, and then all the segment
registers are initialized:sys/i386/i386/locore.s
/* Don't trust what the BIOS gives for eflags. */
pushl $PSL_KERNEL
popfl
/*
* Don't trust what the BIOS gives for %fs and %gs. Trust the bootstrap
* to set %cs, %ds, %es and %ss.
*/
mov %ds, %ax
mov %ax, %fs
mov %ax, %gsbtext calls the routines
recover_bootinfo(),
identify_cpu(),
create_pagetables(), which are also defined
in locore.s. Here is a description of what
they do:
-
+ recover_bootinfoThis routine parses the parameters to the kernel
passed from the bootstrap. The kernel may have been
booted in 3 ways: by the loader, described above, by the
old disk boot blocks, and by the old diskless boot
procedure. This function determines the booting method,
and stores the struct bootinfo
structure into the kernel memory.identify_cpuThis functions tries to find out what CPU it is
running on, storing the value found in a variable
_cpu.create_pagetablesThis function allocates and fills out a Page Table
Directory at the top of the kernel memory area.The next steps are enabling VME, if the CPU supports
it: testl $CPUID_VME, R(_cpu_feature)
jz 1f
movl %cr4, %eax
orl $CR4_VME, %eax
movl %eax, %cr4Then, enabling paging:/* Now enable paging */
movl R(_IdlePTD), %eax
movl %eax,%cr3 /* load ptd addr into mmu */
movl %cr0,%eax /* get control word */
orl $CR0_PE|CR0_PG,%eax /* enable paging */
movl %eax,%cr0 /* and let's page NOW! */The next three lines of code are because the paging was set,
so the jump is needed to continue the execution in virtualized
address space: pushl $begin /* jump to high virtualized address */
ret
/* now running relocated at KERNBASE where the system is linked to run */
begin:The function init386() is called, with
a pointer to the first free physical page, after that
mi_startup(). init386
is an architecture dependent initialization function, and
mi_startup() is an architecture independent
one (the 'mi_' prefix stands for Machine Independent). The
kernel never returns from mi_startup(), and
by calling it, the kernel finishes booting:sys/i386/i386/locore.s:
movl physfree, %esi
pushl %esi /* value of first for init386(first) */
call _init386 /* wire 386 chip for unix operation */
call _mi_startup /* autoconfiguration, mountroot etc */
hlt /* never returns to here */init386()init386() is defined in
sys/i386/i386/machdep.c and performs
low-level initialization, specific to the i386 chip. The
switch to protected mode was performed by the loader. The
loader has created the very first task, in which the kernel
continues to operate. Before running straight away to the
code, I will enumerate the tasks the processor must complete
to initialize protected mode execution:Initialize the kernel tunable parameters, passed from
the bootstrapping program.Prepare the GDT.Prepare the IDT.Initialize the system console.Initialize the DDB, if it is compiled into
kernel.Initialize the TSS.Prepare the LDT.Set up proc0's pcb.What init386() first does is
initialize the tunable parameters passed from bootstrap. This
is done by setting the environment pointer (envp) and calling
init_param1(). The envp pointer has been
passed from loader in the bootinfo
structure:sys/i386/i386/machdep.c:
kern_envp = (caddr_t)bootinfo.bi_envp + KERNBASE;
/* Init basic tunables, hz etc */
init_param1();init_param1() is defined in
sys/kern/subr_param.c. That file has a
number of sysctls, and two functions,
init_param1() and
init_param2(), that are called from
init386():sys/kern/subr_param.c
hz = HZ;
TUNABLE_INT_FETCH("kern.hz", &hz);TUNABLE_<typename>_FETCH is used to fetch the value
from the environment:/usr/src/sys/sys/kernel.h
#define TUNABLE_INT_FETCH(path, var) getenv_int((path), (var))
Sysctl kern.hz is the system clock tick. Along with
this, the following sysctls are set by
init_param1(): kern.maxswzone,
kern.maxbcache, kern.maxtsiz, kern.dfldsiz, kern.dflssiz,
kern.maxssiz, kern.sgrowsiz.Then init386() prepares the Global
Descriptors Table (GDT). Every task on an x86 is running in
its own virtual address space, and this space is addressed by
a segment:offset pair. Say, for instance, the current
instruction to be executed by the processor lies at CS:EIP,
then the linear virtual address for that instruction would be
the virtual address of code segment CS + EIP. For
convenience, segments begin at virtual address 0 and end at a
4Gb boundary. Therefore, the instruction's linear virtual
address for this example would just be the value of EIP.
Segment registers such as CS, DS etc are the selectors,
i.e. indexes, into GDT (to be more precise, an index is not a
selector itself, but the INDEX field of a selector).
FreeBSD's GDT holds descriptors for 15 selectors per
CPU:sys/i386/i386/machdep.c:
union descriptor gdt[NGDT * MAXCPU]; /* global descriptor table */
sys/i386/include/segments.h:
/*
* Entries in the Global Descriptor Table (GDT)
*/
#define GNULL_SEL 0 /* Null Descriptor */
#define GCODE_SEL 1 /* Kernel Code Descriptor */
#define GDATA_SEL 2 /* Kernel Data Descriptor */
#define GPRIV_SEL 3 /* SMP Per-Processor Private Data */
#define GPROC0_SEL 4 /* Task state process slot zero and up */
#define GLDT_SEL 5 /* LDT - eventually one per process */
#define GUSERLDT_SEL 6 /* User LDT */
#define GTGATE_SEL 7 /* Process task switch gate */
#define GBIOSLOWMEM_SEL 8 /* BIOS low memory access (must be entry 8) */
#define GPANIC_SEL 9 /* Task state to consider panic from */
#define GBIOSCODE32_SEL 10 /* BIOS interface (32bit Code) */
#define GBIOSCODE16_SEL 11 /* BIOS interface (16bit Code) */
#define GBIOSDATA_SEL 12 /* BIOS interface (Data) */
#define GBIOSUTIL_SEL 13 /* BIOS interface (Utility) */
#define GBIOSARGS_SEL 14 /* BIOS interface (Arguments) */Note that those #defines are not selectors themselves, but
just a field INDEX of a selector, so they are exactly the
indices of the GDT. for example, an actual selector for the
kernel code (GCODE_SEL) has the value 0x08.The next step is to initialize the Interrupt Descriptor
Table (IDT). This table is to be referenced by the processor
when a software or hardware interrupt occurs. For example, to
make a system call, user application issues the INT
0x80 instruction. This is a software interrupt, so
the processor's hardware looks up a record with index 0x80 in
the IDT. This record points to the routine that handles this
interrupt, in this particular case, this will be the kernel's
syscall gate. The IDT may have a maximum of 256 (0x100)
records. The kernel allocates NIDT records for the IDT, where
NIDT is the maximum (256):sys/i386/i386/machdep.c:
static struct gate_descriptor idt0[NIDT];
struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */
For each interrupt, an appropriate handler is set. The
syscall gate for INT 0x80 is set as
well:sys/i386/i386/machdep.c:
setidt(0x80, &IDTVEC(int0x80_syscall),
SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));So when a userland application issues the INT
0x80 instruction, control will transfer to the
function _Xint0x80_syscall, which is in
the kernel code segment and will be executed with supervisor
privileges.Console and DDB are then initialized:sys/i386/i386/machdep.c:
cninit();
/* skipped */
#ifdef DDB
kdb_init();
if (boothowto & RB_KDB)
Debugger("Boot flags requested debugger");
#endifThe Task State Segment is another x86 protected mode
structure, the TSS is used by the hardware to store task
information when a task switch occurs.The Local Descriptors Table is used to reference userland
code and data. Several selectors are defined to point to the
LDT, they are the system call gates and the user code and data
selectors:/usr/include/machine/segments.h
#define LSYS5CALLS_SEL 0 /* forced by intel BCS */
#define LSYS5SIGR_SEL 1
#define L43BSDCALLS_SEL 2 /* notyet */
#define LUCODE_SEL 3
#define LSOL26CALLS_SEL 4 /* Solaris >= 2.6 system call gate */
#define LUDATA_SEL 5
/* separate stack, es,fs,gs sels ? */
/* #define LPOSIXCALLS_SEL 5*/ /* notyet */
#define LBSDICALLS_SEL 16 /* BSDI system call gate */
#define NLDT (LBSDICALLS_SEL + 1)
Next, proc0's Process Control Block (struct
pcb) structure is initialized. proc0 is a
struct proc structure that describes a kernel
process. It is always present while the kernel is running,
therefore it is declared as global:sys/kern/kern_init.c:
struct proc proc0;The structure struct pcb is a part of a
proc structure. It is defined in
/usr/include/machine/pcb.h and has a
process's information specific to the i386 architecture, such as
registers values.mi_startup()This function performs a bubble sort of all the system
initialization objects and then calls the entry of each object
one by one:sys/kern/init_main.c:
for (sipp = sysinit; *sipp; sipp++) {
/* ... skipped ... */
/* Call function */
(*((*sipp)->func))((*sipp)->udata);
/* ... skipped ... */
}Although the sysinit framework is described in the
Developers' Handbook, I will discuss the internals of it.Every system initialization object (sysinit object) is
created by calling a SYSINIT() macro. Let us take as example an
announce sysinit object. This object prints
the copyright message:sys/kern/init_main.c:
static void
print_caddr_t(void *data __unused)
{
printf("%s", (char *)data);
}
SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)The subsystem ID for this object is SI_SUB_COPYRIGHT
(0x0800001), which comes right after the SI_SUB_CONSOLE
(0x0800000). So, the copyright message will be printed out
first, just after the console initialization.Let us take a look at what exactly the macro
SYSINIT() does. It expands to a
C_SYSINIT() macro. The
C_SYSINIT() macro then expands to a static
struct sysinit structure declaration with
another DATA_SET macro call:/usr/include/sys/kernel.h:
#define C_SYSINIT(uniquifier, subsystem, order, func, ident) \
static struct sysinit uniquifier ## _sys_init = { \ subsystem, \
order, \ func, \ ident \ }; \ DATA_SET(sysinit_set,uniquifier ##
_sys_init);
#define SYSINIT(uniquifier, subsystem, order, func, ident) \
C_SYSINIT(uniquifier, subsystem, order, \
(sysinit_cfunc_t)(sysinit_nfunc_t)func, (void *)ident)The DATA_SET() macro expands to a
MAKE_SET(), and that macro is the point where
the all sysinit magic is hidden:/usr/include/linker_set.h
#define MAKE_SET(set, sym) \
static void const * const __set_##set##_sym_##sym = &sym; \
__asm(".section .set." #set ",\"aw\""); \
__asm(".long " #sym); \
__asm(".previous")
#endif
#define TEXT_SET(set, sym) MAKE_SET(set, sym)
#define DATA_SET(set, sym) MAKE_SET(set, sym)In our case, the following declaration will occur:static struct sysinit announce_sys_init = {
SI_SUB_COPYRIGHT,
SI_ORDER_FIRST,
(sysinit_cfunc_t)(sysinit_nfunc_t) print_caddr_t,
(void *) copyright
};
static void const *const __set_sysinit_set_sym_announce_sys_init =
&announce_sys_init;
__asm(".section .set.sysinit_set" ",\"aw\"");
__asm(".long " "announce_sys_init");
__asm(".previous");The first __asm instruction will create
an ELF section within the kernel's executable. This will happen
at kernel link time. The section will have the name
.set.sysinit_set. The content of this section is one 32-bit
value, the address of announce_sys_init structure, and that is
what the second __asm is. The third
__asm instruction marks the end of a section.
If a directive with the same section name occurred before, the
content, i.e. the 32-bit value, will be appended to the existing
section, so forming an array of 32-bit pointers.Running objdump on a kernel
binary, you may notice the presence of such small
sections:&prompt.user; objdump -h /kernel
7 .set.cons_set 00000014 c03164c0 c03164c0 002154c0 2**2
CONTENTS, ALLOC, LOAD, DATA
8 .set.kbddriver_set 00000010 c03164d4 c03164d4 002154d4 2**2
CONTENTS, ALLOC, LOAD, DATA
9 .set.scrndr_set 00000024 c03164e4 c03164e4 002154e4 2**2
CONTENTS, ALLOC, LOAD, DATA
10 .set.scterm_set 0000000c c0316508 c0316508 00215508 2**2
CONTENTS, ALLOC, LOAD, DATA
11 .set.sysctl_set 0000097c c0316514 c0316514 00215514 2**2
CONTENTS, ALLOC, LOAD, DATA
12 .set.sysinit_set 00000664 c0316e90 c0316e90 00215e90 2**2
CONTENTS, ALLOC, LOAD, DATAThis screen dump shows that the size of .set.sysinit_set
section is 0x664 bytes, so 0x664/sizeof(void
*) sysinit objects are compiled into the kernel. The
other sections such as .set.sysctl_set
represent other linker sets.By defining a variable of type struct
linker_set the content of
.set.sysinit_set section will be collected
into that variable:sys/kern/init_main.c:
extern struct linker_set sysinit_set; /* XXX */The struct linker_set is defined as
follows:/usr/include/linker_set.h:
struct linker_set {
int ls_length;
void *ls_items[1]; /* really ls_length of them, trailing NULL */
};The first node will be equal to the number of a sysinit
objects, and the second node will be a NULL-terminated array of
pointers to them.Returning to the mi_startup()
discussion, it is must be clear now, how the sysinit objects are
being organized. The mi_startup() function
sorts them and calls each. The very last object is the system
scheduler:/usr/include/sys/kernel.h:
enum sysinit_sub_id {
SI_SUB_DUMMY = 0x0000000, /* not executed; for linker*/
SI_SUB_DONE = 0x0000001, /* processed*/
SI_SUB_CONSOLE = 0x0800000, /* console*/
SI_SUB_COPYRIGHT = 0x0800001, /* first use of console*/
...
SI_SUB_RUN_SCHEDULER = 0xfffffff /* scheduler: no return*/
};The system scheduler sysinit object is defined in the file
sys/vm/vm_glue.c, and the entry point for
that object is scheduler(). That function
is actually an infinite loop, and it represents a process with
PID 0, the swapper process. The proc0 structure, mentioned
before, is used to describe it.The first user process, called init, is
created by the sysinit object init:sys/kern/init_main.c:
static void
create_init(const void *udata __unused)
{
int error;
int s;
s = splhigh();
error = fork1(&proc0, RFFDG | RFPROC, &initproc);
if (error)
panic("cannot fork init: %d\n", error);
initproc->p_flag |= P_INMEM | P_SYSTEM;
cpu_set_fork_handler(initproc, start_init, NULL);
remrunqueue(initproc);
splx(s);
}
SYSINIT(init,SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)The create_init() allocates a new process
by calling fork1(), but does not mark it
runnable. When this new process is scheduled for execution by the
scheduler, the start_init() will be called.
That function is defined in init_main.c. It
tries to load and exec the init binary,
probing /sbin/init first, then
/sbin/oinit,
/sbin/init.bak, and finally
/stand/sysinstall:sys/kern/init_main.c:
static char init_path[MAXPATHLEN] =
#ifdef INIT_PATH
__XSTRING(INIT_PATH);
#else
"/sbin/init:/sbin/oinit:/sbin/init.bak:/stand/sysinstall";
#endif
diff --git a/en_US.ISO8859-1/books/arch-handbook/mac/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/mac/chapter.sgml
index 4a826bf9b2..1772a44bd0 100644
--- a/en_US.ISO8859-1/books/arch-handbook/mac/chapter.sgml
+++ b/en_US.ISO8859-1/books/arch-handbook/mac/chapter.sgml
@@ -1,7821 +1,7821 @@
ChrisCostelloTrustedBSD Projectchris@FreeBSD.orgRobertWatsonTrustedBSD Projectrwatson@FreeBSD.orgThe TrustedBSD MAC FrameworkMAC Documentation CopyrightThis documentation was developed for the FreeBSD Project by
Chris Costello at Safeport Network Services and Network
Associates Laboratories, the Security Research Division of
Network Associates, Inc. under DARPA/SPAWAR contract
N66001-01-C-8035 (CBOSS), as part of the DARPA
CHATS research program.Redistribution and use in source (SGML DocBook) and
'compiled' forms (SGML, HTML, PDF, PostScript, RTF and so forth)
with or without modification, are permitted provided that the
following conditions are met:Redistributions of source code (SGML DocBook) must
retain the above copyright notice, this list of conditions
and the following disclaimer as the first lines of this file
unmodified.Redistributions in compiled form (transformed to other
DTDs, converted to PDF, PostScript, RTF and other formats)
must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation
and/or other materials provided with the
distribution.THIS DOCUMENTATION IS PROVIDED BY THE NETWORKS ASSOCIATES
TECHNOLOGY, INC "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL NETWORKS ASSOCIATES TECHNOLOGY,
INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.SynopsisFreeBSD includes experimental support for several
mandatory access control policies, as well as a framework
for kernel security extensibility, the TrustedBSD MAC
Framework. The MAC Framework provides a pluggable access
control framework, permitting new security policies to
be easily linked into the kernel, loaded at boot, or loaded
dynamically at run-time. The framework provides a variety
of features to make it easier to implement new policies,
including the ability to easily tag security labels (such as
confidentiality information) onto system objects.This chapter introduces the MAC policy framework and
provides documentation for a sample MAC policy module.IntroductionThe TrustedBSD MAC framework provides a mechanism to allow
the compile-time or run-time extension of the kernel access
control model. New system policies may be implemented as
kernel modules and linked to the kernel; if multiple policy
modules are present, their results will be composed. The
MAC Framework provides a variety of access control infrastructure
services to assist policy writers, including support for
transient and persistent policy-agnostic object security
labels. This support is currently considered experimental.Policy BackgroundMandatory Access Control (MAC), refers to a set of
access control policies that are mandatorily enforced on
users by the operating system. MAC policies may be contrasted
with Discretionary Access Control (DAC) protections, by which
non-administrative users may (at their discretion) protect
objects. In traditional UNIX systems, DAC protections include
file permissions and access control lists; MAC protections include
process controls preventing inter-user debugging and firewalls.
A variety of MAC policies have been formulated by operating system
designers and security researches, including the Multi-Level
Security (MLS) confidentiality policy, the Biba integrity policy,
Role-Based Access Control (RBAC), and Type Enforcement (TE). Each
model bases decisions on a variety of factors, including user
identity, role, and security clearance, as well as security labels
on objects representing concepts such as data sensitivity and
integrity.The TrustedBSD MAC Framework is capable of supporting policy
modules that implement all of these policies, as well as a broad
class of system hardening policies. In addition, despite the
name, the MAC Framework can also be used to implement purely
discretionary policies, as policy modules are given substantial
flexibility in how they authorize protections.MAC Framework Kernel ArchitectureThe TrustedBSD MAC Framework permits kernel modules to
extend the operating system security policy, as well as
providing infrastructure functionality required by many
access control modules. If multiple policies are
simultaneously loaded, the MAC Framework will usefully (for
some definition of useful) compose the results of the
policies.Kernel ElementsThe MAC Framework contains a number of kernel elements:Framework management interfacesConcurrency and synchronization
primitives.Policy registrationExtensible security label for kernel
objectsPolicy entry point composition
operatorsLabel management primitivesEntry point API invoked by kernel
servicesEntry point API to policy modulesEntry points implementations (policy life cycle,
object life cycle/label management, access control
checks).Policy-agnostic label-management system
callsmac_syscall() multiplex
system callVarious security policies implemented as MAC
policy modulesManagement InterfacesThe TrustedBSD MAC Framework may be directly managed using
sysctls, loader tunables, and system calls.In most cases, sysctls and loader tunables modify the same
parameters, and control behavior such as enforcement of
protections relating to various kernel subsystems. In addition,
if MAC debugging support is compiled into the kernel, a variety
of counters will be maintained tracking label allocation. In
most cases, it is advised that per-subsystem enforcement
controls not be used to control policy behavior in production
environments, as they broadly impact the operation of all
active policies. Instead, per-policy controls should be
preferred to ensure proper policy operation.Loading and unloading of policy modules is performed
using the system module management system calls and other
system interfaces, including loader variables.Concurrency and SynchronizationAs the set of active policies may change at run-time,
and the invocation of entry points is non-atomic,
synchronization is required to prevent unloading or
loading of new policies while an entry point invocation
is progress, freezing the list of policies for the
duration. This is accomplished by means of a Framework
busy count. Whenever an entry point is entered, the
busy count is incremented; whenever it is exited, the
busy count is decremented. While the busy count is
elevated, policy list changes are not permitted, and
threads attempting to modify the policy list will sleep
until the list is not busy. The busy count is protected
by a mutex, and a condition variable is used to wake up
sleepers waiting on policy list modifications.Various optimizations are used to reduce the overhead
of the busy count, including avoiding the full cost of
incrementing and decrementing if the list is empty or
contains only static entries (policies that are loaded
before the system starts, and cannot be unloaded).Policy RegistrationThe MAC Framework maintains two lists of active
policies: a static list, and a dynamic list. The lists
differ only with regards to their locking semantics: an
elevated reference count is not required to make use of
the static list. When kernel modules containing MAC
Framework policies are loaded, the policy module will
use SYSINIT to invoke a registration
function; when a policy module is unloaded,
SYSINIT will likewise invoke a
de-registration function. Registration may fail if a
policy module is loaded more than once, if insufficient
resources are available for the registration (for
example, the policy might require labeling and
insufficient labeling state might be available), or
other policy prerequisites might not be met (some
policies may only be loaded prior to boot). Likewise,
de-registration may fail if a policy refuses an
unload.Entry PointsKernel services interact with the MAC Framework in two ways:
they invoke a series of APIs to notify the framework of relevant
events, and they a policy-agnostic label structure in
security-relevant objects. This label structure is maintained by
the MAC Framework via label management entry points, and permits
the Framework to offer a labeling service to policy modules
through relatively non-invasive changes to the kernel subsystem
maintaining the object. For example, label structures have been
added to processes, process credentials, sockets, pipes, vnodes,
Mbufs, network interfaces, IP reassembly queues, and a variety
of other security-relevant structures. Kernel services also
invoke the MAC Framework when they perform important security
decisions, permitting policy modules to augment those decisions
based on their own criteria (possibly including data stored in
security labels).Policy CompositionWhen more than one policy module is loaded into the kernel
at a time, the results of the policy modules will be composed
by the framework using a composition operator. This operator
is currently hard-coded, and requires that all active policies
must approve a request for it to occur. As policies may
return a variety of error conditions (success, access denied,
object doesn't exist, ...), a precedence operator selects the
resulting error from the set of errors returned by policies.
While it is not guaranteed that the resulting composition will
be useful or secure, we've found that it is for many useful
selections of policies.Labeling SupportAs many interesting access control extensions rely on
security labels on objects, the MAC Framework provides a set
of policy-agnostic label management system calls covering
a variety of user-exposed objects. Common label types
include partition identifiers, sensitivity labels, integrity
labels, compartments, domains, roles, and types. Policy
modules participate in the internalization and externalization
of string-based labels provides by user applications, and can
expose multiple label elements to applications if desired.In-memory labels are stored in struct
label, which consists of a fixed-length array
of unions, each holding a void * pointer
and a long. Policies registering for
label storage will be assigned a "slot" identifier, which
may be used to dereference the label storage. The semantics
of the storage are left entirely up to the policy module:
modules are provided with a variety of entry points
associated with the kernel object life cycle, including
initialization, association/creation, and destruction. Using
these interfaces, it is possible to implement reference
counting and other storage mechanisms. Direct access to
the kernel object is generally not required by policy
modules to retrieve a label, as the MAC Framework generally
passes both a pointer to the object and a direct pointer
to the object's label into entry points.Initialization entry points frequently include a blocking
disposition flag indicating whether or not an initialization
is permitted to block; if blocking is not permitted, a failure
may be returned to cancel allocation of the label. This may
occur, for example, in the network stack during interrupt
handling, where blocking is not permitted. Due to the
performance cost of maintaining labels on in-flight network
packets (Mbufs), policies must specifically declare a
requirement that Mbuf labels be allocated. Dynamically
loaded policies making use of labels must be able to handle
the case where their init function has not been called on
an object, as objects may already exist when the policy is
loaded.In the case of file system labels, special support is
provided for the persistent storage of security labels in
extended attributes. Where available, EA transactions
are used to permit consistent compound updates of
security labels on vnodes.Currently, if a labeled policy permits dynamic
unloading, its state slot cannot be reclaimed.System CallsThe MAC Framework implements a number of system calls:
most of these calls support the policy-agnostic label
retrieval and manipulation APIs exposed to user
applications.The label management calls accept a label description
structure, struct mac, which
contains a series of MAC label elements. Each element
contains a character string name, and character string
value. Each policy will be given the chance to claim a
particular element name, permitting policies to expose
multiple independent elements if desired. Policy modules
perform the internalization and externalization between
kernel labels and user-provided labels via entry points,
permitting a variety of semantics. Label management system
calls are generally wrapped by user library functions to
perform memory allocation and error handling.In addition, mac_syscall()
permits policy modules to create new system calls without
allocating system calls. mac_execve()
permits an atomic process credential label change when
executing a new image.MAC Policy ArchitectureSecurity policies are either linked directly into the kernel,
or compiled into loadable kernel modules that may be loaded at
boot, or dynamically using the module loading system calls at
runtime. Policy modules interact with the system through a
set of declared entry points, providing access to a stream of
system events and permitting the policy to influence access
control decisions. Each policy contains a number of elements:Optional configuration parameters for
policy.Centralized implementation of the policy
logic and parameters.Optional implementation of policy life cycle
events, such as initialization and destruction.Optional support for initializing, maintaining, and
destroying labels on selected kernel objects.Optional support for user process inspection and
modification of labels on selected objects.Implementation of selected access control
entry points that are of interest to the policy.Declaration of policy identity, module entry
points, and policy properties.Policy DeclarationModules may be declared using the
MAC_POLICY_SET() macro, which names the
policy, provides a reference to the MAC entry point vector,
provides load-time flags determining how the policy framework
should handle the policy, and optionally requests the
allocation of label state by the framework.static struct mac_policy_ops mac_policy_ops =
{
.mpo_destroy = mac_policy_destroy,
.mpo_init = mac_policy_init,
.mpo_init_bpfdesc_label = mac_policy_init_bpfdesc_label,
.mpo_init_cred_label = mac_policy_init_label,
/* ... */
.mpo_check_vnode_setutimes = mac_policy_check_vnode_setutimes,
.mpo_check_vnode_stat = mac_policy_check_vnode_stat,
.mpo_check_vnode_write = mac_policy_check_vnode_write,
};The MAC policy entry point vector,
mac_policy_ops in this example, associates
functions defined in the module with specific entry points. A
complete listing of available entry points and their
prototypes may be found in the MAC entry point reference
section. Of specific interest during module registration are
the .mpo_destroy and .mpo_init
entry points. .mpo_init will be invoked once a
policy is successfully registered with the module framework
but prior to any other entry points becoming active. This
permits the policy to perform any policy-specific allocation
and initialization, such as initialization of any data or
locks. .mpo_destroy will be invoked when a
policy module is unloaded to permit releasing of any allocated
memory and destruction of locks. Currently, these two entry
points are invoked with the MAC policy list mutex held to
prevent any other entry points from being invoked: this will
be changed, but in the mean time, policies should be careful
about what kernel primitives they invoke so as to avoid lock
ordering or sleeping problems.The policy declaration's module name field exists so that
the module may be uniquely identified for the purposes of
module dependencies. An appropriate string should be selected.
The full string name of the policy is displayed to the user
via the kernel log during load and unload events, and also
exported when providing status information to userland
processes.Policy FlagsThe policy declaration flags field permits the module to
provide the framework with information about its capabilities at
the time the module is loaded. Currently, three flags are
defined:MPC_LOADTIME_FLAG_UNLOADOKThis flag indicates that the policy module may be
unloaded. If this flag is not provided, then the policy
framework will reject requests to unload the module.
This flag might be used by modules that allocate label
state and are unable to free that state at
runtime.MPC_LOADTIME_FLAG_NOTLATEThis flag indicates that the policy module
must be loaded and initialized early in the boot
process. If the flag is specified, attempts to register
the module following boot will be rejected. The flag
may be used by policies that require pervasive labeling
of all system objects, and cannot handle objects that
have not been properly initialized by the policy.MPC_LOADTIME_FLAG_LABELMBUFSThis flag indicates that the policy module requires
labeling of Mbufs, and that memory should always be
allocated for the storage of Mbuf labels. By default,
the MAC Framework will not allocate label storage for
Mbufs unless at least one loaded policy has this flag
set. This measurably improves network performance when
policies do not require Mbuf labeling. A kernel option,
MAC_ALWAYS_LABEL_MBUF, exists to
force the MAC Framework to allocate Mbuf label storage
regardless of the setting of this flag, and may be
useful in some environments.Policies using the
MPC_LOADTIME_FLAG_LABELMBUFS without the
MPC_LOADTIME_FLAG_NOTLATE flag set
must be able to correctly handle NULL
Mbuf label pointers passed into entry points. This is necessary
as in-flight Mbufs without label storage may persist after a
policy enabling Mbuf labeling has been loaded. If a policy
is loaded before the network subsystem is active (i.e., the
policy is not being loaded late), then all Mbufs are guaranteed
to have label storage.Policy Entry PointsFour classes of entry points are offered to policies
registered with the framework: entry points associated with
the registration and management of policies, entry points
denoting initialization, creation, destruction, and other life
cycle events for kernel objects, events associated with access
control decisions that the policy module may influence, and
calls associated with the management of labels on objects. In
addition, a mac_syscall() entry point is
provided so that policies may extend the kernel interface
without registering new system calls.Policy module writers should be aware of the kernel
locking strategy, as well as what object locks are available
during which entry points. Writers should attempt to avoid
deadlock scenarios by avoiding grabbing non-leaf locks inside
of entry points, and also follow the locking protocol for
object access and modification. In particular, writers should
be aware that while necessary locks to access objects and
their labels are generally held, sufficient locks to modify an
object or its label may not be present for all entry points.
Locking information for arguments is documented in the MAC
framework entry point document.Policy entry points will pass a reference to the object
label along with the object itself. This permits labeled
policies to be unaware of the internals of the object yet
still make decisions based on the label. The exception to this
is the process credential, which is assumed to be understood
by policies as a first class security object in the kernel.
Policies that do not implement labels on kernel objects will
be passed NULL pointers for label arguments to entry
points.MAC Policy Entry Point ReferenceGeneral-Purpose Module Entry Points&mac.mpo;_initvoid
&mac.mpo;_initstruct mac_policy_conf
*conf
-
+
&mac.thead;
confMAC policy definitionPolicy load event. The policy list mutex is held, so
caution should be applied.&mac.mpo;_destroyvoid
&mac.mpo;_destroystruct mac_policy_conf
*conf
-
+
&mac.thead;
confMAC policy definitionPolicy load event. The policy list mutex is held, so
caution should be applied.&mac.mpo;_syscallint
&mac.mpo;_syscallstruct thread
*tdint callvoid *arg
-
+
&mac.thead;
tdCalling threadcallSyscall numberargPointer to syscall argumentsThis entry point provides a policy-multiplexed system
call so that policies may provide additional services to
user processes without registering specific system calls.
The policy name provided during registration is used to
demux calls from userland, and the arguments will be
forwarded to this entry point. When implementing new
services, security modules should be sure to invoke
appropriate access control checks from the MAC framework as
needed. For example, if a policy implements an augmented
signal functionality, it should call the necessary signal
access control checks to invoke the MAC framework and other
registered policies.Modules must currently perform the
copyin() of the syscall data on their
own.&mac.mpo;_thread_userretvoid
&mac.mpo;_thread_userretstruct thread
*td
-
+
&mac.thead;
tdReturning threadThis entry point permits policy modules to perform
MAC-related events when a thread returns to user space.
This is required for policies that have floating process
labels, as it is not always possible to acquire the process
lock at arbitrary points in the stack during system call
processing; process labels might represent traditional
authentication data, process history information, or other
data.Label Operations&mac.mpo;_init_bpfdesc_labelvoid
&mac.mpo;_init_bpfdesc_labelstruct label
*label
-
+
&mac.thead;
labelNew label to applyInitialize the label on a newly instantiated bpfdesc (BPF
descriptor)&mac.mpo;_init_cred_labelvoid
&mac.mpo;_init_cred_labelstruct label
*label
-
+
&mac.thead;
labelNew label to initializeInitialize the label for a newly instantiated
user credential.&mac.mpo;_init_devfsdirent_labelvoid
&mac.mpo;_init_devfsdirent_labelstruct label
*label
-
+
&mac.thead;
labelNew label to applyInitialize the label on a newly instantiated devfs
entry.&mac.mpo;_init_ifnet_labelvoid
&mac.mpo;_init_ifnet_labelstruct label
*label
-
+
&mac.thead;
labelNew label to applyInitialize the label on a newly instantiated network
interface.&mac.mpo;_init_ipq_labelvoid
&mac.mpo;_init_ipq_labelstruct label
*labelint flag
-
+
&mac.thead;
labelNew label to applyflagBlocking/non-blocking &man.malloc.9;; see
belowInitialize the label on a newly instantiated IP fragment
reassembly queue. The flag field may
be one of M_WAITOK and M_NOWAIT,
and should be employed to avoid performing a blocking
&man.malloc.9; during this initialization call. IP fragment
reassembly queue allocation frequently occurs in performance
sensitive environments, and the implementation should be careful
to avoid blocking or long-lived operations. This entry point
is permitted to fail resulting in the failure to allocate
the IP fragment reassembly queue.&mac.mpo;_init_mbuf_labelvoid
&mac.mpo;_init_mbuf_labelint flagstruct label
*label
-
+
&mac.thead;
flagBlocking/non-blocking &man.malloc.9;; see
belowlabelPolicy label to initializeInitialize the label on a newly instantiated mbuf packet
header (mbuf). The
flag field may be one of
M_WAITOK and M_NOWAIT, and
should be employed to avoid performing a blocking
&man.malloc.9; during this initialization call. Mbuf
allocation frequently occurs in performance sensitive
environments, and the implementation should be careful to
avoid blocking or long-lived operations. This entry point
is permitted to fail resulting in the failure to allocate
the mbuf header.&mac.mpo;_init_mount_labelvoid
&mac.mpo;_init_mount_labelstruct label
*mntlabelstruct label
*fslabel
-
+
&mac.thead;
mntlabelPolicy label to be initialized for the mount
itselffslabelPolicy label to be initialized for the file
systemInitialize the labels on a newly instantiated mount
point.&mac.mpo;_init_mount_fs_labelvoid
&mac.mpo;_init_mount_fs_labelstruct label
*label
-
+
&mac.thead;
labelLabel to be initializedInitialize the label on a newly mounted file
system.&mac.mpo;_init_pipe_labelvoid
&mac.mpo;_init_pipe_labelstruct
label*label
-
+
&mac.thead;
labelLabel to be filled inInitialize a label for a newly instantiated pipe.&mac.mpo;_init_socket_labelvoid
&mac.mpo;_init_socket_labelstruct label
*labelint flag
-
+
&mac.thead;
labelNew label to initializeflag&man.malloc.9; flagsInitialize a label for a newly instantiated
socket.&mac.mpo;_init_socket_peer_labelvoid
&mac.mpo;_init_socket_peer_labelstruct label
*labelint flag
-
+
&mac.thead;
labelNew label to initializeflag&man.malloc.9; flagsInitialize the peer label for a newly instantiated
socket.&mac.mpo;_init_proc_labelvoid
&mac.mpo;_init_proc_labelstruct label
*label
-
+
&mac.thead;
labelNew label to initializeInitialize the label for a newly instantiated
process.&mac.mpo;_init_vnode_labelvoid
&mac.mpo;_init_vnode_labelstruct label
*label
-
+
&mac.thead;
labelNew label to initializeInitialize the label on a newly instantiated vnode.&mac.mpo;_destroy_bpfdesc_labelvoid
&mac.mpo;_destroy_bpfdesc_labelstruct label
*label
-
+
&mac.thead;
labelbpfdesc labelDestroy the label on a BPF descriptor. In this entry
point a policy should free any internal storage associated
with label so that it may be
destroyed.&mac.mpo;_destroy_cred_labelvoid
&mac.mpo;_destroy_cred_labelstruct label
*label
-
+
&mac.thead;
labelLabel being destroyedDestroy the label on a credential. In this entry point,
a policy module should free any internal storage associated
with label so that it may be
destroyed.&mac.mpo;_destroy_devfsdirent_labelvoid
&mac.mpo;_destroy_devfsdirent_labelstruct label
*label
-
+
&mac.thead;
labelLabel being destroyedDestroy the label on a devfs entry. In this entry
point, a policy module should free any internal storage
associated with label so that it may
be destroyed.&mac.mpo;_destroy_ifnet_labelvoid
&mac.mpo;_destroy_ifnet_labelstruct label
*label
-
+
&mac.thead;
labelLabel being destroyedDestroy the label on a removed interface. In this entry
point, a policy module should free any internal storage
associated with label so that it may
be destroyed.&mac.mpo;_destroy_ipq_labelvoid
&mac.mpo;_destroy_ipq_labelstruct label
*label
-
+
&mac.thead;
labelLabel being destroyedDestroy the label on an IP fragment queue. In this
entry point, a policy module should free any internal
storage associated with label so that
it may be destroyed.&mac.mpo;_destroy_mbuf_labelvoid
&mac.mpo;_destroy_mbuf_labelstruct label
*label
-
+
&mac.thead;
labelLabel being destroyedDestroy the label on an mbuf header. In this entry
point, a policy module should free any internal storage
associated with label so that it may
be destroyed.&mac.mpo;_destroy_mount_labelvoid
&mac.mpo;_destroy_mount_labelstruct label
*label
-
+
&mac.thead;
labelMount point label being destroyedDestroy the labels on a mount point. In this entry
point, a policy module should free the internal storage
associated with mntlabel so that they
may be destroyed.&mac.mpo;_destroy_mount_labelvoid
&mac.mpo;_destroy_mount_labelstruct label
*mntlabelstruct label
*fslabel
-
+
&mac.thead;
mntlabelMount point label being destroyedfslabelFile system label being destroyed>Destroy the labels on a mount point. In this entry
point, a policy module should free the internal storage
associated with mntlabel and
fslabel so that they may be
destroyed.&mac.mpo;_destroy_socket_labelvoid
&mac.mpo;_destroy_socket_labelstruct label
*label
-
+
&mac.thead;
labelSocket label being destroyedDestroy the label on a socket. In this entry point, a
policy module should free any internal storage associated
with label so that it may be
destroyed.&mac.mpo;_destroy_socket_peer_labelvoid
&mac.mpo;_destroy_socket_peer_labelstruct label
*peerlabel
-
+
&mac.thead;
peerlabelSocket peer label being destroyedDestroy the peer label on a socket. In this entry
point, a policy module should free any internal storage
associated with label so that it may
be destroyed.&mac.mpo;_destroy_pipe_labelvoid
&mac.mpo;_destroy_pipe_labelstruct label
*label
-
+
&mac.thead;
labelPipe labelDestroy the label on a pipe. In this entry point, a
policy module should free any internal storage associated
with label so that it may be
destroyed.&mac.mpo;_destroy_proc_labelvoid
&mac.mpo;_destroy_proc_labelstruct label
*label
-
+
&mac.thead;
labelProcess labelDestroy the label on a process. In this entry point, a
policy module should free any internal storage associated
with label so that it may be
destroyed.&mac.mpo;_destroy_vnode_labelvoid
&mac.mpo;_destroy_vnode_labelstruct label
*label
-
+
&mac.thead;
labelProcess labelDestroy the label on a vnode. In this entry point, a
policy module should free any internal storage associated
with label so that it may be
destroyed.&mac.mpo;_copy_mbuf_labelvoid
&mac.mpo;_copy_mbuf_labelstruct label
*srcstruct label
*dest
-
+
&mac.thead;
srcSource labeldestDestination labelCopy the label information in
src into
dest.&mac.mpo;_copy_pipe_labelvoid
&mac.mpo;_copy_pipe_labelstruct label
*srcstruct label
*dest
-
+
&mac.thead;
srcSource labeldestDestination labelCopy the label information in
src into
dest.&mac.mpo;_copy_vnode_labelvoid
&mac.mpo;_copy_vnode_labelstruct label
*srcstruct label
*dest
-
+
&mac.thead;
srcSource labeldestDestination labelCopy the label information in
src into
dest.&mac.mpo;_externalize_cred_labelint
&mac.mpo;_externalize_cred_label
&mac.externalize.paramdefs;
-
+
&mac.thead;
&mac.externalize.tbody;
&mac.externalize.para;
&mac.mpo;_externalize_ifnet_labelint
&mac.mpo;_externalize_ifnet_label
&mac.externalize.paramdefs;
-
+
&mac.thead;
&mac.externalize.tbody;
&mac.externalize.para;
&mac.mpo;_externalize_pipe_labelint
&mac.mpo;_externalize_pipe_label
&mac.externalize.paramdefs;
-
+
&mac.thead;
&mac.externalize.tbody;
&mac.externalize.para;
&mac.mpo;_externalize_socket_labelint
&mac.mpo;_externalize_socket_label
&mac.externalize.paramdefs;
-
+
&mac.thead;
&mac.externalize.tbody;
&mac.externalize.para;
&mac.mpo;_externalize_socket_peer_labelint
&mac.mpo;_externalize_socket_peer_label
&mac.externalize.paramdefs;
-
+
&mac.thead;
&mac.externalize.tbody;
&mac.externalize.para;
&mac.mpo;_externalize_vnode_labelint
&mac.mpo;_externalize_vnode_label
&mac.externalize.paramdefs;
-
+
&mac.thead;
&mac.externalize.tbody;
&mac.externalize.para;
&mac.mpo;_internalize_cred_labelint
&mac.mpo;_internalize_cred_label
&mac.internalize.paramdefs;
-
+
&mac.thead;
&mac.internalize.tbody;
&mac.internalize.para;
&mac.mpo;_internalize_ifnet_labelint
&mac.mpo;_internalize_ifnet_label
&mac.internalize.paramdefs;
-
+
&mac.thead;
&mac.internalize.tbody;
&mac.internalize.para;
&mac.mpo;_internalize_pipe_labelint
&mac.mpo;_internalize_pipe_label
&mac.internalize.paramdefs;
-
+
&mac.thead;
&mac.internalize.tbody;
&mac.internalize.para;
&mac.mpo;_internalize_socket_labelint
&mac.mpo;_internalize_socket_label
&mac.internalize.paramdefs;
-
+
&mac.thead;
&mac.internalize.tbody;
&mac.internalize.para;
&mac.mpo;_internalize_vnode_labelint
&mac.mpo;_internalize_vnode_label
&mac.internalize.paramdefs;
-
+
&mac.thead;
&mac.internalize.tbody;
&mac.internalize.para;
Label EventsThis class of entry points is used by the MAC framework to
permit policies to maintain label information on kernel
objects. For each labeled kernel object of interest to a MAC
policy, entry points may be registered for relevant life cycle
events. All objects implement initialization, creation, and
destruction hooks. Some objects will also implement
relabeling, allowing user processes to change the labels on
objects. Some objects will also implement object-specific
events, such as label events associated with IP reassembly. A
typical labeled object will have the following life cycle of
entry points:Label initialization o
(object-specific wait) \
Label creation o
\
Relabel events, o--<--.
Various object-specific, | |
Access control events ~-->--o
\
Label destruction oLabel initialization permits policies to allocate memory
and set initial values for labels without context for the use
of the object. The label slot allocated to a policy will be
zeroed by default, so some policies may not need to perform
initialization.Label creation occurs when the kernel structure is
associated with an actual kernel object. For example, Mbufs
may be allocated and remain unused in a pool until they are
required. mbuf allocation causes label initialization on the
mbuf to take place, but mbuf creation occurs when the mbuf is
associated with a datagram. Typically, context will be
provided for a creation event, including the circumstances of
the creation, and labels of other relevant objects in the
creation process. For example, when an mbuf is created from a
socket, the socket and its label will be presented to
registered policies in addition to the new mbuf and its label.
Memory allocation in creation events is discouraged, as it may
occur in performance sensitive ports of the kernel; in
addition, creation calls are not permitted to fail so a
failure to allocate memory cannot be reported.Object specific events do not generally fall into the
other broad classes of label events, but will generally
provide an opportunity to modify or update the label on an
object based on additional context. For example, the label on
an IP fragment reassembly queue may be updated during the
MAC_UPDATE_IPQ entry point as a result of the
acceptance of an additional mbuf to that queue.Access control events are discussed in detail in the
following section.Label destruction permits policies to release storage or
state associated with a label during its association with an
object so that the kernel data structures supporting the
object may be reused or released.In addition to labels associated with specific kernel
objects, an additional class of labels exists: temporary
labels. These labels are used to store update information
submitted by user processes. These labels are initialized and
destroyed as with other label types, but the creation event is
MAC_INTERNALIZE, which accepts a user label
to be converted to an in-kernel representation.File System Object Labeling Event Operations&mac.mpo;_associate_vnode_devfsvoid
&mac.mpo;_associate_vnode_devfsstruct mount
*mpstruct label
*fslabelstruct devfs_dirent
*destruct label
*delabelstruct vnode
*vpstruct label
*vlabel
-
+
&mac.thead;
mpDevfs mount pointfslabelDevfs file system label
(mp->mnt_fslabel)deDevfs directory entrydelabelPolicy label associated with
devpvnode associated with
devlabelPolicy label associated with
vpFill in the label (vlabel) for
a newly created devfs vnode based on the devfs directory
entry passed in de and its
label.&mac.mpo;_associate_vnode_extattrint
&mac.mpo;_associate_vnode_extattrstruct mount
*mpstruct label
*fslabelstruct vnode
*vpstruct label
*vlabel
-
+
&mac.thead;
mpFile system mount pointfslabelFile system labelvpVnode to labelvlabelPolicy label associated with
vpAttempt to retrieve the label for
vp from the file system extended
attributes. Upon success, the value 0
is returned. Should extended attribute retrieval not be
supported, an accepted fallback is to copy
fslabel into
vlabel. In the event of an error,
an appropriate value for errno should
be returned.&mac.mpo;_associate_vnode_singlelabelvoid
&mac.mpo;_associate_vnode_singlelabelstruct mount
*mpstruct label
*fslabelstruct vnode
*vpstruct label
*vlabel
-
+
&mac.thead;
mpFile system mount pointfslabelFile system labelvpVnode to labelvlabelPolicy label associated with
vpOn non-multilabel file systems, this entry point is
called to set the policy label for
vp based on the file system label,
fslabel.&mac.mpo;_create_devfs_devicevoid
&mac.mpo;_create_devfs_devicedev_t devstruct devfs_dirent
*devfs_direntstruct label
*label
-
+
&mac.thead;
devDevice corresponding with
devfs_direntdevfs_direntDevfs directory entry to be labeled.labelLabel for devfs_dirent
to be filled in.Fill out the label on a devfs_dirent being created for
the passed device. This call will be made when the device
file system is mounted, regenerated, or a new device is made
available.&mac.mpo;_create_devfs_directoryvoid
&mac.mpo;_create_devfs_directorychar *dirnameint dirnamelenstruct devfs_dirent
*devfs_direntstruct label
*label
-
+
&mac.thead;
dirnameName of directory being creatednamelenLength of string
dirnamedevfs_direntDevfs directory entry for directory being
created.Fill out the label on a devfs_dirent being created for
the passed directory. This call will be made when the device
file system is mounted, regenerated, or a new device
requiring a specific directory hierarchy is made
available.&mac.mpo;_create_devfs_symlinkvoid
&mac.mpo;_create_devfs_symlinkstruct ucred
*credstruct mount
*mpstruct devfs_dirent
*ddstruct label
*ddlabelstruct devfs_dirent
*destruct label
*delabel
-
+
&mac.thead;
credSubject credentialmpDevfs mount pointddLink destinationddlabelLabel associated with
dddeSymlink entrydelabelLabel associated with
deFill in the label (delabel) for
a newly created &man.devfs.5; symbolic link entry.&mac.mpo;_create_vnode_extattrint
&mac.mpo;_create_vnode_extattrstruct ucred
*credstruct mount
*mpstruct label
*fslabelstruct vnode
*dvpstruct label
*dlabelstruct vnode
*vpstruct label
*vlabelstruct componentname
*cnp
-
+
&mac.thead;
credSubject credentialmountFile system mount pointlabelFile system labeldvpParent directory vnodedlabelLabel associated with
dvpvpNewly created vnodevlabelPolicy label associated with
vpcnpComponent name for
vpWrite out the label for vp to
the appropriate extended attribute. If the write
succeeds, fill in vlabel with the
label, and return 0. Otherwise,
return an appropriate error.&mac.mpo;_create_mountvoid
&mac.mpo;_create_mountstruct ucred
*credstruct mount
*mpstruct label
*mntstruct label
*fslabel
-
+
&mac.thead;
credSubject credentialmpObject; file system being mountedmntlabelPolicy label to be filled in for
mpfslabelPolicy label for the file system
mp mounts.Fill out the labels on the mount point being created by
the passed subject credential. This call will be made when
a new file system is mounted.&mac.mpo;_create_root_mountvoid
&mac.mpo;_create_root_mountstruct ucred
*credstruct mount
*mpstruct label
*mntlabelstruct label
*fslabel
-
+
&mac.thead;
See .Fill out the labels on the mount point being created by
the passed subject credential. This call will be made when
the root file system is mounted, after
&mac.mpo;_create_mount;.&mac.mpo;_relabel_vnodevoid
&mac.mpo;_relabel_vnodestruct ucred
*credstruct vnode
*vpstruct label
*vnodelabelstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialvpvnode to relabelvnodelabelExisting policy label for
vpnewlabelNew, possibly partial label to replace
vnodelabelUpdate the label on the passed vnode given the passed
update vnode label and the passed subject credential.&mac.mpo;_setlabel_vnode_extattrint
&mac.mpo;_setlabel_vnode_extattrstruct ucred
*credstruct vnode
*vpstruct label
*vlabelstruct label
*intlabel
-
+
&mac.thead;
credSubject credentialvpVnode for which the label is being
writtenvlabelPolicy label associated with
vpintlabelLabel to write outWrite out the policy from
intlabel to an extended
attribute. This is called from
vop_stdcreatevnode_ea.&mac.mpo;_update_devfsdirentvoid
&mac.mpo;_update_devfsdirentstruct devfs_dirent
*devfs_direntstruct label
*direntlabelstruct vnode
*vpstruct label
*vnodelabel
-
+
&mac.thead;
devfs_direntObject; devfs directory entrydirentlabelPolicy label for
devfs_dirent to be
updated.vpParent vnodeLockedvnodelabelPolicy label for
vpUpdate the devfs_dirent label
from the passed devfs vnode label. This call will be made
when a devfs vnode has been successfully relabeled to commit
the label change such that it lasts even if the vnode is
recycled. It will also be made when when a symlink is
created in devfs, following a call to
mac_vnode_create_from_vnode to
initialize the vnode label.IPC Object Labeling Event Operations&mac.mpo;_create_mbuf_from_socketvoid
&mac.mpo;_create_mbuf_from_socketstruct socket
*sostruct label
*socketlabelstruct mbuf *mstruct label
*mbuflabel
-
+
&mac.thead;
socketSocketSocket locking WIPsocketlabelPolicy label for
socketmObject; mbufmbuflabelPolicy label to fill in for
mSet the label on a newly created mbuf header from the
passed socket label. This call is made when a new datagram
or message is generated by the socket and stored in the
passed mbuf.&mac.mpo;_create_pipevoid
&mac.mpo;_create_pipestruct ucred
*credstruct pipe
*pipestruct label
*pipelabel
-
+
&mac.thead;
credSubject credentialpipePipepipelabelPolicy label associated with
pipeSet the label on a newly created pipe from the passed
subject credential. This call is made when a new pipe is
created.&mac.mpo;_create_socketvoid
&mac.mpo;_create_socketstruct ucred
*credstruct socket
*sostruct label
*socketlabel
-
+
&mac.thead;
credSubject credentialImmutablesoObject; socket to labelsocketlabelLabel to fill in for
soSet the label on a newly created socket from the passed
subject credential. This call is made when a socket is
created.&mac.mpo;_create_socket_from_socketvoid
&mac.mpo;_create_socket_from_socketstruct socket
*oldsocketstruct label
*oldsocketlabelstruct socket
*newsocketstruct label
*newsocketlabel
-
+
&mac.thead;
oldsocketListening socketoldsocketlabelPolicy label associated with
oldsocketnewsocketNew socketnewsocketlabelPolicy label associated with
newsocketlabelLabel a socket, newsocket,
newly &man.accept.2;ed, based on the &man.listen.2;
socket, oldsocket.&mac.mpo;_relabel_pipevoid
&mac.mpo;_relabel_pipestruct ucred
*credstruct pipe
*pipestruct label
*oldlabelstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialpipePipeoldlabelCurrent policy label associated with
pipenewlabelPolicy label update to apply to
pipeApply a new label, newlabel, to
pipe.&mac.mpo;_relabel_socketvoid
&mac.mpo;_relabel_socketstruct ucred
*credstruct socket
*sostruct label
*oldlabelstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialImmutablesoObject; socketoldlabelCurrent label for
sonewlabelLabel update for
soUpdate the label on a socket from the passed socket
label update.&mac.mpo;_set_socket_peer_from_mbufvoid
&mac.mpo;_set_socket_peer_from_mbufstruct mbuf
*mbufstruct label
*mbuflabelstruct label
*oldlabelstruct label
*newlabel
-
+
&mac.thead;
mbufFirst datagram received over socketmbuflabelLabel for mbufoldlabelCurrent label for the socketnewlabelPolicy label to be filled out for the
socketSet the peer label on a stream socket from the passed
mbuf label. This call will be made when the first datagram
is received by the stream socket, with the exception of Unix
domain sockets.&mac.mpo;_set_socket_peer_from_socketvoid
&mac.mpo;_set_socket_peer_from_socketstruct socket
*oldsocketstruct label
*oldsocketlabelstruct socket
*newsocketstruct label
*newsocketpeerlabel
-
+
&mac.thead;
oldsocketLocal socketoldsocketlabelPolicy label for
oldsocketnewsocketPeer socketnewsocketpeerlabelPolicy label to fill in for
newsocketSet the peer label on a stream UNIX domain socket from
the passed remote socket endpoint. This call will be made
when the socket pair is connected, and will be made for both
endpoints.Network Object Labeling Event Operations&mac.mpo;_create_bpfdescvoid
&mac.mpo;_create_bpfdescstruct ucred
*credstruct bpf_d
*bpf_dstruct label
*bpflabel
-
+
&mac.thead;
credSubject credentialImmutablebpf_dObject; bpf descriptorbpfPolicy label to be filled in for
bpf_dSet the label on a newly created BPF descriptor from the
passed subject credential. This call will be made when a
BPF device node is opened by a process with the passed
subject credential.&mac.mpo;_create_ifnetvoid
&mac.mpo;_create_ifnetstruct ifnet
*ifnetstruct label
*ifnetlabel
-
+
&mac.thead;
ifnetNetwork interfaceifnetlabelPolicy label to fill in for
ifnetSet the label on a newly created interface. This call
may be made when a new physical interface becomes available
to the system, or when a pseudo-interface is instantiated
during the boot or as a result of a user action.&mac.mpo;_create_ipqvoid
&mac.mpo;_create_ipqstruct mbuf
*fragmentstruct label
*fragmentlabelstruct ipq
*ipqstruct label
*ipqlabel
-
+
&mac.thead;
fragmentFirst received IP fragmentfragmentlabelPolicy label for
fragmentipqIP reassembly queue to be labeledipqlabelPolicy label to be filled in for
ipqSet the label on a newly created IP fragment reassembly
queue from the mbuf header of the first received
fragment.&mac.mpo;_create_datagram_from_ipqvoid
&mac.mpo;_create_create_datagram_from_ipqstruct ipq
*ipqstruct label
*ipqlabelstruct mbuf
*datagramstruct label
*datagramlabel
-
+
&mac.thead;
ipqIP reassembly queueipqlabelPolicy label for
ipqdatagramDatagram to be labeleddatagramlabelPolicy label to be filled in for
datagramlabelSet the label on a newly reassembled IP datagram from
the IP fragment reassembly queue from which it was
generated.&mac.mpo;_create_fragmentvoid
&mac.mpo;_create_fragmentstruct mbuf
*datagramstruct label
*datagramlabelstruct mbuf
*fragmentstruct label
*fragmentlabel
-
+
&mac.thead;
datagramDatagramdatagramlabelPolicy label for
datagramfragmentFragment to be labeledfragmentlabelPolicy label to be filled in for
datagramSet the label on the mbuf header of a newly created IP
fragment from the label on the mbuf header of the datagram
it was generate from.&mac.mpo;_create_mbuf_from_mbufvoid
&mac.mpo;_create_mbuf_from_mbufstruct mbuf
*oldmbufstruct label
*oldmbuflabelstruct mbuf
*newmbufstruct label
*newmbuflabel
-
+
&mac.thead;
oldmbufExisting (source) mbufoldmbuflabelPolicy label for
oldmbufnewmbufNew mbuf to be labelednewmbuflabelPolicy label to be filled in for
newmbufSet the label on the mbuf header of a newly created
datagram from the mbuf header of an existing datagram. This
call may be made in a number of situations, including when
an mbuf is re-allocated for alignment purposes.&mac.mpo;_create_mbuf_linklayervoid
&mac.mpo;_create_mbuf_linklayerstruct ifnet
*ifnetstruct label
*ifnetlabelstruct mbuf
*mbufstruct label
*mbuflabel
-
+
&mac.thead;
ifnetNetwork interfaceifnetlabelPolicy label for
ifnetmbufmbuf header for new datagrammbuflabelPolicy label to be filled in for
mbufSet the label on the mbuf header of a newly created
datagram generated for the purposes of a link layer response
for the passed interface. This call may be made in a number
of situations, including for ARP or ND6 responses in the
IPv4 and IPv6 stacks.&mac.mpo;_create_mbuf_from_bpfdescvoid
&mac.mpo;_create_mbuf_from_bpfdescstruct bpf_d
*bpf_dstruct label
*bpflabelstruct mbuf
*mbufstruct label
*mbuflabel
-
+
&mac.thead;
bpf_dBPF descriptorbpflabelPolicy label for
bpflabelmbufNew mbuf to be labeledmbuflabelPolicy label to fill in for
mbufSet the label on the mbuf header of a newly created
datagram generated using the passed BPF descriptor. This
call is made when a write is performed to the BPF device
associated with the passed BPF descriptor.&mac.mpo;_create_mbuf_from_ifnetvoid
&mac.mpo;_create_mbuf_from_ifnetstruct ifnet
*ifnetstruct label
*ifnetlabelstruct mbuf
*mbufstruct label
*mbuflabel
-
+
&mac.thead;
ifnetNetwork interfaceifnetlabelPolicy label for
ifnetlabelmbufmbuf header for new datagrammbuflabelPolicy label to be filled in for
mbufSet the label on the mbuf header of a newly created
datagram generated from the passed network interface.&mac.mpo;_create_mbuf_multicast_encapvoid
&mac.mpo;_create_mbuf_multicast_encapstruct mbuf
*oldmbufstruct label
*oldmbuflabelstruct ifnet
*ifnetstruct label
*ifnetlabelstruct mbuf
*newmbufstruct label
*newmbuflabel
-
+
&mac.thead;
oldmbufmbuf header for existing datagramoldmbuflabelPolicy label for
oldmbufifnetNetwork interfaceifnetlabelPolicy label for
ifnetnewmbufmbuf header to be labeled for new
datagramnewmbuflabelPolicy label to be filled in for
newmbufSet the label on the mbuf header of a newly created
datagram generated from the existing passed datagram when it
is processed by the passed multicast encapsulation
interface. This call is made when an mbuf is to be
delivered using the virtual interface.&mac.mpo;_create_mbuf_netlayervoid
&mac.mpo;_create_mbuf_netlayerstruct mbuf
*oldmbufstruct label
*oldmbuflabelstruct mbuf
*newmbufstruct label
*newmbuflabel
-
+
&mac.thead;
oldmbufReceived datagramoldmbuflabelPolicy label for
oldmbufnewmbufNewly created datagramnewmbuflabelPolicy label for
newmbufSet the label on the mbuf header of a newly created
datagram generated by the IP stack in response to an
existing received datagram (oldmbuf).
This call may be made in a number of situations, including
when responding to ICMP request datagrams.&mac.mpo;_fragment_matchint
&mac.mpo;_fragment_matchstruct mbuf
*fragmentstruct label
*fragmentlabelstruct ipq
*ipqstruct label
*ipqlabel
-
+
&mac.thead;
fragmentIP datagram fragmentfragmentlabelPolicy label for
fragmentipqIP fragment reassembly queueipqlabelPolicy label for
ipqDetermine whether an mbuf header containing an IP
datagram (fragment) fragment matches
the label of the passed IP fragment reassembly queue
(ipq). Return
(1) for a successful match, or
(0) for no match. This call is
made when the IP stack attempts to find an existing fragment
reassembly queue for a newly received fragment; if this
fails, a new fragment reassembly queue may be instantiated
for the fragment. Policies may use this entry point to
prevent the reassembly of otherwise matching IP fragments if
policy does not permit them to be reassembled based on the
label or other information.&mac.mpo;_relabel_ifnetvoid
&mac.mpo;_relabel_ifnetstruct ucred
*credstruct ifnet
*ifnetstruct label
*ifnetlabelstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialifnetObject; Network interfaceifnetlabelPolicy label for
ifnetnewlabelLabel update to apply to
ifnetUpdate the label of network interface,
ifnet, based on the passed update
label, newlabel, and the passed
subject credential, cred.&mac.mpo;_update_ipqvoid
&mac.mpo;_update_ipqstruct mbuf
*fragmentstruct label
*fragmentlabelstruct ipq
*ipqstruct label
*ipqlabel
-
+
&mac.thead;
mbufIP fragmentmbuflabelPolicy label for
mbufipqIP fragment reassembly queueipqlabelPolicy label to be updated for
ipqUpdate the label on an IP fragment reassembly queue
(ipq) based on the acceptance of the
passed IP fragment mbuf header
(mbuf).Process Labeling Event Operations&mac.mpo;_create_credvoid
&mac.mpo;_create_credstruct ucred
*parent_credstruct ucred
*child_cred
-
+
&mac.thead;
parent_credParent subject credentialchild_credChild subject credentialSet the label of a newly created subject credential from
the passed subject credential. This call will be made when
&man.crcopy.9; is invoked on a newly created struct
ucred. This call should not be confused with a
process forking or creation event.&mac.mpo;_execve_transitionvoid
&mac.mpo;_execve_transitionstruct ucred
*oldstruct ucred
*newstruct vnode
*vpstruct label
*vnodelabel
-
+
&mac.thead;
oldExisting subject credentialImmutablenewNew subject credential to be labeledvpFile to executeLockedvnodelabelPolicy label for
vpUpdate the label of a newly created subject credential
(new) from the passed existing
subject credential (old) based on a
label transition caused by executing the passed vnode
(vp). This call occurs when a
process executes the passed vnode and one of the policies
returns a success from the
mpo_execve_will_transition entry point.
Policies may choose to implement this call simply by
invoking mpo_create_cred and passing
the two subject credentials so as not to implement a
transitioning event. Policies should not leave this entry
point unimplemented if they implement
mpo_create_cred, even if they do not
implement
mpo_execve_will_transition.&mac.mpo;_execve_will_transitionint
&mac.mpo;_execve_will_transitionstruct ucred
*oldstruct vnode
*vpstruct label
*vnodelabel
-
+
&mac.thead;
oldSubject credential prior to
&man.execve.2;ImmutablevpFile to executevnodelabelPolicy label for
vpDetermine whether the policy will want to perform a
transition event as a result of the execution of the passed
vnode by the passed subject credential. Return
1 if a transition is required,
0 if not. Even if a policy
returns 0, it should behave
correctly in the presence of an unexpected invocation of
mpo_execve_transition, as that call may
happen as a result of another policy requesting a
transition.&mac.mpo;_create_proc0void
&mac.mpo;_create_proc0struct ucred
*cred
-
+
&mac.thead;
credSubject credential to be filled inCreate the subject credential of process 0, the parent
of all kernel processes.&mac.mpo;_create_proc1void
&mac.mpo;_create_proc1struct ucred
*cred
-
+
&mac.thead;
credSubject credential to be filled inCreate the subject credential of process 1, the parent
of all user processes.&mac.mpo;_relabel_credvoid
&mac.mpo;_relabel_credstruct ucred
*credstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialnewlabelLabel update to apply to
credUpdate the label on a subject credential from the passed
update label.Access Control ChecksAccess control entry points permit policy modules to
influence access control decisions made by the kernel.
Generally, although not always, arguments to an access control
entry point will include one or more authorizing credentials,
information (possibly including a label) for any other objects
involved in the operation. An access control entry point may
return 0 to permit the operation, or an &man.errno.2; error
value. The results of invoking the entry point across various
registered policy modules will be composed as follows: if all
modules permit the operation to succeed, success will be
returned. If one or modules returns a failure, a failure will
be returned. If more than one module returns a failure, the
errno value to return to the user will be selected using the
following precedence, implemented by the
error_select() function in
kern_mac.c:
-
+ Most precedenceEDEADLKEINVALESRCHEACCESLeast precedenceEPERMIf none of the error values returned by all modules are
listed in the precedence chart then an arbitrarily selected
value from the set will be returned. In general, the rules
provide precedence to errors in the following order: kernel
failures, invalid arguments, object not present, access not
permitted, other.&mac.mpo;_check_bpfdesc_receiveint
&mac.mpo;_check_bpfdesc_receivestruct bpf_d
*bpf_dstruct label
*bpflabelstruct ifnet
*ifnetstruct label
*ifnetlabel
-
+
&mac.thead;
bpf_dSubject; BPF descriptorbpflabelPolicy label for
bpf_difnetObject; network interfaceifnetlabelPolicy label for
ifnetDetermine whether the MAC framework should permit
datagrams from the passed interface to be delivered to the
buffers of the passed BPF descriptor. Return
(0) for success, or an
errno value for failure Suggested
failure: EACCES for label mismatches,
EPERM for lack of privilege.&mac.mpo;_check_kenv_dumpint
&mac.mpo;_check_kenv_dumpstruct ucred
*cred
-
+
&mac.thead;
credSubject credentialDetermine whether the subject should be allowed to
retrieve the kernel environment (see &man.kenv.2;).&mac.mpo;_check_kenv_getint
&mac.mpo;_check_kenv_getstruct ucred
*credchar *name
-
+
&mac.thead;
credSubject credentialnameKernel environment variable nameDetermine whether the subject should be allowed to
retrieve the value of the specified kernel environment
variable.&mac.mpo;_check_kenv_setint
&mac.mpo;_check_kenv_setstruct ucred
*credchar *name
-
+
&mac.thead;
credSubject credentialnameKernel environment variable nameDetermine whether the subject should be allowed to set
the specified kernel environment variable.&mac.mpo;_check_kenv_unsetint
&mac.mpo;_check_kenv_unsetstruct ucred
*credchar *name
-
+
&mac.thead;
credSubject credentialnameKernel environment variable nameDetermine whether the subject should be allowed to unset
the specified kernel environment variable.&mac.mpo;_check_kld_loadint
&mac.mpo;_check_kld_loadstruct ucred
*credstruct vnode
*vpstruct label
*vlabel
-
+
&mac.thead;
credSubject credentialvpKernel module vnodevlabelLabel associated with
vpDetermine whether the subject should be allowed to load
the specified module file.&mac.mpo;_check_kld_statint
&mac.mpo;_check_kld_statstruct ucred
*cred
-
+
&mac.thead;
credSubject credentialDetermine whether the subject should be allowed to
retrieve a list of loaded kernel module files and associated
statistics.&mac.mpo;_check_kld_unloadint
&mac.mpo;_check_kld_unloadstruct ucred
*cred
-
+
&mac.thead;
credSubject credentialDetermine whether the subject should be allowed to
unload a kernel module.&mac.mpo;_check_pipe_ioctlint
&mac.mpo;_check_pipe_ioctlstruct ucred
*credstruct pipe
*pipestruct label
*pipelabelunsigned long
cmdvoid *data
-
+
&mac.thead;
credSubject credentialpipePipepipelabelPolicy label associated with
pipecmd&man.ioctl.2; commanddata&man.ioctl.2; dataDetermine whether the subject should be allowed to make
the specified &man.ioctl.2; call.&mac.mpo;_check_pipe_pollint
&mac.mpo;_check_pipe_pollstruct ucred
*credstruct pipe
*pipestruct label
*pipelabel
-
+
&mac.thead;
credSubject credentialpipePipepipelabelPolicy label associated with
pipeDetermine whether the subject should be allowed to poll
pipe.&mac.mpo;_check_pipe_readint
&mac.mpo;_check_pipe_readstruct ucred
*credstruct pipe
*pipestruct label
*pipelabel
-
+
&mac.thead;
credSubject credentialpipePipepipelabelPolicy label associated with
pipeDetermine whether the subject should be allowed read
access to pipe.&mac.mpo;_check_pipe_relabelint
&mac.mpo;_check_pipe_relabelstruct ucred
*credstruct pipe
*pipestruct label
*pipelabelstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialpipePipepipelabelCurrent policy label associated with
pipenewlabelLabel update to
pipelabelDetermine whether the subject should be allowed to
relabel pipe.&mac.mpo;_check_pipe_statint
&mac.mpo;_check_pipe_statstruct ucred
*credstruct pipe
*pipestruct label
*pipelabel
-
+
&mac.thead;
credSubject credentialpipePipepipelabelPolicy label associated with
pipeDetermine whether the subject should be allowed to
retrieve statistics related to
pipe.&mac.mpo;_check_pipe_writeint
&mac.mpo;_check_pipe_writestruct ucred
*credstruct pipe
*pipestruct label
*pipelabel
-
+
&mac.thead;
credSubject credentialpipePipepipelabelPolicy label associated with
pipeDetermine whether the subject should be allowed to write
to pipe.&mac.mpo;_check_socket_bindint
&mac.mpo;_check_socket_bindstruct ucred
*credstruct socket
*socketstruct label
*socketlabelstruct sockaddr
*sockaddr
-
+
&mac.thead;
credSubject credentialsocketSocket to be boundsocketlabelPolicy label for
socketsockaddrAddress of
socket&mac.mpo;_check_socket_connectint
&mac.mpo;_check_socket_connectstruct ucred
*credstruct socket
*socketstruct label
*socketlabelstruct sockaddr
*sockaddr
-
+
&mac.thead;
credSubject credentialsocketSocket to be connectedsocketlabelPolicy label for
socketsockaddrAddress of
socketDetermine whether the subject credential
(cred) can connect the passed socket
(socket) to the passed socket address
(sockaddr). Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatches,
EPERM for lack of privilege.&mac.mpo;_check_socket_receiveint
&mac.mpo;_check_socket_receivestruct ucred
*credstruct socket
*sostruct label
*socketlabel
-
+
&mac.thead;
credSubject credentialsoSocketsocketlabelPolicy label associated with
soDetermine whether the subject should be allowed to
receive information from the socket
so.&mac.mpo;_check_socket_sendint
&mac.mpo;_check_socket_sendstruct ucred
*credstruct socket
*sostruct label
*socketlabel
-
+
&mac.thead;
credSubject credentialsoSocketsocketlabelPolicy label associated with
soDetermine whether the subject should be allowed to send
information across the socket
so.&mac.mpo;_check_cred_visibleint
&mac.mpo;_check_cred_visiblestruct ucred
*u1struct ucred
*u2
-
+
&mac.thead;
u1Subject credentialu2Object credentialDetermine whether the subject credential
u1 can see other
subjects with the passed subject credential
u2. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatches,
EPERM for lack of privilege, or
ESRCH to hide visibility. This call
may be made in a number of situations, including
inter-process status sysctls used by ps,
and in procfs lookups.&mac.mpo;_check_socket_visibleint
&mac.mpo;_check_socket_visiblestruct ucred
*credstruct socket
*socketstruct label
*socketlabel
-
+
&mac.thead;
credSubject credentialsocketObject; socketsocketlabelPolicy label for
socket&mac.mpo;_check_ifnet_relabelint
&mac.mpo;_check_ifnet_relabelstruct ucred
*credstruct ifnet
*ifnetstruct label
*ifnetlabelstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialifnetObject; network interfaceifnetlabelExisting policy label for
ifnetnewlabelPolicy label update to later be applied to
ifnetDetermine whether the subject credential can relabel the
passed network interface to the passed label update.&mac.mpo;_check_socket_relabelint
&mac.mpo;_check_socket_relabelstruct ucred
*credstruct socket
*socketstruct label
*socketlabelstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialsocketObject; socketsocketlabelExisting policy label for
socketnewlabelLabel update to later be applied to
socketlabelDetermine whether the subject credential can relabel the
passed socket to the passed label update.&mac.mpo;_check_cred_relabelint
&mac.mpo;_check_cred_relabelstruct ucred
*credstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialnewlabelLabel update to later be applied to
credDetermine whether the subject credential can relabel
itself to the passed label update.&mac.mpo;_check_vnode_relabelint
&mac.mpo;_check_vnode_relabelstruct ucred
*credstruct vnode
*vpstruct label
*vnodelabelstruct label
*newlabel
-
+
&mac.thead;
credSubject credentialImmutablevpObject; vnodeLockedvnodelabelExisting policy label for
vpnewlabelPolicy label update to later be applied to
vpDetermine whether the subject credential can relabel the
passed vnode to the passed label update.&mac.mpo;_check_mount_statint &mac.mpo;_check_mount_statstruct ucred
*credstruct mount
*mpstruct label
*mountlabel
-
+
&mac.thead;
credSubject credentialmpObject; file system mountmountlabelPolicy label for
mpDetermine whether the subject credential can see the
results of a statfs performed on the file system. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatches
or EPERM for lack of privilege. This
call may be made in a number of situations, including during
invocations of &man.statfs.2; and related calls, as well as to
determine what file systems to exclude from listings of file
systems, such as when &man.getfsstat.2; is invoked. &mac.mpo;_check_proc_debugint
&mac.mpo;_check_proc_debugstruct ucred
*credstruct proc
*proc
-
+
&mac.thead;
credSubject credentialImmutableprocObject; processDetermine whether the subject credential can debug the
passed process. Return 0 for
success, or an errno value for failure.
Suggested failure: EACCES for label
mismatch, EPERM for lack of
privilege, or ESRCH to hide
visibility of the target. This call may be made in a number
of situations, including use of the &man.ptrace.2; and
&man.ktrace.2; APIs, as well as for some types of procfs
operations.&mac.mpo;_check_vnode_accessint
&mac.mpo;_check_vnode_accessstruct ucred
*credstruct vnode
*vpstruct label
*labelint flags
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for
vpflags&man.access.2; flagsDetermine how invocations of &man.access.2; and related
calls by the subject credential should return when performed
on the passed vnode using the passed access flags. This
should generally be implemented using the same semantics
used in &mac.mpo;_check_vnode_open.
Return 0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatches
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_chdirint
&mac.mpo;_check_vnode_chdirstruct ucred
*credstruct vnode
*dvpstruct label
*dlabel
-
+
&mac.thead;
credSubject credentialdvpObject; vnode to &man.chdir.2; intodlabelPolicy label for
dvpDetermine whether the subject credential can change the
process working directory to the passed vnode. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_chrootint
&mac.mpo;_check_vnode_chrootstruct ucred
*credstruct vnode
*dvpstruct label
*dlabel
-
+
&mac.thead;
credSubject credentialdvpDirectory vnodedlabelPolicy label associated with
dvpDetermine whether the subject should be allowed to
&man.chroot.2; into the specified directory
(dvp).&mac.mpo;_check_vnode_createint
&mac.mpo;_check_vnode_createstruct ucred
*credstruct vnode
*dvpstruct label
*dlabelstruct componentname
*cnpstruct vattr
*vap
-
+
&mac.thead;
credSubject credentialdvpObject; vnodedlabelPolicy label for
dvpcnpComponent name for
dvpvapvnode attributes for vapDetermine whether the subject credential can create a
vnode with the passed parent directory, passed name
information, and passed attribute information. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES. for label mismatch,
or EPERM for lack of privilege.
This call may be made in a number of situations, including
as a result of calls to &man.open.2; with
O_CREAT, &man.mknod.2;, &man.mkfifo.2;, and
others.&mac.mpo;_check_vnode_deleteint
&mac.mpo;_check_vnode_deletestruct ucred
*credstruct vnode
*dvpstruct label
*dlabelstruct vnode
*vpvoid *labelstruct componentname
*cnp
-
+
&mac.thead;
credSubject credentialdvpParent directory vnodedlabelPolicy label for
dvpvpObject; vnode to deletelabelPolicy label for
vpcnpComponent name for
vpDetermine whether the subject credential can delete a
vnode from the passed parent directory and passed name
information. Return 0 for
success, or an errno value for failure.
Suggested failure: EACCES for label
mismatch, or EPERM for lack of
privilege. This call may be made in a number of situations,
including as a result of calls to &man.unlink.2; and
&man.rmdir.2;. Policies implementing this entry point
should also implement
mpo_check_rename_to to authorize
deletion of objects as a result of being the target of a
rename.&mac.mpo;_check_vnode_deleteaclint
&mac.mpo;_check_vnode_deleteaclstruct ucred *credstruct vnode *vpstruct label *labelacl_type_t type
-
+
&mac.thead;
credSubject credentialImmutablevpObject; vnodeLockedlabelPolicy label for
vptypeACL typeDetermine whether the subject credential can delete the
ACL of passed type from the passed vnode. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_execint
&mac.mpo;_check_vnode_execstruct ucred
*credstruct vnode
*vpstruct label
*label
-
+
&mac.thead;
credSubject credentialvpObject; vnode to executelabelPolicy label for
vpDetermine whether the subject credential can execute the
passed vnode. Determination of execute privilege is made
separately from decisions about any transitioning event.
Return 0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_getaclint
&mac.mpo;_check_vnode_getaclstruct ucred
*credstruct vnode
*vpstruct label
*labelacl_type_t
type
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for
vptypeACL typeDetermine whether the subject credential can retrieve
the ACL of passed type from the passed vnode. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_getextattrint
&mac.mpo;_check_vnode_getextattrstruct ucred
*credstruct vnode
*vpstruct label
*labelint
attrnamespaceconst char
*namestruct uio
*uio
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for
vpattrnamespaceExtended attribute namespacenameExtended attribute nameuioI/O structure pointer; see &man.uio.9;Determine whether the subject credential can retrieve
the extended attribute with the passed namespace and name
from the passed vnode. Policies implementing labeling using
extended attributes may be interested in special handling of
operations on those extended attributes. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_linkint
&mac.mpo;_check_vnode_linkstruct ucred
*credstruct vnode
*dvpstruct label
*dlabelstruct vnode
*vpstruct label
*labelstruct componentname
*cnp
-
+
&mac.thead;
credSubject credentialdvpDirectory vnodedlabelPolicy label associated with
dvpvpLink destination vnodelabelPolicy label associated with
vpcnpComponent name for the link being createdDetermine whether the subject should be allowed to
create a link to the vnode vp with
the name specified by cnp.&mac.mpo;_check_vnode_mmapint
&mac.mpo;_check_vnode_mmapstruct ucred
*credstruct vnode
*vpstruct label
*labelint prot
-
+
&mac.thead;
credSubject credentialvpVnode to maplabelPolicy label associated with
vpprotMmap protections (see &man.mmap.2;)Determine whether the subject should be allowed to map
the vnode vp with the protections
specified in prot.&mac.mpo;_check_vnode_mmap_downgradevoid
&mac.mpo;_check_vnode_mmap_downgradestruct ucred
*credstruct vnode
*vpstruct label
*labelint *prot
-
+
&mac.thead;
credSee
.vplabelprotMmap protections to be downgradedDowngrade the mmap protections based on the subject and
object labels.&mac.mpo;_check_vnode_mprotectint
&mac.mpo;_check_vnode_mprotectstruct ucred
*credstruct vnode
*vpstruct label
*labelint prot
-
+
&mac.thead;
credSubject credentialvpMapped vnodeprotMemory protectionsDetermine whether the subject should be allowed to
set the specified memory protections on memory mapped from
the vnode vp.&mac.mpo;_check_vnode_pollint
&mac.mpo;_check_vnode_pollstruct ucred
*active_credstruct ucred
*file_credstruct vnode
*vpstruct label
*label
-
+
&mac.thead;
active_credSubject credentialfile_credCredential associated with the struct
filevpPolled vnodelabelPolicy label associated with
vpDetermine whether the subject should be allowed to poll
the vnode vp.&mac.mpo;_check_vnode_rename_fromint
&mac.mpo;_vnode_rename_fromstruct ucred
*credstruct vnode
*dvpstruct label
*dlabelstruct vnode
*vpstruct label
*labelstruct componentname
*cnp
-
+
&mac.thead;
credSubject credentialdvpDirectory vnodedlabelPolicy label associated with
dvpvpVnode to be renamedlabelPolicy label associated with
vpcnpComponent name for
vpDetermine whether the subject should be allowed to
rename the vnode vp to something
else.&mac.mpo;_check_vnode_rename_toint
&mac.mpo;_check_vnode_rename_tostruct ucred
*credstruct vnode
*dvpstruct label
*dlabelstruct vnode
*vpstruct label
*labelint samedirstruct componentname
*cnp
-
+
&mac.thead;
credSubject credentialdvpDirectory vnodedlabelPolicy label associated with
dvpvpOverwritten vnodelabelPolicy label associated with
vpsamedirBoolean; 1 if the source and
destination directories are the samecnpDestination component nameDetermine whether the subject should be allowed to
rename to the vnode vp, into the
directory dvp, or to the name
represented by cnp. If there is no
existing file to overwrite, vp and
label will be NULL.&mac.mpo;_check_socket_listenint
&mac.mpo;_check_socket_listenstruct ucred
*credstruct socket
*socketstruct label
*socketlabel
-
+
&mac.thead;
credSubject credentialsocketObject; socketsocketlabelPolicy label for
socketDetermine whether the subject credential can listen on
the passed socket. Return 0 for
success, or an errno value for failure.
Suggested failure: EACCES for label
mismatch, or EPERM for lack of
privilege.&mac.mpo;_check_vnode_lookupint
&mac.mpo;_check_vnode_lookupstruct ucred
*credstruct vnode
*dvpstruct label
*dlabelstruct componentname
*cnp
-
+
&mac.thead;
credSubject credentialdvpObject; vnodedlabelPolicy label for
dvpcnpComponent name being looked upDetermine whether the subject credential can perform a
lookup in the passed directory vnode for the passed name.
Return 0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_openint
&mac.mpo;_check_vnode_openstruct ucred
*credstruct vnode
*vpstruct label
*labelint
acc_mode
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for
vpacc_mode&man.open.2; access modeDetermine whether the subject credential can perform an
open operation on the passed vnode with the passed access
mode. Return 0 for success, or
an errno value for failure. Suggested failure:
EACCES for label mismatch, or
EPERM for lack of privilege.&mac.mpo;_check_vnode_readdirint
&mac.mpo;_check_vnode_readdirstruct ucred
*credstruct vnode
*dvpstruct label
*dlabel
-
+
&mac.thead;
credSubject credentialdvpObject; directory vnodedlabelPolicy label for
dvpDetermine whether the subject credential can perform a
readdir operation on the passed
directory vnode. Return 0 for
success, or an errno value for failure.
Suggested failure: EACCES for label
mismatch, or EPERM for lack of
privilege.&mac.mpo;_check_vnode_readlinkint
&mac.mpo;_check_vnode_readlinkstruct ucred
*credstruct vnode
*vpstruct label
*label
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for
vpDetermine whether the subject credential can perform a
readlink operation on the passed
symlink vnode. Return 0 for
success, or an errno value for failure.
Suggested failure: EACCES for label
mismatch, or EPERM for lack of
privilege. This call may be made in a number of situations,
including an explicit readlink call by
the user process, or as a result of an implicit
readlink during a name lookup by the
process.&mac.mpo;_check_vnode_revokeint
&mac.mpo;_check_vnode_revokestruct ucred
*credstruct vnode
*vpstruct label
*label
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for
vpDetermine whether the subject credential can revoke
access to the passed vnode. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_setaclint
&mac.mpo;_check_vnode_setaclstruct ucred
*credstruct vnode
*vpstruct label
*labelacl_type_t
typestruct acl
*acl
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for
vptypeACL typeaclACLDetermine whether the subject credential can set the
passed ACL of passed type on the passed vnode. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_setextattrint
&mac.mpo;_check_vnode_setextattrstruct ucred
*credstruct vnode
*vpstruct label
*labelint
attrnamespaceconst char
*namestruct uio
*uio
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for vpattrnamespaceExtended attribute namespacenameExtended attribute nameuioI/O structure pointer; see &man.uio.9;Determine whether the subject credential can set the
extended attribute of passed name and passed namespace on
the passed vnode. Policies implementing security labels
backed into extended attributes may want to provide
additional protections for those attributes. Additionally,
policies should avoid making decisions based on the data
referenced from uio, as there is a
potential race condition between this check and the actual
operation. The uio may also be
NULL if a delete operation is being
performed. Return 0 for success,
or an errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_setflagsint
&mac.mpo;_check_vnode_setflagsstruct ucred
*credstruct vnode
*vpstruct label
*labelu_long flags
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for
vpflagsFile flags; see &man.chflags.2;Determine whether the subject credential can set the
passed flags on the passed vnode. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_setmodeint
&mac.mpo;_check_vnode_setmodestruct ucred
*credstruct vnode
*vpstruct label
*labelmode_t mode
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for vpmodeFile mode; see &man.chmod.2;Determine whether the subject credential can set the
passed mode on the passed vnode. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_vnode_setownerint
&mac.mpo;_check_vnode_setownerstruct ucred
*credstruct vnode
*vpstruct label
*labeluid_t uidgid_t gid
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for vpuidUser IDgidGroup IDDetermine whether the subject credential can set the
passed uid and passed gid as file uid and file gid on the
passed vnode. The IDs may be set to (-1)
to request no update. Return 0
for success, or an errno value for
failure. Suggested failure: EACCES
for label mismatch, or EPERM for lack
of privilege.&mac.mpo;_check_vnode_setutimesint
&mac.mpo;_check_vnode_setutimesstruct ucred
*credstruct vnode
*vpstruct label
*labelstruct timespec
atimestruct timespec
mtime
-
+
&mac.thead;
credSubject credentialvpObject; vplabelPolicy label for
vpatimeAccess time; see &man.utimes.2;mtimeModification time; see &man.utimes.2;Determine whether the subject credential can set the
passed access timestamps on the passed vnode. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_proc_schedint
&mac.mpo;_check_proc_schedstruct ucred
*ucredstruct proc
*proc
-
+
&mac.thead;
credSubject credentialprocObject; processDetermine whether the subject credential can change the
scheduling parameters of the passed process. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
EPERM for lack of privilege, or
ESRCH to limit visibility.See &man.setpriority.2; for more information.&mac.mpo;_check_proc_signalint
&mac.mpo;_check_proc_signalstruct ucred
*credstruct proc
*procint signal
-
+
&mac.thead;
credSubject credentialprocObject; processsignalSignal; see &man.kill.2;Determine whether the subject credential can deliver the
passed signal to the passed process. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
EPERM for lack of privilege, or
ESRCH to limit visibility.&mac.mpo;_check_vnode_statint
&mac.mpo;_check_vnode_statstruct ucred
*credstruct vnode
*vpstruct label
*label
-
+
&mac.thead;
credSubject credentialvpObject; vnodelabelPolicy label for
vpDetermine whether the subject credential can
stat the passed vnode. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatch,
or EPERM for lack of
privilege.See &man.stat.2; for more information.&mac.mpo;_check_ifnet_transmitint
&mac.mpo;_check_ifnet_transmitstruct ucred
*credstruct ifnet
*ifnetstruct label
*ifnetlabelstruct mbuf
*mbufstruct label
*mbuflabel
-
+
&mac.thead;
credSubject credentialifnetNetwork interfaceifnetlabelPolicy label for
ifnetmbufObject; mbuf to be sentmbuflabelPolicy label for
mbufDetermine whether the network interface can transmit the
passed mbuf. Return 0 for
success, or an errno value for failure.
Suggested failure: EACCES for label
mismatch, or EPERM for lack of
privilege.&mac.mpo;_check_socket_deliverint
&mac.mpo;_check_socket_deliverstruct ucred
*credstruct ifnet
*ifnetstruct label
*ifnetlabelstruct mbuf
*mbufstruct label
*mbuflabel
-
+
&mac.thead;
credSubject credentialifnetNetwork interfaceifnetlabelPolicy label for
ifnetmbufObject; mbuf to be deliveredmbuflabelPolicy label for
mbufDetermine whether the socket may receive the datagram
stored in the passed mbuf header. Return
0 for success, or an
errno value for failure. Suggested
failures: EACCES for label mismatch,
or EPERM for lack of
privilege.&mac.mpo;_check_socket_visibleint
&mac.mpo;_check_socket_visiblestruct ucred
*credstruct socket
*sostruct label
*socketlabel
-
+
&mac.thead;
credSubject credentialImmutablesoObject; socketsocketlabelPolicy label for
soDetermine whether the subject credential cred can "see"
the passed socket (socket) using
system monitoring functions, such as those employed by
&man.netstat.8; and &man.sockstat.1;. Return
0 for success, or an
errno value for failure. Suggested
failure: EACCES for label mismatches,
EPERM for lack of privilege, or
ESRCH to hide visibility.&mac.mpo;_check_system_acctint
&mac.mpo;_check_system_acctstruct ucred
*ucredstruct vnode
*vpstruct label
*vlabel
-
+
&mac.thead;
ucredSubject credentialvpAccounting file; &man.acct.5;vlabelLabel associated with
vpDetermine whether the subject should be allowed to
enable accounting, based on its label and the label of the
accounting log file.&mac.mpo;_check_system_nfsdint
&mac.mpo;_check_system_nfsdstruct ucred
*cred
-
+
&mac.thead;
credSubject credentialDetermine whether the subject should be allowed to call
&man.nfssvc.2;.&mac.mpo;_check_system_rebootint
&mac.mpo;_check_system_rebootstruct ucred
*credint howto
-
+
&mac.thead;
credSubject credentialhowtohowto parameter from
&man.reboot.2;Determine whether the subject should be allowed to
reboot the system in the specified manner.&mac.mpo;_check_system_settimeint
&mac.mpo;_check_system_settimestruct ucred
*cred
-
+
&mac.thead;
credSubject credentialDetermine whether the user should be allowed to set the
system clock.&mac.mpo;_check_system_swaponint
&mac.mpo;_check_system_swaponstruct ucred
*credstruct vnode
*vpstruct label
*vlabel
-
+
&mac.thead;
credSubject credentialvpSwap devicevlabelLabel associated with
vpDetermine whether the subject should be allowed to add
vp as a swap device.&mac.mpo;_check_system_sysctlint
&mac.mpo;_check_system_sysctlstruct ucred
*credint *nameu_int *namelenvoid *oldsize_t
*oldlenpint inkernelvoid *newsize_t newlen
-
+
&mac.thead;
credSubject credentialnameSee &man.sysctl.3;namelenoldoldlenpinkernelBoolean; 1 if called from
kernelnewSee &man.sysctl.3;newlenDetermine whether the subject should be allowed to make
the specified &man.sysctl.3; transaction.Label Management CallsRelabel events occur when a user process has requested
that the label on an object be modified. A two-phase update
occurs: first, an access control check will be performed to
determine if the update is both valid and permitted, and then
the update itself is performed via a separate entry point.
Relabel entry points typically accept the object, object label
reference, and an update label submitted by the process.
Memory allocation during relabel is discouraged, as relabel
calls are not permitted to fail (failure should be reported
earlier in the relabel check).Userland ArchitectureThe TrustedBSD MAC Framework includes a number of
policy-agnostic elements, including MAC library interfaces
for abstractly managing labels, modifications to the system
credential management and login libraries to support the
assignment of MAC labels to users, and a set of tools to
monitor and modify labels on processes, files, and network
interfaces. More details on the user architecture will
be added to this section in the near future.APIs for Policy-Agnostic Label ManagementThe TrustedBSD MAC Framework provides a number of
library and system calls permitting applications to
manage MAC labels on objects using a policy-agnostic
interface. This permits applications to manipulate
labels for a variety of policies without being
written to support specific policies. These interfaces
are used by general-purpose tools such as &man.ifconfig.8;,
&man.ls.1; and &man.ps.1; to view labels on network
interfaces, files, and processes. The APIs also support
MAC management tools including &man.getfmac.8;,
&man.getpmac.8;, &man.setfmac.8;, &man.setfsmac.8;,
and &man.setpmac.8;. The MAC APIs are documented in
&man.mac.3;.Applications handle MAC labels in two forms: an
internalized form used to return and set labels on
processes and objects (mac_t),
and externalized form based on C strings appropriate for
storage in configuration files, display to the user, or
input from the user. Each MAC label contains a number of
elements, each consisting of a name and value pair.
Policy modules in the kernel bind to specific names
and interpret the values in policy-specific ways. In
the externalized string form, labels are represented
by a comma-delimited list of name and value pairs separated
by the / character. Labels may be
directly converted to and from text using provided APIs;
when retrieving labels from the kernel, internalized
label storage must first be prepared for the desired
label element set. Typically, this is done in one of
two ways: using &man.mac.prepare.3; and an arbitrary
list of desired label elements, or one of the variants
of the call that loads a default element set from the
&man.mac.conf.5; configuration file. Per-object
defaults permit application writers to usefully display
labels associated with objects without being aware of
the policies present in the system.Currently, direct manipulation of label elements
other than by conversion to a text string, string editing,
and conversion back to an internalized label is not supported
by the MAC library. Such interfaces may be added in the
future if they prove necessary for application
writers.Binding of Labels to UsersThe standard user context management interface,
&man.setusercontext.3;, has been modified to retrieve
MAC labels associated with a user's class from
&man.login.conf.5;. These labels are then set along
with other user context when either
LOGIN_SETALL is specified, or when
LOGIN_SETMAC is explicitly
specified.It is expected that, in a future version of FreeBSD,
the MAC label database will be separated from the
login.conf user class abstraction,
and be maintained in a separate database. However, the
&man.setusercontext.3; API should remain the same
following such a change.ConclusionThe TrustedBSD MAC framework permits kernel modules to
augment the system security policy in a highly integrated
manner. They may do this based on existing object properties,
or based on label data that is maintained with the assistance of
the MAC framework. The framework is sufficiently flexible to
implement a variety of policy types, including information flow
security policies such as MLS and Biba, as well as policies
based on existing BSD credentials or file protections. Policy
authors may wish to consult this documentation as well as
existing security modules when implementing a new security
service.
diff --git a/en_US.ISO8859-1/books/developers-handbook/secure/chapter.sgml b/en_US.ISO8859-1/books/developers-handbook/secure/chapter.sgml
index 05022487d6..79cddbeb80 100644
--- a/en_US.ISO8859-1/books/developers-handbook/secure/chapter.sgml
+++ b/en_US.ISO8859-1/books/developers-handbook/secure/chapter.sgml
@@ -1,525 +1,525 @@
MurrayStockelyContributed by Secure ProgrammingSynopsisThis chapter describes some of the security issues that
have plagued &unix; programmers for decades and some of the new
tools available to help programmers avoid writing exploitable
code.Secure Design
MethodologyWriting secure applications takes a very scrutinous and
pessimistic outlook on life. Applications should be run with
the principle of least privilege so that no
process is ever running with more than the bare minimum access
that it needs to accomplish its function. Previously tested
code should be reused whenever possible to avoid common
mistakes that others may have already fixed.One of the pitfalls of the &unix; environment is how easy it
is to make assumptions about the sanity of the environment.
Applications should never trust user input (in all its forms),
system resources, inter-process communication, or the timing of
events. &unix; processes do not execute synchronously so logical
operations are rarely atomic.Buffer OverflowsBuffer Overflows have been around since the very
beginnings of the Von-Neuman architecture.
buffer overflowVon-Neuman
They first gained widespread notoriety in 1988 with the Morris
Internet worm. Unfortunately, the same basic attack remains
Morris Internet worm
effective today. Of the 17 CERT security advisories of 1999, 10
CERTsecurity advisories
of them were directly caused by buffer-overflow software bugs.
By far the most common type of buffer overflow attack is based
on corrupting the stack.stackargumentsMost modern computer systems use a stack to pass arguments
to procedures and to store local variables. A stack is a last
in first out (LIFO) buffer in the high memory area of a process
image. When a program invokes a function a new "stack frame" is
LIFOprocess imagestack pointer
created. This stack frame consists of the arguments passed to
the function as well as a dynamic amount of local variable
space. The "stack pointer" is a register that holds the current
stack framestack pointer
location of the top of the stack. Since this value is
constantly changing as new values are pushed onto the top of the
stack, many implementations also provide a "frame pointer" that
is located near the beginning of a stack frame so that local
variables can more easily be addressed relative to this
value. The return address for function
frame pointerprocess imageframe pointerreturn addressstack-overflow
calls is also stored on the stack, and this is the cause of
stack-overflow exploits since overflowing a local variable in a
function can overwrite the return address of that function,
potentially allowing a malicious user to execute any code he or
she wants.Although stack-based attacks are by far the most common,
it would also be possible to overrun the stack with a heap-based
(malloc/free) attack.The C programming language does not perform automatic
bounds checking on arrays or pointers as many other languages
do. In addition, the standard C library is filled with a
handful of very dangerous functions.
-
+ strcpy(char *dest, const char
*src)May overflow the dest bufferstrcat(char *dest, const char
*src)May overflow the dest buffergetwd(char *buf)May overflow the buf buffergets(char *s)May overflow the s buffer[vf]scanf(const char *format,
...)May overflow its arguments.realpath(char *path, char
resolved_path[])May overflow the path buffer[v]sprintf(char *str, const char
*format, ...)May overflow the str buffer.Example Buffer OverflowThe following example code contains a buffer overflow
designed to overwrite the return address and skip the
instruction immediately following the function call. (Inspired
by )#include stdio.h
void manipulate(char *buffer) {
char newbuffer[80];
strcpy(newbuffer,buffer);
}
int main() {
char ch,buffer[4096];
int i=0;
while ((buffer[i++] = getchar()) != '\n') {};
i=1;
manipulate(buffer);
i=2;
printf("The value of i is : %d\n",i);
return 0;
}Let us examine what the memory image of this process would
look like if we were to input 160 spaces into our little program
before hitting return.[XXX figure here!]Obviously more malicious input can be devised to execute
actual compiled instructions (such as exec(/bin/sh)).Avoiding Buffer OverflowsThe most straightforward solution to the problem of
stack-overflows is to always use length restricted memory and
string copy functions. strncpy and
strncat are part of the standard C library.
string copy functionsstrncpystring copy functionsstrncat
These functions accept a length value as a parameter which
should be no larger than the size of the destination buffer.
These functions will then copy up to `length' bytes from the
source to the destination. However there are a number of
problems with these functions. Neither function guarantees NUL
termination if the size of the input buffer is as large as the
NUL termination
destination. The length parameter is also used inconsistently
between strncpy and strncat so it is easy for programmers to get
confused as to their proper usage. There is also a significant
performance loss compared to strcpy when
copying a short string into a large buffer since
strncpy NUL fills up the size
specified.In OpenBSD, another memory copy implementation has been
OpenBSD
created to get around these problem. The
strlcpy and strlcat
functions guarantee that they will always null terminate the
destination string when given a non-zero length argument. For
more information about these functions see . The OpenBSD strlcpy and
strlcat instructions have been in FreeBSD
since 3.3.string copy functionsstrlcpystring copy functionsstrlcatCompiler based run-time bounds checkingbounds checkingcompiler-basedUnfortunately there is still a very large assortment of
code in public use which blindly copies memory around without
using any of the bounded copy routines we just discussed.
Fortunately, there is another solution. Several compiler
add-ons and libraries exist to do Run-time bounds checking in
C/C++.StackGuardgccStackGuard is one such add-on that is implemented as a
small patch to the gcc code generator. From the StackGuard
website:
"StackGuard detects and defeats stack
smashing attacks by protecting the return address on the stack
from being altered. StackGuard places a "canary" word next to
the return address when a function is called. If the canary
word has been altered when the function returns, then a stack
smashing attack has been attempted, and the program responds
by emitting an intruder alert into syslog, and then
halts."
"StackGuard is implemented as a small patch
to the gcc code generator, specifically the function_prolog()
and function_epilog() routines. function_prolog() has been
enhanced to lay down canaries on the stack when functions
start, and function_epilog() checks canary integrity when the
function exits. Any attempt at corrupting the return address
is thus detected before the function
returns."
buffer overflowRecompiling your application with StackGuard is an
effective means of stopping most buffer-overflow attacks, but
it can still be compromised.Library based run-time bounds checkingbounds checkinglibrary-basedCompiler-based mechanisms are completely useless for
binary-only software for which you cannot recompile. For
these situations there are a number of libraries which
re-implement the unsafe functions of the C-library
(strcpy, fscanf,
getwd, etc..) and ensure that these
functions can never write past the stack pointer.libsafelibverifylibparanoiaUnfortunately these library-based defenses have a number
of shortcomings. These libraries only protect against a very
small set of security related issues and they neglect to fix
the actual problem. These defenses may fail if the
application was compiled with -fomit-frame-pointer. Also, the
LD_PRELOAD and LD_LIBRARY_PATH environment variables can be
overwritten/unset by the user.SetUID issuesseteuidThere are at least 6 different IDs associated with any
given process. Because of this you have to be very careful with
the access that your process has at any given time. In
particular, all seteuid applications should give up their
privileges as soon as it is no longer required.user IDsreal user IDuser IDseffective user IDThe real user ID can only be changed by a superuser
process. The login program sets this
when a user initially logs in and it is seldom changed.The effective user ID is set by the
exec() functions if a program has its
seteuid bit set. An application can call
seteuid() at any time to set the effective
user ID to either the real user ID or the saved set-user-ID.
When the effective user ID is set by exec()
functions, the previous value is saved in the saved set-user-ID.Limiting your program's environmentchroot()The traditional method of restricting a process
is with the chroot() system call. This
system call changes the root directory from which all other
paths are referenced for a process and any child processes. For
this call to succeed the process must have execute (search)
permission on the directory being referenced. The new
environment does not actually take effect until you
chdir() into your new environment. It
should also be noted that a process can easily break out of a
chroot environment if it has root privilege. This could be
accomplished by creating device nodes to read kernel memory,
attaching a debugger to a process outside of the jail, or in
many other creative ways.The behavior of the chroot() system
call can be controlled somewhat with the
kern.chroot_allow_open_directories sysctl
variable. When this value is set to 0,
chroot() will fail with EPERM if there are
any directories open. If set to the default value of 1, then
chroot() will fail with EPERM if there are
any directories open and the process is already subject to a
chroot() call. For any other value, the
check for open directories will be bypassed completely.FreeBSD's jail functionalityjailThe concept of a Jail extends upon the
chroot() by limiting the powers of the
superuser to create a true `virtual server'. Once a prison is
set up all network communication must take place through the
specified IP address, and the power of "root privilege" in this
jail is severely constrained.While in a prison, any tests of superuser power within the
kernel using the suser() call will fail.
However, some calls to suser() have been
changed to a new interface suser_xxx().
This function is responsible for recognizing or denying access
to superuser power for imprisoned processes.A superuser process within a jailed environment has the
power to:Manipulate credential with
setuid, seteuid,
setgid, setegid,
setgroups, setreuid,
setregid, setloginSet resource limits with setrlimitModify some sysctl nodes
(kern.hostname)chroot()Set flags on a vnode:
chflags,
fchflagsSet attributes of a vnode such as file
permission, owner, group, size, access time, and modification
time.Bind to privileged ports in the Internet
domain (ports < 1024)Jail is a very useful tool for
running applications in a secure environment but it does have
some shortcomings. Currently, the IPC mechanisms have not been
converted to the suser_xxx so applications
such as MySQL cannot be run within a jail. Superuser access
may have a very limited meaning within a jail, but there is
no way to specify exactly what "very limited" means.&posix;.1e Process CapabilitiesPOSIX.1e Process CapabilitiesTrustedBSD&posix; has released a working draft that adds event
auditing, access control lists, fine grained privileges,
information labeling, and mandatory access control.This is a work in progress and is the focus of the TrustedBSD project. Some
of the initial work has been committed to FreeBSD-current
(cap_set_proc(3)).TrustAn application should never assume that anything about the
users environment is sane. This includes (but is certainly not
limited to): user input, signals, environment variables,
resources, IPC, mmaps, the filesystem working directory, file
descriptors, the # of open files, etc.positive filteringdata validationYou should never assume that you can catch all forms of
invalid input that a user might supply. Instead, your
application should use positive filtering to only allow a
specific subset of inputs that you deem safe. Improper data
validation has been the cause of many exploits, especially with
CGI scripts on the world wide web. For filenames you need to be
extra careful about paths ("../", "/"), symbolic links, and
shell escape characters.Perl Taint modePerl has a really cool feature called "Taint" mode which
can be used to prevent scripts from using data derived outside
the program in an unsafe way. This mode will check command line
arguments, environment variables, locale information, the
results of certain syscalls (readdir(),
readlink(),
getpwxxx(), and all file input.Race ConditionsA race condition is anomalous behavior caused by the
unexpected dependence on the relative timing of events. In
other words, a programmer incorrectly assumed that a particular
event would always happen before another.race conditionssignalsrace conditionsaccess checksrace conditionsfile opensSome of the common causes of race conditions are signals,
access checks, and file opens. Signals are asynchronous events
by nature so special care must be taken in dealing with them.
Checking access with access(2) then
open(2) is clearly non-atomic. Users can
move files in between the two calls. Instead, privileged
applications should seteuid() and then call
open() directly. Along the same lines, an
application should always set a proper umask before
open() to obviate the need for spurious
chmod() calls.
diff --git a/en_US.ISO8859-1/books/fdp-primer/sgml-markup/chapter.sgml b/en_US.ISO8859-1/books/fdp-primer/sgml-markup/chapter.sgml
index 844e3d610f..ee88a035c6 100644
--- a/en_US.ISO8859-1/books/fdp-primer/sgml-markup/chapter.sgml
+++ b/en_US.ISO8859-1/books/fdp-primer/sgml-markup/chapter.sgml
@@ -1,2692 +1,2692 @@
SGML MarkupThis chapter describes the two markup languages you will encounter
when you contribute to the FreeBSD documentation project. Each section
describes the markup language, and details the markup that you are likely
to want to use, or that is already in use.These markup languages contain a large number of elements, and it can
be confusing sometimes to know which element to use for a particular
situation. This section goes through the elements you are most likely to
need, and gives examples of how you would use them.This is not an exhaustive list of elements, since
that would just reiterate the documentation for each language. The aim of
this section is to list those elements more likely to be useful to you.
If you have a question about how best to markup a particular piece of
content, please post it to the &a.doc;.Inline vs. blockIn the remainder of this document, when describing elements,
inline means that the element can occur within a
block element, and does not cause a line break. A
block element, by comparison, will cause a line
break (and other processing) when it is encountered.HTMLHTML, the HyperText Markup Language, is the markup language of
choice on the World Wide Web. More information can be found at
<URL:>.HTML is used to markup pages on the FreeBSD web site. It should not
(generally) be used to mark up other documentation,
since DocBook offers a
far richer set of elements to choose from. Consequently, you will
normally only encounter HTML pages if you are writing for the web
site.HTML has gone through a number of versions, 1, 2, 3.0, 3.2, and the
latest, 4.0 (available in both strict and
loose variants).The HTML DTDs are available from the ports collection in the
textproc/html port. They are automatically
installed as part of the textproc/docproj
port.Formal Public Identifier (FPI)There are a number of HTML FPIs, depending upon the version (also
known as the level) of HTML that you want to declare your document to
be compliant with.The majority of HTML documents on the FreeBSD web site comply with
the loose version of HTML 4.0.PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"Sectional elementsAn HTML document is normally split into two sections. The first
section, called the head, contains
meta-information about the document, such as its title, the name of
the author, the parent document, and so on. The second section, the
body, contains the content that will be displayed
to the user.These sections are indicated with head and
body elements respectively. These elements are
contained within the top-level html element.Normal HTML document structure<html>
<head>
<title>The document's title</title>
</head>
<body>
…
</body>
</html>Block elementsHeadingsHTML allows you to denote headings in your document, at up to
six different levels.The largest and most prominent heading is h1,
then h2, continuing down to
h6.The element's content is the text of the heading.h1, h2, etc.Use:First section
This is the heading for the first section
This is the heading for the first sub-section
This is the heading for the second section
]]>Generally, an HTML page should have one first level heading
(h1). This can contain many second level
headings (h2), which can in turn contain many
third level headings. Each
hn element should have
the same element, but one further up the hierarchy, preceding it.
Leaving gaps in the numbering is to be avoided.Bad ordering of
hn elementsUse:First section
Sub-section
]]>ParagraphsHTML supports a single paragraph element,
p.pUse:This is a paragraph. It can contain just about any
other element.
]]>
Block quotationsA block quotation is an extended quotation from another document
that should not appear within the current paragraph.blockquoteUse:A small excerpt from the US Constitution:
We the People of the United States, in Order to form
a more perfect Union, establish Justice, insure domestic
Tranquility, provide for the common defence, promote the general
Welfare, and secure the Blessings of Liberty to ourselves and our
Posterity, do ordain and establish this Constitution for the
United States of America.
]]>ListsYou can present the user with three types of lists, ordered,
unordered, and definition.Typically, each entry in an ordered list will be numbered, while
each entry in an unordered list will be preceded by a bullet point.
Definition lists are composed of two sections for each entry. The
first section is the term being defined, and the second section is
the definition of the term.Ordered lists are indicated by the ol
element, unordered lists by the ul element, and
definition lists by the dl element.Ordered and unordered lists contain listitems, indicated by the
li element. A listitem can contain textual
content, or it may be further wrapped in one or more
p elements.Definition lists contain definition terms
(dt) and definition descriptions
(dd). A definition term can only contain inline
elements. A definition description can contain other block
elements.ul and olUse:An unordered list. Listitems will probably be
preceded by bullets.
First item
Second item
Third item
An ordered list, with list items consisting of multiple
paragraphs. Each item (note: not each paragraph) will be
numbered.
This is the first item. It only has one paragraph.
This is the first paragraph of the second item.
This is the second paragraph of the second item.
This is the first and only paragraph of the third
item.
]]>Definition lists with dlUse:
Term 1
Paragraph 1 of definition 1.
Paragraph 2 of definition 1.
Term 2
Paragraph 1 of definition 2.
Term 3
Paragraph 1 of definition 3. Note that the <p>
element is not required in the single paragraph case.
]]>Pre-formatted textYou can indicate that text should be shown to the user exactly
as it is in the file. Typically, this means that the text is shown
in a fixed font, multiple spaces are not merged into one, and line
breaks in the text are significant.In order to do this, wrap the content in the
pre element.preYou could use pre to mark up an e-mail
message; From: nik@FreeBSD.org
To: freebsd-doc@FreeBSD.org
Subject: New documentation available
There is a new copy of my primer for contributors to the FreeBSD
Documentation Project available at
Comments appreciated.
N]]>TablesMost text-mode browsers (such as Lynx) do not render tables
particularly effectively. If you are relying on the tabular
display of your content, you should consider using alternative
markup to prevent confusion.Mark up tabular information using the table
element. A table consists of one or more table rows
(tr), each containing one or more cells of table
data (td). Each cell can contain other block
elements, such as paragraphs or lists. It can also contain another
table (this nesting can repeat indefinitely). If the cell only
contains one paragraph then you do not need to include the
p element.Simple use of tableUse:This is a simple 2x2 table.
Top left cell
Top right cell
Bottom left cell
Bottom right cell
]]>A cell can span multiple rows and columns. To indicate this,
add the rowspan and/or colspan
attributes, with values indicating the number of rows of columns
that should be spanned.Using rowspanUse:One tall thin cell on the left, two short cells next to
it on the right.
Long and thin
Top cell
Bottom cell
]]>Using colspanUse:One long cell on top, two short cells below it.
Top cell
Bottom left cell
Bottom right cell
]]>Using rowspan and
colspan togetherUse:On a 3x3 grid, the top left block is a 2x2 set of
cells merged into one. The other cells are normal.
Top left large cell
Top right cell
Middle right cell
Bottom left cell
Bottom middle cell
Bottom right cell
]]>In-line elementsEmphasising informationYou have two levels of emphasis available in HTML,
em and strong.
em is for a normal level of emphasis and
strong indicates stronger emphasis.Typically, em is rendered in italic and
strong is rendered in bold. This is not always
the case, however, and you should not rely on it.em and strongUse:This has been emphasised, while
this has been strongly emphasised.]]>Bold and italicsBecause HTML includes presentational markup, you can also
indicate that particular content should be rendered in bold or
italic. The elements are b and
i respectively.b and iThis is in bold, while this is
in italics.]]>Indicating fixed pitch textIf you have content that should be rendered in a fixed pitch
(typewriter) typeface, use tt (for
teletype).ttUse:This document was originally written by
Nik Clayton, who can be reached by e-mail as
nik@FreeBSD.org.]]>Content sizeYou can indicate that content should be shown in a larger or
smaller font. There are three ways of doing this.Use big and small
around the content you wish to change size. These tags can be
nested, so <big><big>This is much
bigger</big></big> is possible.Use font with the size
attribute set to +1 or -1
respectively. This has the same effect as using
big or small. However,
the use of this approach is deprecated.Use font with the size
attribute set to a number between 1 and 7. The default font size
is 3. This approach is deprecated.big, small, and
fontThe following fragments all do the same thing.This text is slightly smaller. But
this text is slightly bigger.
This text is slightly smaller. But
this text is slightly bigger
This text is slightly smaller. But
this text is slightly bigger.
]]>
LinksLinks are also in-line elements.Linking to other documents on the WWWIn order to include a link to another document on the WWW you
must know the URL of the document you want to link to.The link is indicated with a, and the
href attribute contains the URL of the target
document. The content of the element becomes the link, and is
normally indicated to the user in some way (underlining, change of
color, different mouse cursor when over the link, and so
on).Using <a href="...">Use:More information is available at the
FreeBSD web site.]]>These links will take the user to the top of the chosen
document.Linking to other parts of documentsLinking to a point within another document (or within the same
document) requires that the document author include anchors that you
can link to.Anchors are indicated with a and the
name attribute instead of
href.Using <a name="...">Use:This paragraph can be referenced
in other links with the name para1.]]>To link to a named part of a document, write a normal link to
that document, but include the name of the anchor after a
# symbol.Linking to a named part of another documentAssume that the para1 example resides in a
document called foo.html.More information can be found in the
first paragraph of
foo.html.]]>If you are linking to a named anchor within the same document
then you can omit the document's URL, and just include the name of
the anchor (with the preceding #).Linking to a named part of the same documentAssume that the para1 example resides in
this documentMore information can be found in the
first paragraph of this
document.]]>DocBookDocBook was originally developed by HaL Computer Systems and O'Reilly
& Associates to be a DTD for writing technical documentation
A short history can be found under
http://www.oasis-open.org/committees/docbook/intro.shtml.
. Since 1998 it is maintained by the
DocBook Technical Committee. As such, and unlike LinuxDoc
and HTML, DocBook is very heavily oriented towards markup that
describes what something is, rather than describing
how it should be presented.formal vs. informalSome elements may exist in two forms, formal
and informal. Typically, the formal version of
the element will consist of a title followed by the informal
version of the element. The informal version will not have a
title.The DocBook DTD is available from the ports collection in the
textproc/docbook port. It is automatically
installed as part of the textproc/docproj
port.FreeBSD extensionsThe FreeBSD Documentation Project has extended the DocBook DTD by
adding some new elements. These elements serve to make some of the
markup more precise.Where a FreeBSD specific element is listed below it is clearly
marked.Throughout the rest of this document, the term
DocBook is used to mean the FreeBSD extended DocBook
DTD.There is nothing about these extensions that is FreeBSD
specific, it was just felt that they were useful enhancements for
this particular project. Should anyone from any of the other *nix
camps (NetBSD, OpenBSD, Linux, …) be interested in
collaborating on a standard DocBook extension set, please get in
touch with &a.doceng;.The FreeBSD extensions are not (currently) in the ports
collection. They are stored in the FreeBSD CVS tree, as doc/share/sgml/freebsd.dtd.Formal Public Identifier (FPI)In compliance with the DocBook guidelines for writing FPIs for
DocBook customisations, the FPI for the FreeBSD extended DocBook DTD
is;PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN"Document structureDocBook allows you to structure your documentation in several
ways. In the FreeBSD Documentation Project we are using two primary
types of DocBook document: the book and the article.A book is organized into chapters. This is a
mandatory requirement. There may be parts between
the book and the chapter to provide another layer of organisation.
The Handbook is arranged in this way.A chapter may (or may not) contain one or more sections. These
are indicated with the sect1 element. If a section
contains another section then use the sect2
element, and so on, up to sect5.Chapters and sections contain the remainder of the content.An article is simpler than a book, and does not use chapters.
Instead, the content of an article is organized into one or more
sections, using the same sect1 (and
sect2 and so on) elements that are used in
books.Obviously, you should consider the nature of the documentation you
are writing in order to decide whether it is best marked up as a book
or an article. Articles are well suited to information that does not
need to be broken down into several chapters, and that is, relatively
speaking, quite short, at up to 20-25 pages of content. Books are
best suited to information that can be broken up into several
chapters, possibly with appendices and similar content as well.The FreeBSD
tutorials are all marked up as articles, while this
document, the FreeBSD
FAQ, and the FreeBSD Handbook are
all marked up as books.Starting a bookThe content of the book is contained within the
book element. As well as containing structural
markup, this element can contain elements that include additional
information about the book. This is either meta-information, used
for reference purposes, or additional content used to produce a
title page.This additional information should be contained within
bookinfo.Boilerplate book with
bookinfo<book>
<bookinfo>
<title>Your title here</title>
<author>
<firstname>Your first name</firstname>
<surname>Your surname</surname>
<affiliation>
<address><email>Your e-mail address</email></address>
</affiliation>
</author>
<copyright>
<year>1998</year>
<holder role="mailto:your e-mail address">Your name</holder>
</copyright>
<releaseinfo>$FreeBSD$</releaseinfo>
<abstract>
<para>Include an abstract of the book's contents here.</para>
</abstract>
</bookinfo>
…
</book>Starting an articleThe content of the article is contained within the
article element. As well as containing
structural markup, this element can contain elements that include
additional information about the article. This is either
meta-information, used for reference purposes, or additional content
used to produce a title page.This additional information should be contained within
articleinfo.Boilerplate article with
articleinfo<article>
<articleinfo>
<title>Your title here</title>
<author>
<firstname>Your first name</firstname>
<surname>Your surname</surname>
<affiliation>
<address><email>Your e-mail address</email></address>
</affiliation>
</author>
<copyright>
<year>1998</year>
<holder role="mailto:your e-mail address">Your name</holder>
</copyright>
<releaseinfo>$FreeBSD$</releaseinfo>
<abstract>
<para>Include an abstract of the article's contents here.</para>
</abstract>
</articleinfo>
…
</article>Indicating chaptersUse chapter to mark up your chapters. Each
chapter has a mandatory title. Articles do not
contain chapters, they are reserved for books.A simple chapterThe chapter's title
...
]]>A chapter cannot be empty; it must contain elements in addition
to title. If you need to include an empty
chapter then just use an empty paragraph.Empty chaptersThis is an empty chapter
]]>Sections below chaptersIn books, chapters may (but do not need to) be broken up into
sections, subsections, and so on. In articles, sections are the
main structural element, and each article must contain at least one
section. Use the
sectn element. The
n indicates the section number, which
identifies the section level.The first sectn is
sect1. You can have one or more of these in a
chapter. They can contain one or more sect2
elements, and so on, down to sect5.Sections in chaptersA sample chapterSome text in the chapter.First section (1.1)
…
Second section (1.2)First sub-section (1.2.1)First sub-sub-section (1.2.1.1)
…
Second sub-section (1.2.2)
…
]]>This example includes section numbers in the section titles.
You should not do this in your documents. Adding the section
numbers is carried out by the stylesheets (of which more
later), and you do not need to manage them yourself.Subdividing using partsYou can introduce another layer of organisation between
book and chapter with one or
more parts. This cannot be done in an
article.IntroductionOverview
...
What is FreeBSD?
...
History
...
]]>Block elementsParagraphsDocBook supports three types of paragraphs:
formalpara, para, and
simpara.Most of the time you will only need to use
para. formalpara includes a
title element, and simpara
disallows some elements from within para. Stick
with para.paraUse:This is a paragraph. It can contain just about any
other element. ]]>Appearance:This is a paragraph. It can contain just about any other
element.Block quotationsA block quotation is an extended quotation from another document
that should not appear within the current paragraph. You will
probably only need it infrequently.Blockquotes can optionally contain a title and an attribution
(or they can be left untitled and unattributed).blockquoteUse:A small excerpt from the US Constitution;
Preamble to the Constitution of the United StatesCopied from a web site somewhereWe the People of the United States, in Order to form a more perfect
Union, establish Justice, insure domestic Tranquility, provide for the
common defence, promote the general Welfare, and secure the Blessings
of Liberty to ourselves and our Posterity, do ordain and establish this
Constitution for the United States of America.
]]>Appearance:
Preamble to the Constitution of the United StatesCopied from a web site somewhereWe the People of the United States, in Order to form a more
perfect Union, establish Justice, insure domestic Tranquility,
provide for the common defence, promote the general Welfare, and
secure the Blessings of Liberty to ourselves and our Posterity,
do ordain and establish this Constitution for the United States
of America.
Tips, notes, warnings, cautions, important information and
sidebars.You may need to include extra information separate from the
main body of the text. Typically this is meta
information that the user should be aware of.Depending on the nature of the information, one of
tip, note,
warning, caution, and
important should be used. Alternatively, if the
information is related to the main text but is not one of the above,
use sidebar.The circumstances in which to choose one of these elements over
another is unclear. The DocBook documentation suggests;A Note is for information that should be heeded by all
readers.An Important element is a variation on Note.A Caution is for information regarding possible data loss
or software damage.A Warning is for information regarding possible hardware
damage or injury to life or limb.warningUse:Installing FreeBSD may make you want to delete Windows from your
hard disk.
]]>Installing FreeBSD may make you want to delete Windows from
your hard disk.Lists and proceduresYou will often need to list pieces of information to the user,
or present them with a number of steps that must be carried out in
order to accomplish a particular goal.In order to do this, use itemizedlist,
orderedlist, or
procedureThere are other types of
list element in DocBook, but we are not concerned with those at
the moment.itemizedlist and
orderedlist are similar to their counterparts in
HTML, ul and ol. Each one
consists of one or more listitem elements, and
each listitem contains one or more block
elements. The listitem elements are analogous to
HTML's li tags. However, unlike HTML, they are
required.procedure is slightly different. It consists
of steps, which may in turn consists of more
steps or substeps. Each
step contains block elements.itemizedlist,
orderedlist, and
procedureUse:This is the first itemized item.This is the second itemized item.This is the first ordered item.This is the second ordered item.Do this.Then do this.And now do this.]]>Appearance:This is the first itemized item.This is the second itemized item.This is the first ordered item.This is the second ordered item.Do this.Then do this.And now do this.Showing file samplesIf you want to show a fragment of a file (or perhaps a complete
file) to the user, wrap it in the programlisting
element.White space and line breaks within
programlistingare
significant. In particular, this means that the opening tag should
appear on the same line as the first line of the output, and the
closing tag should appear on the same line as the last line of the
output, otherwise spurious blank lines may be included.programlistingUse:When you have finished, your program should look like
this;
#include <stdio.h>
int
main(void)
{
printf("hello, world\n");
}]]>Notice how the angle brackets in the
#include line need to be referenced by their
entities instead of being included literally.Appearance:When you have finished, your program should look like
this;#include <stdio.h>
int
main(void)
{
printf("hello, world\n");
}CalloutsA callout is a mechanism for referring back to an earlier piece
of text or specific position within an earlier example without
linking to it within the text.To do this, mark areas of interest in your example
(programlisting,
literallayout, or whatever) with the
co element. Each element must have a unique
id assigned to it. After the example include a
calloutlist that refers back to the example and
provides additional commentary.co and
calloutlistWhen you have finished, your program should look like
this;
#include <stdio.h>
int
main(void)
{
printf("hello, world\n");
}Includes the standard IO header file.Specifies that main() returns an
int.The printf() call that writes
hello, world to standard output.]]>Appearance:When you have finished, your program should look like
this;#include <stdio.h>
int
main(void)
{
printf("hello, world\n");
}Includes the standard IO header file.Specifies that main() returns an
int.The printf() call that writes
hello, world to standard output.TablesUnlike HTML, you do not need to use tables for layout purposes,
as the stylesheet handles those issues for you. Instead, just use
tables for marking up tabular data.In general terms (and see the DocBook documentation for more
detail) a table (which can be either formal or informal) consists of
a table element. This contains at least one
tgroup element, which specifies (as an attribute)
the number of columns in this table group. Within the tablegroup
you can then have one thead element, which
contains elements for the table headings (column headings), and one
tbody which contains the body of the
table.Both tgroup and thead
contain row elements, which in turn contain
entry elements. Each entry
element specifies one cell in the table.informaltableUse:
-
+ This is column head 1This is column head 2Row 1, column 1Row 1, column 2Row 2, column 1Row 2, column 2
]]>Appearance:
-
+ This is column head 1This is column head 2Row 1, column 1Row 1, column 2Row 2, column 1Row 2, column 2If you do not want a border around the table the
frame attribute can be added to the
informaltable element with a value of
none (i.e., <informaltable
frame="none">).Tables where frame="none"Appearance:This is column head 1This is column head 2Row 1, column 1Row 1, column 2Row 2, column 1Row 2, column 2Examples for the user to followA lot of the time you need to show examples for the user to
follow. Typically, these will consist of dialogs with the computer;
the user types in a command, the user gets a response back, they
type in another command, and so on.A number of distinct elements and entities come into play
here.screenEverything the user sees in this example will be on the
computer screen, so the next element is
screen.Within screen, white space is
significant.prompt,
&prompt.root; and
&prompt.user;Some of the things the user will be seeing on the screen
are prompts from the computer (either from the operating system, command
shell, or application). These should be marked up using
prompt.As a special case, the two shell prompts for the normal
user and the root user have been provided as entities. Every
time you want to indicate the user is at a shell prompt, use
one of &prompt.root; and
&prompt.user; as necessary. They do
not need to be inside prompt.&prompt.root; and
&prompt.user; are FreeBSD
extensions to DocBook, and are not part of the original
DTD.userinputWhen displaying text that the user should type in, wrap it
in userinput tags. It will probably be
displayed differently to the user.screen, prompt, and
userinputUse:&prompt.user; ls -1
foo1
foo2
foo3
&prompt.user; ls -1 | grep foo2
foo2
&prompt.user; suPassword:
&prompt.root; cat foo2
This is the file called 'foo2']]>Appearance:&prompt.user; ls -1
foo1
foo2
foo3
&prompt.user; ls -1 | grep foo2
foo2
&prompt.user; suPassword:
&prompt.root; cat foo2
This is the file called 'foo2'Even though we are displaying the contents of the file
foo2, it is not marked
up as programlisting. Reserve
programlisting for showing fragments of files
outside the context of user actions.In-line elementsEmphasising informationWhen you want to emphasise a particular word or phrase, use
emphasis. This may be presented as italic, or
bold, or might be spoken differently with a text-to-speech
system.There is no way to change the presentation of the emphasis
within your document, no equivalent of HTML's b
and i. If the information you are presenting is
important then consider presenting it in
important rather than
emphasis.emphasisUse:FreeBSD is without doubt the
premiere Unix like operating system for the Intel architecture.]]>Appearance:FreeBSD is without doubt the premiere Unix
like operating system for the Intel architecture.QuotationsTo quote text from another document or source, or to denote
a phrase that is used figuratively, use quote.
Within a quote tag, you may use most of the
markup tags available for normal text.QuotationsUse:However, make sure that the search does not go beyond the
boundary between local and public administration,
as RFC 1535 calls it.]]>Appearance:However, make sure that the search does not go beyond the
boundary between local and public administration,
as RFC 1535 calls it.Keys, mouse buttons, and combinationsTo refer to a specific key on the keyboard, use
keycap. To refer to a mouse button, use
mousebutton. And to refer to combinations of key
presses or mouse clicks, wrap them all in
keycombo.keycombo has an attribute called
action, which may be one of
click, double-click,
other, press,
seq, or simul. The last two
values denote whether the keys or buttons should be pressed in
sequence, or simultaneously.The stylesheets automatically add any connecting symbols, such
as +, between the key names, when wrapped in
keycombo.Keys, mouse buttons, and combinationsUse:To switch to the second virtual terminal, press
AltF1.
To exit vi without saving your work, type
Esc:q!.My window manager is configured so that
Altright mouse button is used to move windows.]]>Appearance:To switch to the second virtual terminal, press
AltF1.To exit vi without saving your work, type
Esc:q!.My window manager is configured so that
Altright mouse button is used to move windows.Applications, commands, options, and citesYou will frequently want to refer to both applications and
commands when writing for the Handbook. The distinction between
them is simple: an application is the name for a suite (or possibly
just 1) of programs that fulfil a particular task. A command is the
name of a program that the user can run.In addition, you will occasionally need to list one or more of
the options that a command might take.Finally, you will often want to list a command with its manual
section number, in the command(number) format so
common in Unix manuals.Mark up application names with
application.When you want to list a command with its manual section number
(which should be most of the time) the DocBook element is
citerefentry. This will contain a further two
elements, refentrytitle and
manvolnum. The content of
refentrytitle is the name of the command, and the
content of manvolnum is the manual page
section.This can be cumbersome to write, and so a series of general entities
have been created to make this easier. Each entity takes the form
&man.manual-page.manual-section;.The file that contains these entities is in
doc/share/sgml/man-refs.ent, and can be
referred to using this FPI:PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN"Therefore, the introduction to your documentation will probably
look like this:<!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN">
%man;
…
]>Use command when you want to include a
command name in-line but present it as something the
user should type in.Use option to mark up a command's
options.When referring to the same command multiple times in
close proximity it is preferred to use the
&man.command.section;
notation to markup the first reference and use
command to markup subsequent references.
This makes the generated output, especially HTML, appear
visually better.This can be confusing, and sometimes the choice is not always
clear. Hopefully this example makes it clearer.Applications, commands, and options.Use:Sendmail is the most
widely used Unix mail application.
Sendmail includes the
sendmail8, &man.mailq.8;, and &man.newaliases.8;
programs.One of the command line parameters to sendmail8, , will display the current
status of messages in the mail queue. Check this on the command
line by running sendmail -bp.]]>Appearance:Sendmail is the most widely used
Unix mail application.Sendmail includes the
sendmail8, mailq8, and newaliases8 programs.One of the command line parameters to sendmail8, , will display the current
status of messages in the mail queue. Check this on the command
line by running sendmail -bp.Notice how the
&man.command.section; notation is easier to follow.Files, directories, extensionsWhenever you wish to refer to the name of a file, a directory,
or a file extension, use filename.filenameUse:The SGML source for the Handbook in English can be
found in /usr/doc/en/handbook/. The first
file is called handbook.sgml in that
directory. You should also see a Makefile
and a number of files with a .ent
extension.]]>Appearance:The SGML source for the Handbook in English can be found in
/usr/doc/en/handbook/. The first file is
called handbook.sgml in that directory. You
should also see a Makefile and a number of
files with a .ent extension.The name of portsFreeBSD extensionThese elements are part of the FreeBSD extension to DocBook,
and do not exist in the original DocBook DTD.You might need to include the name of a program from the
FreeBSD Ports Collection in the documentation. Use the
filename tag with the role
attribute set to package to identify these.
Since ports
can be installed in any number of locations, only include
the category and the port name; do not include
/usr/ports.filename tag with
package roleUse:Install the net/ethereal port to view network traffic.]]>Appearance:Install the net/ethereal
port to view network traffic.DevicesFreeBSD extensionThese elements are part of the FreeBSD extension to DocBook,
and do not exist in the original DocBook DTD.When referring to devices you have two choices. You can either
refer to the device as it appears in /dev, or
you can use the name of the device as it appears in the kernel. For
this latter course, use devicename.Sometimes you will not have a choice. Some devices, such as
networking cards, do not have entries in /dev,
or the entries are markedly different from those entries.devicenameUse:sio is used for serial
communication in FreeBSD. sio manifests
through a number of entries in /dev, including
/dev/ttyd0 and /dev/cuaa0.
By contrast, the networking devices, such as
ed0 do not appear in /dev.In MS-DOS, the first floppy drive is referred to as
a:. In FreeBSD it is
/dev/fd0.]]>Appearance:sio is used for serial communication
in FreeBSD. sio manifests through a
number of entries in /dev, including
/dev/ttyd0 and
/dev/cuaa0.By contrast, the networking devices, such as
ed0 do not appear in
/dev.In MS-DOS, the first floppy drive is referred to as
a:. In FreeBSD it is
/dev/fd0.Hosts, domains, IP addresses, and so forthFreeBSD extensionThese elements are part of the FreeBSD extension to DocBook,
and do not exist in the original DocBook DTD.You can markup identification information for networked
computers (hosts) in several ways, depending on the nature of the
information. All of them use hostid as the
element, with the role attribute selecting the
type of the marked up information.No role attribute, or
role="hostname"With no role attribute (i.e.,
hostid.../hostid) the
marked up information is the simple hostname, such as
freefall or wcarchive.
You can explicitly specify this with
role="hostname".role="domainname"The text is a domain name, such as
FreeBSD.org or
ngo.org.uk. There is no hostname
component.role="fqdn"The text is a Fully Qualified Domain Name, with both
hostname and domain name parts.role="ipaddr"The text is an IP address, probably expressed as a dotted
quad.role="ip6addr"The text is an IPv6 address.role="netmask"The text is a network mask, which might be expressed as a
dotted quad, a hexadecimal string, or as a
/ followed by a number.role="mac"The text is an Ethernet MAC address, expressed as a series
of 2 digit hexadecimal numbers separated by colons.hostid and rolesUse:The local machine can always be referred to by the
name localhost, which will have the IP address
127.0.0.1.
The FreeBSD.org domain
contains a number of different hosts, including
freefall.FreeBSD.org and
bento.FreeBSD.org.When adding an IP alias to an interface (using
ifconfig) always use a
netmask of 255.255.255.255
(which can also be expressed as 0xffffffff.The MAC address uniquely identifies every network card
in existence. A typical MAC address looks like 08:00:20:87:ef:d0.]]>Appearance:The local machine can always be referred to by the name
localhost, which will have the IP address 127.0.0.1.The FreeBSD.org domain
contains a number of different hosts, including freefall.FreeBSD.org and bento.FreeBSD.org.When adding an IP alias to an interface (using
ifconfig) always use a
netmask of 255.255.255.255 (which
can also be expressed as 0xffffffff.The MAC address uniquely identifies every network card in
existence. A typical MAC address looks like 08:00:20:87:ef:d0.UsernamesFreeBSD extensionThese elements are part of the FreeBSD extension to DocBook,
and do not exist in the original DocBook DTD.When you need to refer to a specific username, such as
root or bin, use
username.usernameUse:To carry out most system administration functions you
will need to be root.]]>Appearance:To carry out most system administration functions you will
need to be root.Describing MakefilesFreeBSD extensionThese elements are part of the FreeBSD extension to DocBook,
and do not exist in the original DocBook DTD.Two elements exist to describe parts of
Makefiles, maketarget and
makevar.maketarget identifies a build target exported
by a Makefile that can be given as a parameter
to make. makevar identifies a
variable that can be set (in the environment, on the
make command line, or within the
Makefile) to influence the process.maketarget and
makevarUse:Two common targets in a Makefile
are all and clean.
Typically, invoking all will rebuild the
application, and invoking clean will remove
the temporary files (.o for example) created by
the build process.clean may be controlled by a number of
variables, including CLOBBER and
RECURSE.]]>Appearance:Two common targets in a Makefile are
all and
clean.Typically, invoking all will rebuild
the application, and invoking clean will
remove the temporary files (.o for example)
created by the build process.clean may be controlled by a number
of variables, including CLOBBER and
RECURSE.Literal textYou will often need to include literal text in the
Handbook. This is text that is excerpted from another file, or
which should be copied from the Handbook into another file
verbatim.Some of the time, programlisting will be
sufficient to denote this text. programlisting
is not always appropriate, particularly when you want to include a
portion of a file in-line with the rest of the
paragraph.On these occasions, use literal.literalUse:The maxusers 10 line in the kernel
configuration file determines the size of many system tables, and is
a rough guide to how many simultaneous logins the system will
support.]]>Appearance:The maxusers 10 line in the kernel
configuration file determines the size of many system tables, and
is a rough guide to how many simultaneous logins the system will
support.Showing items that the user must fill
inThere will often be times when you want to show the user what to
do, or refer to a file, or command line, or similar, where the user
cannot simply copy the examples that you provide, but must instead
include some information themselves.replaceable is designed for this eventuality.
Use it inside other elements to indicate parts
of that element's content that the user must replace.replaceableUse:&prompt.user; man command
]]>Appearance:&prompt.user; man commandreplaceable can be used in many different
elements, including literal. This example also
shows that replaceable should only be wrapped
around the content that the user is meant to
provide. The other content should be left alone.Use:The maxusers n
line in the kernel configuration file determines the size of many system
tables, and is a rough guide to how many simultaneous logins the system will
support.
For a desktop workstation, 32 is a good value
for n.]]>Appearance:The maxusers n
line in the kernel configuration file determines the size of many
system tables, and is a rough guide to how many simultaneous
logins the system will support.For a desktop workstation, 32 is a good
value for n.Quoting system errorsYou might want to show errors generated by FreeBSD.
Mark these with errorname. This
indicates the exact error that appears.errornameUse:Panic: cannot mount root ]]>
Appearance:Panic: cannot mount rootImagesImage support in the documentation is currently extremely
experimental. I think the mechanisms described here are unlikely to
change, but that is not guaranteed.You will also need to install the
graphics/ImageMagick port, which is used to
convert between the different image formats. This is a big port,
and most of it is not required. However, while we are working on the
Makefiles and other infrastructure it makes
things easier. This port is not in the
textproc/docproj meta port, you must install it
by hand.The best example of what follows in practice is the
doc/en_US.ISO8859-1/articles/vm-design/ document.
If you are unsure of the description that follows, take a look at the
files in that directory to see how everything hangs together.
Experiment with creating different formatted versions of the
document to see how the image markup appears in the formatted
output.Image formatsWe currently support two formats for images. The format you
should use will depend on the nature of your image.For images that are primarily vector based, such as network
diagrams, time lines, and similar, use Encapsulated Postscript, and
make sure that your images have the .eps
extension.For bitmaps, such as screen captures, use the Portable Network
Graphic format, and make sure that your images have the
.png extension.These are the only formats in which images
should be committed to the CVS repository.Use the right format for the right image. It is to be expected
that your documentation will have a mix of EPS and PNG images. The
Makefiles ensure that the correct format image
is chosen depending on the output format that you use for your
documentation. Do not commit the same image to the
repository in two different formats.It is anticipated that the Documentation Project will switch to
using the Scalable Vector Graphic (SVG) format for vector images.
However, the current state of SVG capable editing tools makes this
impractical.MarkupThe markup for an image is relatively simple. First, markup a
mediaobject. The mediaobject
can contain other, more specific objects. We are concerned with
two, the imageobject and the
textobject.You should include one imageobject, and two
textobject elements. The
imageobject will point to the name of the image
file that will be used (without the extension). The
textobject elements contain information that will
be presented to the user as well as, or instead of, the
image.There are two circumstances where this can happen.When the reader is viewing the documentation in HTML. In
this case, each image will need to have associated alternate
text to show the user, typically whilst the image is loading, or
if they hover the mouse pointer over the image.When the reader is viewing the documentation in plain text.
In this case, each image should have an ASCII art equivalent to
show the user.An example will probably make things easier to understand.
Suppose you have an image, called fig1, that
you want to include in the document. This image is of a rectangle
with an A inside it. The markup for this would be as
follows.<mediaobject>
<imageobject>
<imagedata fileref="fig1">
</imageobject>
<textobject>
<literallayout class="monospaced">+---------------+
| A |
+---------------+</literallayout>
</textobject>
<textobject>
<phrase>A picture</phrase>
</textobject>
</mediaobject>Include an imagedata element inside the
imageobject element. The
fileref attribute should contain the filename
of the image to include, without the extension. The stylesheets
will work out which extension should be added to the filename
automatically.The first textobject should contain a
literallayout element, where the
class attribute is set to
monospaced. This is your opportunity to
demonstrate your ASCII art skills. This content will be used if
the document is converted to plain text.Notice how the first and last lines of the content of the
literallayout element butt up next to the
element's tags. This ensures no extraneous white space is
included.The second textobject should contain a
single phrase element. The contents of this
will become the alt attribute for the image
when this document is converted to HTML.Makefile entriesYour images must be listed in the
Makefile in the IMAGES
variable. This variable should contain the name of all your
source images. For example, if you have
created three figures, fig1.eps,
fig2.png, fig3.png, then
your Makefile should have lines like this in
it.…
IMAGES= fig1.eps fig2.png fig3.png
…or…
IMAGES= fig1.eps
IMAGES+= fig2.png
IMAGES+= fig3.png
…Again, the Makefile will work out the
complete list of images it needs to build your source document, you
only need to list the image files you
provided.Images and chapters in subdirectoriesYou must be careful when you separate your documentation into
smaller files (see ) in
different directories.Suppose you have a book with three chapters, and the chapters
are stored in their own directories, called
chapter1/chapter.sgml,
chapter2/chapter.sgml, and
chapter3/chapter.sgml. If each chapter has
images associated with it, I suggest you place those images in each
chapter's subdirectory (chapter1/,
chapter2/, and
chapter3/).However, if you do this you must include the directory names in
the IMAGES variable in the
Makefile, and you must
include the directory name in the imagedata
element in your document.For example, if you have chapter1/fig1.png,
then chapter1/chapter.sgml should
contain<mediaobject>
<imageobject>
<imagedata fileref="chapter1/fig1">
</imageobject>
…
</mediaobject>The directory name must be included in the
fileref attributeThe Makefile must contain…
IMAGES= chapter1/fig1.png
…Then everything should just work.LinksLinks are also in-line elements.Linking to other parts of the same documentLinking within the same document requires you to specify
where you are linking from (i.e., the text the user will click, or
otherwise indicate, as the source of the link) and where you are
linking to (the link's destination).Each element within DocBook has an attribute called
id. You can place text in this attribute to
uniquely name the element it is attached to.This value will be used when you specify the link
source.Normally, you will only be linking to chapters or sections, so
you would add the id attribute to these
elements.id on chapters and sectionsIntroductionThis is the introduction. It contains a subsection,
which is identified as well.Sub-sect 1This is the subsection.
]]>Obviously, you should use more descriptive values. The values
must be unique within the document (i.e., not just the file, but the
document the file might be included in as well). Notice how the
id for the subsection is constructed by appending
text to the id of the chapter. This helps to
ensure that they are unique.If you want to allow the user to jump into a specific portion of
the document (possibly in the middle of a paragraph or an example),
use anchor. This element has no content, but
takes an id attribute.anchorThis paragraph has an embedded
link target in it. It will not show up in
the document.]]>When you want to provide the user with a link they can activate
(probably by clicking) to go to a section of the document that has
an id attribute, you can use either
xref or link.Both of these elements have a linkend
attribute. The value of this attribute should be the value that you
have used in a id attribute (it does not matter
if that value has not yet occurred in your document; this will work
for forward links as well as backward links).If you use xref then you have no control over
the text of the link. It will be generated for you.Using xrefAssume that this fragment appears somewhere in a document that
includes the id example;More information can be found
in .
More specific information can be found
in .]]>The text of the link will be generated automatically, and will
look like (emphasised text indicates the text
that will be the link);
More information can be found in Chapter
One.More specific information can be found in the
section called Sub-sect 1.
Notice how the text from the link is derived from the section
title or the chapter number.This means that you cannot use
xref to link to an id
attribute on an anchor element. The
anchor has no content, so the
xref cannot generate the text for the
link.If you want to control the text of the link then use
link. This element wraps content, and the
content will be used for the link.Using linkAssume that this fragment appears somewhere in a document that
includes the id example.More information can be found in
the first chapter.
More specific information can be found in
this section.]]>This will generate the following
(emphasised text indicates the text that will
be the link);
More information can be found in the first
chapter.More specific information can be found in
this section.
That last one is a bad example. Never use words like
this or here as the source for the
link. The reader will need to hunt around the surrounding context
to see where the link is actually taking them.You can use link to
include a link to an id on an
anchor element, since the
link content defines the text that will be used
for the link.Linking to documents on the WWWLinking to external documents is much simpler, as long as you
know the URL of the document you want to link to. Use
ulink. The url attribute is
the URL of the page that the link points to, and the content of the
element is the text that will be displayed for the user to
activate.ulinkUse:Of course, you could stop reading this document and
go to the FreeBSD
home page instead.]]>Appearance:Of course, you could stop reading this document and go to the
FreeBSD home page
instead.