1# In-Band Update of BMC Firmware using USB
2
3Author: George Liu <liuxiwei!>
4
5Primary assignee: George Liu
6
7Created: 2021-10-12
8
9## Problem Description
10
11When Redfish or scp cannot be used, BMC needs a new mechanism for images to get
12into the machine.
13
14## Background and References
15
16The openbmc project currently has a [phosphor-software-manager][1] repository.
17In order to perform an update, need first to bring the image into the BMC
18directory (/tmp/images). However, only TFTP and HTTP are currently supported,
19and USB is not yet supported.
20
21The intent of this new application design is to enable the USB driver of BMC to
22enter the new image into BMC.
23
24## Requirements
25
26The following statements are reflective of the initial requirements.
27 * Monitor whether the USB key is inserted.
28 * The first tar file found in the sorted list of files on the USB device is
29copied to `/tmp/images`.
30 * Manually trigger firmware upgrade.
31 * Disable automatic reboot the BMC firmware after upgrade is complete to
32prevent a potential loop in the event of a key inserted.
33 * This mechanism attempts to maintain security, for example this feature is
34disabled by default or can be enabled or disabled via Redfish.
35
36## Proposed Design
37
38The new code would be part of the phosphor-software-manager
39repository(eg: phosphor-usb-code-update).
40The design process is as follows:
41 - Define a macro switch (`usb-code-update`) in [phosphor-software-manager][1]
42repository to identify whether to enable the USB Code Update function,
43which is _enabled_ by default.
44 - If `usb-code-update` enabled, install the udev rules file to
45`/lib/udev/rules.d` during compilation.
46 - Once the udev rules are met, the systemd service is directly triggered and
47start the phosphor-usb-code-update daemon.
48 - This daemon verifies the `/run/media/usb/sda1` directory and copies
49the first `.tar` file in the directory to `/tmp/images` and starts
50verification.
51 - Set ApplyTime to OnReset so that the proposed usb code update app does not
52reboot the BMC after activation.
53 - Set RequestedActivation to Active, follow the updated status, start to
54update the firmware, and restart the BMC after completion.
55 - Exit the phosphor-usb-code-update daemon.
56
57## Pseudocode
58
59The udev rules files for example:
60```
61SUBSYSTEM=="block", ACTION=="add", ENV{ID_USB_DRIVER}=="usb-storage", ENV{DEVTYPE}=="partition", ENV{SYSTEMD_WANTS}="usb-code-update@%k", TAG+="systemd"
62```
63
64## Security
65
66 - It is recommended to run a local CI run and analyze & avoid potential
67vulnerabilities via cppcheck.
68 - Assuming that the USB drive has a physical security vulnerability
69(such as memory overflow, etc.), should disable "USB code update" via Redfish.
70After the vulnerability is fixed, enable "USB code update" again via Redfish.
71
72## Alternatives Considered
73
74If the OS fails to boot due to an error, so the firmware update cannot be done
75through the OS, or the network fails, and the update cannot be done through
76Redfish or scp, the server support staff can only uninstall the flash chip and
77re-flashing, this is not Reasonably, service support should have local access
78to the machine and update the system to a working firmware level.
79
80## Impacts
81
82This impacts security because it can copy files to the BMC via an external USB
83key. There is no expected performance impact since the process just copies
84files during runtime and exits automatically after completion.
85
86## Testing
87
88 - When the USB code update is disabled, the service will return directly
89without any update.
90 - Manually insert the USB key with the firmware upgrade package, and check
91whether the upgrade file is correct through the log.
92 - Simulate `dev/sda1` on qemu with some test scripts and start the
93service(eg: `systemcl start usb-code-update@sda1.service`)
94 - Verify that the ApplyTime attribute value is set to OnRest.
95 - Verify that the RequestedActivation property value is set to Active.
96 - Verify that the firmware update was successful.
97
98[1]: https://github.com/openbmc/phosphor-bmc-code-mgmt
99