[Transfer] Linux Kernel Security Technology (4): Introduction to Vold Principles

foreword

Earlier, we followed our predecessors to learn security articles. In the Linux kernel security technology (3): Android system security technology - FBE key framework and technical details, it involves:

  • VIOLENCE,
  • Linux Kernel Keyring、
  • Linux Kernel Fscrypt、
  • KSM、
  • Keymaster
  • ICE,

I just saw an article about VOLD by my predecessors. This is not a good time to study together.

Original link: https://blog.csdn.net/feelabclihu/article/details/119834131

1. Introduction to Vold

Vold in Android is a volume Daemon, that is, a Volume daemon process , which is used to manage hot-plug events of storage classes in Android. The scenarios involved in hot swapping here are as follows:

  1. Mounting and uninstalling of disk data after the mobile phone USB is plugged and unplugged from the PC in the way of MTP or photo transfer;

  2. Mounting and unmounting of each partition of the storage device when the device is turned on and off;

  3. The file system is mounted and unmounted during the identification process of T card insertion and removal.

During the mount process in each scenario, the security encryption of disk data (FDE/FBE), the creation of file nodes and directories, and the garbage cleaning of the file system are also controlled by Vold.

2. Vold Architecture

Vold exists as a daemon process in the system and is a separate process. Between Kernel and Framework, it is a bridge connecting the two levels. The figure below is the overall architecture of Vold in the Android system

insert image description here

  • Vold mainly receives Kernel's uevent message ,
  • Then NetLinkManager puts the message on the NetLinkHandler queue and sends it to VolumeManager,
  • Finally, the message is passed to the StorageManager of the Framework .
  • Finally, StorageManager will store the data ,
  • The message is notified to the services and applications registered with StorageManager.

3. Vold startup process

When the Android system starts, the init process will parse the init.rc file, and the command with start vold in init.rc will be parsed by init , and the function corresponding to start do_start(constBuiltinArguments& args) ;

That is to start the corresponding service, and then the service parses the vold.rc file to do some initial configuration for Vold.

insert image description here
The main function in Vold has a complete startup process, as follows

insert image description here

  • Start VolumeManager : VolumeManager will first uninstall everything in the corresponding folder to make it in a clean state, and then construct a built-in storage directory, that is, /data/media, where an EmulatedVolume is newly created through the VolumeBase base class pointer object. In the create function, doCreate is executed and onVolumeCreated is called back. The listener here is the StorageManager service. However, since Vold started earlier, SystemServer has not started the StorageManager, so the getListener() here is empty. After the StorageManager startup is completed will retrigger. Finally, the status of the current storage device is set to unmounted. Among them, doCreate is a virtual function, but it is not implemented in EmulatedVolume, so the base class function is finally called, and it returns directly. Finally Vold will create a virtual disk, namely /data/misc/vold/virtual_disk.

  • Start VoldNativeService : VoldNativeService relies on aidl interface logic, which connects StorageManager and vold. It inherits from BinderService. During the startup process, the interface is mainly registered, so that other services can be found through IVold, and then the thread is started.

  • Start NetlinkManager : A socket connection is established internally during the startup process to receive all uevent events, and finally a new NetlinkHandler object will be created and the start function will be executed. Then call the startListener function of the NetlinkListener parent class to listen to the event.

After Vold is started, Vold will monitor the uevent event of the kernel, and then process and forward the notification to StorageManager through Callback, while Framework services and Apps can use Vold to process Command through StorageManager.

4. Operating principle of Vold

Regarding the operating principle of Vold, it mainly introduces how to establish the connection between the kernel and Vold, and between the StorageManager and Vold, and how to receive and process information. Here first explain the kernel–Uevent mechanism.

1. Linuxkernel–Uevent mechanism

Uevent is a mechanism for communicating between kernel space and user space, mainly used for hotplug events (hotplug). Uevent events are sent to user space in the form of environment variables (that is, strings), taking kernel 5.4 as an example

insert image description here
The events corresponding to the actions of the kobject correspond to the following types:

insert image description here
The event is sent to the user space through the kobject_uevent function in the kernel, but the action of actually sending the event is implemented by calling the function kobject_uevent_env.

insert image description here
The kobject_uevent_env function mainly does two aspects of work:

  • 1) Obtain and organize the environment variables related to the event to be sent, such as ACTION, DEVPATH and SUBSYSTE, etc.

  • 2) Send events to user space.

2. The connection between Vold and the kernel

As mentioned before, when NetlinkManager starts, it will execute startListener to start listening to Kernel's uevent event.

NetlinkHandler inherits from NetlinkListener, and NetlinkListener is a subclass of SoctetListener, so the startListener function of SoctetListener is finally called. This function is to start listening to the message, and then start a thread to execute the runListener function, read the socket message in a loop and send it to each client. NetlinkListener is one of them, and it will go to further processing after receiving the Callback.
insert image description here
mCtrlPipe[0] is used as the reader here, and will read the event corresponding to POLLIN from the stream, and the socket file descriptor corresponding to each client will also be stored in the vector. The next step is to use the poll function to poll each file descriptor in the vector.

Then, according to revents, it is determined whether there is an event to be read. If no event is read, the next round will be performed. If an event is read, the client corresponding to the file descriptor will be saved, and finally the Callback onDataAvailable function will be called.

insert image description here

The onDataAvailable side is here to actually receive the data, establish socket communication with it through the given client field, read the data with the help of the uevent_kernel_recv function, and call onEvent to distribute it after decoding and parsing.

insert image description here
At this time, NetlinkHandler comes on the stage, obtains the VolumeManager singleton object, and calls handleBlockEvent to process the event.

insert image description here

3. The connection between Vold and StorageManager

The connection between Vold and StorageManager is to establish communication through the binder, and the StorageManager sends commands to Vold through the binder, and registers the listener in Vold to complete the message reporting.

In StorageManager, when SystemServer starts StorageManager, it will call the start method to connect to vold.

insert image description here
Then the IVold interface will be obtained through the binder, and the mListener will be registered in the past. Here is the aidl interface of Vold, which corresponds to the interface class of VoldNativeService.

insert image description here
Take booting up and hanging on the built-in storage device as an example, when the booting broadcast BootCompleted is sent out, StorageManager will perform lockuser or unlockuser operations, then add built-in storage, and reset Vold, which actually corresponds to calling the reset function of VolumeManager, and finally start user, create the corresponding file directory and link to the corresponding data storage partition.
insert image description here

Here, after the StorageManager is started, reset is executed, and the mInternalEmulated->create(); process will be re-executed, which will notify the StorageManager and trigger InternalEmulated to mount. After the mount is triggered, the doMount() function of the EmulatedVolume class will eventually be executed to complete the real mount process.

insert image description here

4. External storage device SD card mounting example

Combined with the above-mentioned Vold operation principle, the SD card mounting process is briefly introduced by drawing the following flow chart

insert image description here

References:

  1. Linuxkernel-5.4 source code 2.http://androidxref.com/9.0.0_r3/xref/system/vold/vold.rc 3.http://aospxref.com/android-11.0.0_r21/xref/system/core/libsysutils/src/SocketListener.cpp 4.http://aospxref.com/android-11.0.0_r21/xref/system/core/libsysutils/src/NetlinkListener.cpp 5.http://aospxref.com/android-11.0.0_r21/xref/system/vold/NetlinkHandler.cpp 6.http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/StorageManagerService.java

7.http://aospxref.com/android-11.0.0_r21/xref/system/vold/VolumeManager.cpp

Guess you like

Origin blog.csdn.net/weixin_45264425/article/details/131147632