In this section, you will learn how the Zircon kernel objects enable Fuchsia to follow the principle of least privilege, isolating processes and granting them only the capabilities they require.
Sandboxing
When a new process is created, it has no capabilities. The process relies entirely on its creator to provide capabilities through the set of handles passed to it. One might also say that an empty process has no ambient authority.
Because of this, processes are usually created with some initial resources
and capabilities. The fuchsia.process.Launcher
protocol provides the
low-level interface to create new processes on the system from an executable
and a set of kernel object handles. Most software uses the component framework,
which simplifies the work of setting up a new process to execute some code with
a standard set of initial capabilities. You will explore components in more
detail later on.
Some initial handles given to a process are directories that the process mounts into its namespace.
Namespaces
The namespace of a process contains its private view of the world, and controls how much of the Fuchsia system the process can influence. This effectively defines the rules of the sandbox in which that process runs.
Namespaces are populated with various resource objects, including:
- Files: Objects which contain binary data.
- Directories: Objects which contain other objects.
- Sockets: Objects which establish connections when opened, like named pipes.
- Protocols and services: Objects which provide structured services when opened.
- Devices: Objects which provide access to hardware resources.
The creator of the process populates the contents of a namespace based on the set of required capabilities. A process cannot add objects to its own namespace, as this would essentially amount to that process self-granting the capabilities to access those objects.
Exercise: Namespaces
Most processes in Fuchsia represent executable programs associated with a component , where the component declaration is responsible for constructing the namespace that process can see.
In this exercise, you'll explore the contents of a component's namespace.
Start the emulator
If you do not already have an instance running, start the emulator:
ffx emu start --headless
When startup is complete, the emulator prints the following message and returns:
Logging to "$HOME/.local/share/Fuchsia/ffx/emu/instances/fuchsia-emulator/emulator.log"
Waiting for Fuchsia to start (up to 60 seconds)........
Emulator is ready.
Find a target component
You learned in the previous section that processes associated with a component
are named with a .cm
extension. Recall the following example process list:
TASK PSS PRIVATE SHARED STATE NAME
j: 1027 507.8M 507.4M root
p: 1061 564.4k 564k 36k bin/bootsvc
p: 1150 4264.4k 4264k 36k bin/component_manager
j: 1479 228.4k 228k
p: 1583 228.4k 228k 36k pwrbtn-monitor.cm
j: 1484 532.4k 532k
p: 1599 532.4k 532k 36k svchost.cm
j: 1544 402.4k 304k
p: 1633 402.4k 304k 232k netsvc.cm
j: 1681 296.4k 296k
p: 1733 296.4k 296k 36k console-launcher.cm
j: 1799 7232.4k 7232k
p: 1825 7232.4k 7232k 36k archivist.cm
...
j: 31294 1872.2K 1872K
p: 31331 1872.2K 1872K 20K http-client.cm
For this exercise, you'll use http-client.cm
as your target to explore.
Connect to the target component
In order to explore a component's namespace, you need to determine the unique identifier for that component within the system. This is known as the component moniker .
Use the ffx component show
command to list additional details about the
component, including the component moniker:
ffx component show http-client.cm
The command prints output similar to the following:
$ ffx component show http-client.cm
Moniker: /core/network/http-client
URL: #meta/http-client.cm
Type: CML static component
...
You can use the ffx component explore
command to open an interactive shell
inside the target component's environment. Try this for the http-client
component:
ffx component explore /core/network/http-client
Inside the explore shell, list the contents of the root directory using the
ls
command:
[explore shell] $ ls
bin
exposed
ns
out
runtime
svc
Explore the namespace
You'll find the component's namespace under the /ns
path inside the
environment.
Inside the explore shell, list the contents of the namespace:
[explore shell] $ ls /ns
config
pkg
svc
Here are some quick highlights of each element:
config/
: configuration data for the componentpkg/
: the contents of the component's packagesvc/
: system services available to the component
Inside the explore shell, list the contents of the incoming /ns/svc
directory. This directory contains
service nodes
representing the system services provided to this component.
[explore shell] $ ls /ns/svc
fuchsia.logger.LogSink
fuchsia.net.name.Lookup
fuchsia.posix.socket.Provider
Each of these services is accessible over a well-known protocol defined by a Fuchsia Interface Definition Language (FIDL) interface. We'll explore FIDL protocols and how to access various services in more detail later on.
Inside the explore shell, type exit
to return to the shell on your
development machine:
[explore shell] $ exit