Add module nat20device to linux examples.#99
Add module nat20device to linux examples.#99werwurm wants to merge 3 commits intowerwurm/linux_example_nat20libfrom
Conversation
This module creates a new character device class intended to implement the nat20 service protocol implementing DICE based device state attestation and an embedded CA.
LCOV of commit
|
There was a problem hiding this comment.
Pull request overview
Adds a new example Linux kernel module (“nat20device”) intended to provide a NAT20 character-device interface (with optional certificate exposure) and wires it into the Buildroot external tree plus CI so the module is built in automated workflows.
Changes:
- Introduces the
nat20devicekernel module framework (char device + optional securityfs certificate file). - Adds Buildroot package definitions/configuration to build/install
nat20device.koand enables it in the QEMU defconfig. - Updates developer tooling (envsetup) and CI workflow to build and verify
nat20device.ko.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| examples/linux/nat20device/nat20device.c | Implements nat20device framework: instance registry, char device fops, optional certificate reader via securityfs. |
| examples/linux/nat20device/include/nat20device.h | Public API for registering/unregistering a nat20device instance and dispatch/cert callbacks. |
| examples/linux/nat20device/Makefile | Out-of-tree kernel module build targets (modules/install/clean). |
| examples/linux/nat20device/Kbuild | Kbuild rules for building nat20device.o with include path. |
| examples/linux/br_external/utils/envsetup.sh | Exports NAT20DEVICE_OVERRIDE_SRCDIR and adds rebuild target help. |
| examples/linux/br_external/package/nat20device/nat20device.mk | Buildroot package recipe for the nat20device kernel module. |
| examples/linux/br_external/package/nat20device/Config.in | Buildroot menuconfig entry for enabling nat20device. |
| examples/linux/br_external/configs/qemu_br_defconfig | Enables BR2_PACKAGE_NAT20DEVICE=y in the QEMU Buildroot config. |
| examples/linux/br_external/Config.in | Sources the nat20device Buildroot package Config.in. |
| .github/workflows/linux-kmod-build.yml | Adds CI steps to build and verify nat20device.ko. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| instance->cdev_fops.owner = owner; | ||
| instance->cdev_fops.open = nat20device_open; | ||
| instance->cdev_fops.release = nat20device_release; | ||
| instance->cdev_fops.write = nat20device_write; | ||
| instance->cdev_fops.read = nat20device_read; | ||
| instance->cert_fops.owner = owner; | ||
| instance->cert_fops.open = nat20device_cert_fops_open; | ||
| instance->cert_fops.release = nat20device_cert_fops_release; | ||
| instance->cert_fops.read = nat20device_cert_fops_read; | ||
|
|
||
| /* Initialize character device */ | ||
| cdev_init(&instance->cdev, &instance->cdev_fops); | ||
| instance->cdev.owner = owner; |
There was a problem hiding this comment.
Because the owner depends on this module, this module cannot be unloaded while the owner has its reference counter increased due to an open file.
| void nat20device_unregister_driver(struct nat20device_driver* driver) { | ||
| struct nat20device_driver_instance* instance; | ||
|
|
||
| if (!driver) return; | ||
|
|
||
| instance = to_nat20device_instance(driver); | ||
|
|
||
| pr_info("NAT20: Unregistering driver instance %s%d\n", NAT20DEVICE_DEVICE_NAME, instance->id); | ||
|
|
||
| if (instance->nat20device_cert_file) { | ||
| /* Remove certificate sysfs file and directory */ | ||
| securityfs_remove(instance->nat20device_cert_file); | ||
| } | ||
| if (instance->nat20device_cert_dir) { | ||
| securityfs_remove(instance->nat20device_cert_dir); | ||
| } | ||
|
|
||
| /* Remove device node */ | ||
| device_destroy(nat20device_class, nat20device_dev_number + instance->id); | ||
|
|
||
| /* Remove character device */ | ||
| cdev_del(&instance->cdev); | ||
|
|
||
| /* Free ID */ | ||
| ida_free(&nat20device_ida, instance->id); | ||
|
|
||
| /* Free instance */ | ||
| kfree(instance); |
There was a problem hiding this comment.
Unregister must only be called when the underlying driver is unloaded. But the underlying driver is the owner of any file operations which means it cannot be unloaded while a file is open.
| /* Check if we have a response buffer */ | ||
| if (!file_priv->response.data) return -EAGAIN; | ||
|
|
||
| /* Calculate bytes remaining from current offset */ | ||
| if (file_priv->response.size <= *f_pos) { | ||
| /* All data has been read */ | ||
| return 0; | ||
| } | ||
| bytes_remaining = file_priv->response.size - *f_pos; | ||
|
|
||
| /* Read up to count bytes */ | ||
| bytes_to_read = min(count, bytes_remaining); | ||
|
|
||
| /* Copy to userspace */ | ||
| ret = copy_to_user(buf, (char*)file_priv->response.data + *f_pos, bytes_to_read); | ||
| if (ret) return -EFAULT; | ||
|
|
||
| /* Update offset */ | ||
| *f_pos += bytes_to_read; | ||
|
|
||
| return bytes_to_read; |
This module creates a new character device class intended to implement
the nat20 service protocol implementing DICE based device state
attestation and an embedded CA.