Generally a process' label is inherited from its parent process and remains constant. A few privileged launchers exist which can set a process label when executing a new process. These include the profiles shells (pfsh, pfksh, and pfcsh), the system shell (sysh), and the Internet daemon (inetd). Each of these processes interpret entries in the exec_attr database when executing programs.
All of the shells interpret the label keyword associated with a command when they execute a new process. inetd is able to launch servers at the same label as the requesting client. Such servers are said to be polyinstantiated, since a server instance can be launched corresponding to the label of each requesting client. The rules for determining the client's label are based on the contents of trusted networking databases that were discussed in the previous Sun BluePrints article1. In this article, we rely on inetd to polyinstantiate servers for ftp and telnet. Since this is the default behavior, no configuration changes are required.
The SMTP daemon, sendmail, has been modified in the Trusted Solaris OE to work in a polyinstantiated manner. It automatically forks off a process at the label of the requesting client. No special configuration is required, but a common configuration file is maintained by the service provider.
Creating a CGI Sandbox
Customers may want to develop and execute scripts on the server using the Common Gateway Interface (CGI) or Server Side Includes (SSI), so it is desirable to compartmentalize the web server and the CGI environment. Apache provides a small execution wrapper known as suEXEC, which allows scripts to be executed with a different user ID from the calling Web server. This concept can be extended to provide execution in a protected sandbox. By running the web server in the HTTP FTP compartment, and the CGI scripts in the CGI compartment, the environments are isolated from each other except for a pipe to the web server used for standard I/O.
Neither the web server nor the CGI scripts are able to modify any files with the C1 label because they are not permitted to write down, but each can read these files unless they are protected by DAC. In addition, the web server and the CGI scripts cannot read any files created in the other compartment because neither dominates the other. The CGI environment is also prevented from connecting to any remote systems since its label is outside the accreditation range of all network interfaces connected to the Internet (see section, "Associating Labels with Network Interfaces," on page -7).
The suEXEC program is Open Source, so it can be modified to switch its label compartments prior to executing a CGI script. The modification consists of a few lines of C added to file suexec.c which are executed between fork(2) and exec(2). Since the MAC policy for files is enforced when a file or pipe is opened, it is possible to pass open file descriptors to a child process even if its process label is changed. The following code fragment turns off the HTTP FTP compartment and turns on the CGI compartment (error handling is omitted for clarity).
#include <tsol/label.h> bclabel_t label; int p; getcmwplabel(&label); /* current label */ stobsl("- HTTP FTP", bcltosl(&label), 0, &p); /* HTTP, FTP off */ stobsl("+ CGI", bcltosl(&label), 0, &p); /* CGI on */ setcmwplabel(&label, SETCL_SL); /* set new label */
The system call getcmwplabel(2) returns the initial process label of suEXEC, which is the same as the web server. The function stobsl(3) translates a string to a binary label. In these calls it adds or removes the compartment bits corresponding to a specified string. The label translation requires the privilege proc_setsl. The resulting label is then applied to the current process by the system call setcmwplabel(2), which requires the privilege proc_setsl. Since no change is made to the classification component of the label, this single change works for any of the customer labels described above. A modified version of the file suexec.c which incorporates this logic is included in the configuration files for this article.
The standard suEXEC program, which sets up the new user ID before executing the specified commands, requires the privilege proc_setid. These privileges are applied to the executable using the following commands:
# cd /usr/apache/bin # setfpriv -s -a all -f proc_setid,sys_trans_label,proc_setsl suexec
The Apache documentation for suEXEC describes how to make it a setuid program by assigning it the permission bits 4711. Although the Trusted Solaris OE privilege policy does not require this setting, the Apache server refuses to communicate with suEXEC unless these permissions are set.
An alternative approach to modifying suEXEC is to write a privileged profile shell script wrapper around it. Such a wrapper would rely on the profile shell functionality to set the process label instead of suEXEC. However, the complexity of creating multiple profiles and the requirement to make the shell script wrapper a setuid program, make it a less attractive solution than modifying suEXEC directly.
Instantiating Servlets and JavaServer Pages™ Software
Another kind of web server application is a Java™ servlet container such as Apache's Tomcat server. A servlet container manages and invokes servlets on the behalf of users. The Tomcat servlet container described here is a combination of a web server plug-in and a Java container implementation that runs in a Java virtual achine or JVM™ software outside the web server. The web server plug-in and the Java servlet container JVM software communicate using TCP/IP sockets; therefore the servlet container can run on a backend machine, which is also running the Trusted Solaris OE. Unlike connections to the public Internet, the interfaces between these two systems are multilevel. That means that the respective interfaces can be used to communicate at any label within their accreditation ranges. We can use the Tomcat server's default port number, 8007, for all customers, since the port is polyinstantiated. Each Tomcat server will run in its own JVM software, and will only accept connections from a web server running with the same label.
Adding backend servers is optional, but is consistent with the Trusted Solaris architecture since the compartmentalization provided by the MAC policy is enforced throughout the trusted network.