125
126
127
128
– ‘ git am / path / to/ a1 – zones – base . patch ‘ in / usr/ src 5
-
Build the kernel 6
-
‘ cd / usr/ src/ sys/ arch / amd64 / compile / GENERIC . MP ‘ 7
-
‘ make obj ‘ 8
-
‘ make config ‘ 9
– ‘ make -j 5 ‘ 10
-
‘ doas make install ‘ 11
-
-
Reboot into the kernel 12
-
‘ doas reboot ‘ 13
-
-
‘ make obj ‘ in / usr/ src 14
-
‘ doas make includes ‘ in / usr/ src/ include 15
-
Verify the zones syscalls are in / usr/ include / sys/ syscall. h 16
-
Verify / usr/ include / sys/ zones. h exists 17
-
-
Make and install libc 18
-
‘ cd / usr/ src/ lib / libc ‘ 19
– ‘ make -j 5 ‘ 20
-
‘ doas make install ‘ 21
-
-
Optional: make ps , and pkill/ pgrep 22
-
make zone (8) 23
-
‘ cd / usr/ src/ usr. sbin / zone ‘ 24
-
‘ make ‘ 25
-
‘ doas make install ‘ 26
-
-
Verify ‘ zone (8)‘ and the zones subsystem works: 27
$ zone list 28
ID NAME 29
0 global 30
$ zone create 31
usage : zone create zonename 32
$ zone create test 33
zone : create : Operation not permitted 34
$ doas zone create test 35
doas ( dlg@ comp 3301 . eait. uq. edu . au) password : 36
$ zone list 37
ID NAME 38
0 global 39
42101 test 40
$ zone id 41
0 42
$ zone id test 43
42101 44
$ zone exec test ps – aux 45
zone : enter: Operation not permitted 46
$ doas zone exec test ps – aux 47
USER PID % CPU % MEM VSZ RSS TT STAT STARTED TIME COMMAND 48
root 41705 0.0 0.1 628 580 p0 R+pU /0 3:37 PM 0:00.14 ps – aux 49
$ doas zone exec test zone id 50
42101 51
$ doas zone exec test zone id global 52
zone : id: No such process 53
$ 54
As you add the functionality specified in the next sections, some of these steps will be repeated. eg, changing the kernel means rebuilding and installing the kernel. Adding a syscall means making the syscall stub as a function visible in the headers (make includes), and callable through libc.
129
130
131
132
133
134
135
136
137
138
139
A note on errors
We have over-specified the errors you should return from your syscalls – if you do not require an error code (for example, never returning ENOMEM on memory failures because you never allocate any memory) then you do not have to use it. The reverse is also true – if you find an error case that is not listed, choose an appropriate error from errno(2). We will not explicitly test all errors, but during your code interview, we will expect you to be able to explain the suitability of the error codes you use.
-
Zone Rename
The zone(8) commands should be extended to enable renaming of zones. Zones should only be able to be renamed by the owner, root, or members of the zone’s group. Additionally, the global zone cannot be renamed, and zone names must be unique.
$ zone
usage : zone create zonename zone destroy zonename
zone exec zonename command … zone list
zone name [ id] zone id [ zonename ]
$
$
$
$
zone rename zone newname doas zone create foo
zone list
ID NAME
0 global
289 foo
doas zone rename 298 bar zone list
ID NAME
0 global
289 bar
$ doas zone rename 0 something zone : rename: Invalid Argument
$ doas zone rename 289 global zone : rename: File exists
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
140
141
142
143
144
145
146
147
148
149
150
-
Modifications to Existing Syscalls
zone_create() syscall
The zone_create() syscall should now ensure that the created zone is associated with the group of the user that created it, as well as the user themself. Additionally, this will mean ensuring that non-root users can create zones. The definition of zone_create() should not change – it should still take a single char *zonename as its argument.
All other syscalls
The full suite of zone_* syscalls should permit users with matching credentials (owner or group) to perform zone operations on them, not only the root user. The credentials may be changed
so appropriate synchronisation should be used. Namely, we expect that, unless credentials are being changed by another thread, authorisation should be non-blocking.
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
-
Zone name and zone list
zone_name() syscall
The zone_name() syscall should be renamed to zone_info(). Subsequently, it should return not only the name and namelen, but also the zone, user and group id, preferably all bundled in a struct format. However you may pass back one or more of these as individual parameters if that is easier. The zone(8) userland sub-command for zone name should also be modified in line with these changes – the name should be changed to zone info and the additional information should be provided to the user. Alternatively, you may also create zone info as an independent command.
zone list
The zone list subcommand should now take flags: -o and -g. If the -o flag is provided, the owner of the zone should be printed, and if the -g flag is provided, the zone’s group should be printed. If both flags are provided, print both. The extra fields should be printed as extra columns in the current table format. zone id and name must be displayed first. However, the order of the additional fields does not matter.
-
Zone chown and chgrp
The zone(8) commands and the kernel zones system should be extended to enable changing the owner and group of a zone. Zone owners and groups should only be able to be changed by the owner, root, or members of the zone’s group. Additionally, the owner of the global zone cannot be changed.
$ zone
usage : zone create zonename zone destroy zonename
zone exec zonename command … zone list
zone name [zoneid] zone id [ zonename ] zone chown zone user zone chgrp zone group
1
2
3
4
5
6
7
8
9
The two subcommands you are adding are zone chown and zone chgrp. zone chown takes the name of a zone and uses the zone_chown() syscall to change its owner to the user with the specified name. If a zone with the name zonename does not exist, zone(8) will attempt to interpret the argument as a numeric zone identifier.
zone chgrp behaves similarly, but instead, it uses the zone_chgrp() syscall to change the zone’s group to the specified group name.
To support these subcommands, you will need to implement the following system calls:
zone_chown() syscall
int zone_chown ( zoneid_t z, uid_t user);
179
180
181
182
The zone_chown() syscall alters the owner of the zone identified by the z argument. The new owner should be the owner identified by the user argument. If called from a non-global zone, then the z id must be the identifier for the current zone, but in the global zone, it can be any zone identifier. This means that to the user, a non-global zone should only be able to see itself.
183 Potential Errors:
184 • EPERM – the user does not have permission to alter the zone z
185 • ESRCH – the zone identified by z does not exist
186 • ENOMEM – the system was not able to allocate memory
187 • EINVAL – the zone to alter was the global zone
188 zone_chgrp() syscall
int zone_chgrp ( zoneid_t z, gid_t group );
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
The zone_chgrp() syscall alters the owner of the zone identified by the z argument. The new owner should be the group identified by the group argument. If called from a non-global zone, then the z id must be the identifier for the current zone, but in the global zone, it can be any zone identifier. This means that to the user, a non-global zone should only be able to see itself.
Potential Errors:
-
EPERM – the user does not have permission to alter the zone z
-
ESRCH – the zone identified by z does not exist
-
ENOMEM – the system was not able to allocate memory
-
EINVAL – the zone to alter was the global zone
-
Other Requirements & Suggestions
-
Code Style
Your code is to be written according to OpenBSD’s style guide, as per the style(9) man page. An automatic tool for checking for style violations is available at: https://stluc.manta.uqcloud.net/comp3301/public/2022/cstyle.pl
This tool will be used to calculate your style marks for this assignment.
-
Compilation
Your code for this assignment is to be built on an amd64 OpenBSD 7.5 system identical to your course-provided VM.
The following steps must succeed:
-
make obj; make config; make in src/sys/arch/amd64/compile/GENERIC.MP
-
make obj; make includes in src
-
make obj; make; make install in src/lib/libc
-
make obj; make; make install in src/usr.sbin/zone
The existing Makefiles in the provided code are functional as-is, but may need modification as part of your work for this assignment. Note that the existing Makefile ensures the -Wall flag is passed to the compiler, as well as a few other warning and error-related flags.
216
217
218
219
220
221
222
-
-
Provided code
The provided code, which forms the basis for this assignment, can be downloaded as a single patch file at:
https://stluc.manta.uqcloud.net/comp3301/public/2024/a1-zones-base.patch
You should create a new a1 branch in your repository based on the openbsd-7.5 tag using git checkout, and then apply this base patch using the git am command:
$ git checkout -b a1 openbsd -7.5
$ ftp https: // stluc. manta. uqcloud. net/ comp3301 / public /2024/ a1 – zones – base. patch
$ git am < a1 – zones – base . patch
$ git push origin a1
-
1
2
3
4
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
-
Recommendations
The following order will likely be the most reasonable way to complete this assignment:
-
Download, build, and install the zones patch.
-
Add the zone rename subcommand to zone(8).
-
Minimally modify zone_create() to store credentials.
-
Rewrite zone_name() to zone_info().
This ensures you have a way to view the credentials of a zone.
-
Add the zone_chown() and zone_chgrp() syscalls.
-
Add the corresponding zone chown and zone chgrp commands to zone(8).
-
Fix up any tiny bugs and ensure it’s all working. But you did that as you were going… right?
Additionally, it is strongly recommended (and in some cases, required) that the following APIs be considered for use as part of your changes:
-
sys/ucred.h – provides necessary handlers for dealing with user and group credentials
-
copyin(9)/copyout(9) – provides the ability to copy data across the userspace boundary
-
user_from_uid(3) – conversions from group/user name to id and back
-
strtonum(3) – BSD style safe string to int conversions
-
Finally, you may wish to look at the header file sys/proc.h to see how user and group credentials are currently stored by threads.
-
Reviews
There are no reviews yet.