Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: THEend8_
OpenBSD Zones “Episode 3: Return of the Sys(call)”
Due: 3pm Monday in Week 5 (19th of August)
1 Academic Integrity
All assessments are individual. You should feel free to discuss aspects of C programming and assessment specifications with fellow students and discuss the related APIs in general terms.
You should not actively help (or seek help from) other students with the actual coding of your assessment. It is cheating to look at another student’s code, and it is cheating to allow your code to be seen or shared in printed or electronic form. You should note that all submitted code will be subject to automated checks for plagiarism and collusion. If we detect plagiarism or collusion (outside of the base code given to everyone), formal misconduct proceedings will be initiated against you.
If you’re having trouble, seek help from a teaching staff member. Do not be tempted to copy another student’s code. You should read and understand the statements on student misconduct in the course profile and on the school website: https://eecs.uq.edu.au/current-students/guidelines-and-policies-students/student-conduct.
1.1 Use of AI Tools
All assessment tasks evaluate students’ abilities, skills and knowledge without the aid of gen-erative Artificial Intelligence (AI) or Machine Translation (MT). Students are advised that the use of AI technologies to develop responses (e.g. code generation) is strictly prohibited and may constitute student misconduct under the Student Code of Conduct.
2 Introduction
This assignment will extend a basic implementation of “zones” in the OpenBSD kernel. The main area of improvement will be separating group and user permissions on zone operations.
You will be provided with a diff that adds the basic zones functionality to OpenBSD. You will need to make changes and improvements on top of this diff.
The purpose of this assignment is for you to demonstrate an understanding of the role of an operating system kernel and how it supports processes making system calls, as well as your skills in reading, understanding, and modifying existing code.
2.1 Background
Zones extend the isolation of processes beyond what is traditionally provided by UNIX and UNIX-like systems, including OpenBSD. Traditionally, all processes running on an OpenBSD are visible to all other processes. This can be demonstrated by running commands like top(1), ps(1), and pgrep(1)/pkill(1), which can show all processes running in a system:
$ ps - ax
PID TT STAT TIME COMMAND
1 ?? I 0:01.01 / sbin / init
35862 ?? Ip 0:00.01 / sbin / slaacd
9544 ?? Ip 0:00.01 slaacd : engine ( slaacd )
33073 ?? IpU 0:00.01 slaacd : frontend ( slaacd )
96644 ?? IU 0:00.01 / sbin / dhcpleased
82639 ?? Ip 0:00.01 dhcpleased : engine ( dhcpleased )
68436 ?? IpU 0:00.01 dhcpleased : frontend ( dhcpleased )
6881 ?? IpU 0:00.01 / sbin / resolvd
69588 ?? IpU 0:00.03 syslogd : [ priv ] ( syslogd )
54598 ?? Spc 0:00.03 / usr / sbin / syslogd
14516 ?? IU 0:00.01 pflogd : [ priv ] ( pflogd )
15079 ?? Spc 0:00.12 pflogd : [ running ] -s 160 -i pflog0 -f / var / log /
pflog
94692 ?? S < pc 0:00.12 ntpd : ntp engine ( ntpd )
37809 ?? Sp 0:00.26 ntpd : dns engine ( ntpd )
1816 ?? I < pU 0:00.00 / usr / sbin / ntpd
63841 ?? I 0:00.01 sshd : / usr / sbin / sshd [ listener ] 0 of 10 -100
startups
83125 ?? Ip 0:00.02 / usr / sbin / smtpd
58972 ?? Ipc 0:00.02 smtpd : crypto ( smtpd )
99695 ?? Ipc 0:00.02 smtpd : control ( smtpd )
5777 ?? Ip 0:00.02 smtpd : lookup ( smtpd )
45996 ?? Ipc 0:00.04 smtpd : dispatcher ( smtpd )
37682 ?? Ipc 0:00.02 smtpd : queue ( smtpd )
97246 ?? Ipc 0:00.02 smtpd : scheduler ( smtpd )
48848 ?? IpU 0:00.00 sndiod : helper ( sndiod )
47188 ?? I < pc 0:00.00 / usr / bin / sndiod
96369 ?? Ip 0:00.02 / usr / sbin / cron
45067 ?? I 0:00.07 sshd : dlg [ priv ] ( sshd )
32638 ?? S 0:00.03 sshd : dlg@ttyp0 ( sshd )
1730 p0 Sp 0:00.02 - ksh ( ksh )
16990 p0 R + pU /2 0:00.00 ps - ax
33428 00 I + pU 0:00.01 / usr / libexec / getty std .9600 tty00
$
‘‘‘
While all processes are visible to each other, they are restricted from interacting with each other based on the user that each process is running as. A non-root user can only signal their own processes. Attempts to signal processes running as another user fails:
$ whoami
dlg
$ ps -U _sndio
PID TT STAT TIME COMMAND
47188 ?? I < pc 0:00.00 / usr / bin / sndiod
$ kill 47188
ksh : kill : 47188: Operation not permitted
$
However, the root user is allowed to signal any process:
$ doas kill 47188
doas ( dlg@comp3301 . eait . uq . edu . au ) password :
$ ps -U _sndio
PID TT STAT TIME COMMAND
$
3 Zones Implementation
Zones are implemented for this assignment to add further isolation of processes. Processes running within a zone can only see and interact with processes running within the same zone, regardless of which user within the zone is running the commands. This implementation is loosely modelled on the design of Solaris Zones as described in PSARC/2002/174.
The exception to this enhanced isolation is for processes running in the ”global” zone, which is the default zone that is created and exists on boot. Processes running in the global zone can see all other processes in the system, including those running in other (non-global) zones, and the root user in the global zone can signal any of these processes too. However, non-root users in the global zone cannot signal processes in other zones, even if they are running as the same user.
The provided diff implements changes to the kernel and several userland utilities and adds a zone(8) command and man page. The zone(8) command provides several sub-commands that expose the functionality of the kernel zone subsystem.
3.1 Provided Zone Syscalls
zone_create()
zoneid_t zone_create ( const char * zonename ) ;
zone_create() creates a new zone id for use in the system, with a unique name specified by zonename.
zone_destroy()
int zone_destroy ( zoneid_t z ) ;
zone_destroy() deletes the specified zone instance. The zone must have no running processes inside it for the request to succeed.
zone_enter()
int zone_enter ( zoneid_t z ) ;
zone_enter() moves the current process into the specified zone.
zone_list()
int zone_list ( zoneid_t * zs , size_t * nzs ) ;
In the global zone zone_list() provides the list of zones in the running system as an array of zoneid ts. If run in a non-global zone, the list will only contain the current zone.
zone_name()
int zone_name ( zoneid_t z , char * name , size_t namelen ) ;
The zone_name() syscall provides the name of the zone identified by the z argument. If run in a non-global zone the z id must be the identifier for the current zone. In the global zone it can be any zone identifier.
zone_id()
zoneid_t zone_id ( const char * name ) ;
zone_id() provides the id associated with the name zone. If run in a non-global zone, only the current zone name may be specified. If name is a NULL pointer the zone id calling process is running in is returned.
zone_stats()
int zone_stats ( zoneid_t z , struct zstats * zstats ) ;
zone_stats() provides an assortment of operating system statistics resulting from processes in the zone associated with the id z.
zone_rename()
int zone_rename ( zoneid_t z , char * newname ) ;
zone_rename() alters the name of the zone identified by the z argument. The new name will be the name provided in the newname argument. zone_rename() handles the necessary tree updates on the zone names tree.
This syscall will be necessary for you to implement the zone rename subcommand.
3.2 zone(8)
usage : zone create zonename 1
zone destroy zonename 2
zone exec zonename command ... 3
zone list 4
zone id [ zonename ] 5
zone name [ zid ] 6
zone stats [ - H ] [ - o property [ ,...] zone [...] 7
The zone(8) program uses the zone syscalls to allow systems administrators or operators to use the zone subsystem in the kernel.
zone create
zone create uses the zone_create() syscall to create a zone with the specified name.
zone destroy
zone destroy uses the zone_destroy() syscall to create a zone with the specified name. If a zone with the specified name does not exist, zone(8) will attempt to interpret the argument as a numeric zone identifier.
zone exec
zone exec uses the zone_enter() syscall to move itself into the specified zone, and then executes the program. If a zone with the specified name does not exist, zone(8) will attempt to interpret the argument as a numeric zone identifier.
zone list
zone list uses the zone_list() syscall to fetch a list of ids for the currently running zones, and iterates over it calling the zone_name() syscall to print out the list of zone ids and names.
zone name / zone id
zone name and zone id use their associated syscalls zone_name() and zone_id() to return the name of a zone given its id, or the id of a zone given its name.
zone stats
zone stats uses the zone_stat() syscall to obtain and print out to the user a series of statis-tics from processes running in the current zone. See the manual page in zone(8) for more information.
3.3 Your Tasks
You will be adding additional functionality to a series of zone(8) sub-commands, adding three new zone(8) sub-commands, and implementing any necessary changes to the kernel zones system to support them.
Your additional functionality centers around zone permissions. Files have an associated “user” and “group”, and this user or group may have permission to operate on the file. Your task is to associate zones with a particular owner and group, and allow the owner of the zone and users who are in that group to perform. operations on the zone (regardless of whether they are the owner of the zone).
In short, where zones are now only controllable by root, your changes will allow the owner of a zone and a different group of users to control a zone.
The additional sub-commands you will be implementing are: zone rename, which will change the name of a zone; zone chown, which will change the owner of a zone in a manner similar to the existing chown(8); and zone chgrp, which will change the group of a zone in a manner similar to the existing chgrp(8).