Project Description
Create a PoC for a modular packaged kernel. This means:
- the kernel package itself is minimal
- all device drivers are packaged as KMPs (kernel module packages)
- some other modules (e.g. subsystems like netfilter, SCSI, …) are packaged as KMPs, too
- module dependencies (depmod) translate into package dependencies and are handled by rpm
- hardware requirements are handled by zypper/YaST via modalias
- other system requirements (e.g. "this system needs a firewall") would be handled by patterns
Advantages
- minimal installation size and download size for kernel and drivers — only actually required/used modules are installed
- reduced build time: drivers don't need to be rebuilt with every kernel update, only if the driver itself (or the APIs it uses) are updated. KABI tracking ensures that drivers remain compatible with updated kernels.
- vice-versa, a driver update doesn't necessitate a full kernel update.
- this might also simplify QA procedures: driver testing could be separated from core kernel testing.
- replacement of in-box drivers by out-of-box drivers simplified; it would become a routine procedure
- conservative customers can update components selectively, reducing regression risks
- package management techniques (e.g. download statistics) can be used to track usage of drivers and identify modules to be disabled
- we could get rid of package bundles like
kernel-default-base
orkernel-default-extra
.
Disadvantages / Challenges
- "Missing driver problem": e.g. network controller breaks, new controller needs new driver → unavoidable, patterns e.g. "kernel-network-driver-all" or "kernel-usb-driver-all" as precaution (but this would forfeit a lot of the size advantage)
- weak dependencies, or dependencies that aren't expressed in depmod terms. We handle this partially already for initrd (
SUSE INITRD
mechanism). We must translate it into package dependencies - user space dependencies: many tools might not be prepared for a large number of missing drivers in an (open)SUSE environment. Need to look into dracut etc.
- is our KABI tracking good enough? So far it works well for the small number of KMPs, but what if we get 1000s of KMPs with complex dependencies?
- Does the KABI dependency tracking scale to this level, or will dependency checks be extremely slow?
- It gets more difficult to assess system supportablity. Tooling is required to verify that installed driver packages are compatible.
- we can't run depmod after every KMP installation, it'd be far too slow (I have a patched depmod available that would make this possible with "incremental" mode).
- avoid excessive meta data duplication (kernel changelog in every KMP)
- the KMP concept needs to be revised. The
multiversion(kernel)
property of KMPs allows to install the same KMP for different KABI versions, but doesn't work well for version updates of the KMP itself. That would be a big problem, because we update some drivers frequently. - do we need a means for kernel module management tools (modprobe) to hook into package management (zypper) for pulling in missing modules automatically?
- …
Goal for this Hackweek
- Make it possible to build "real" KMPs from the kernel package build. Note that the in-kernel
-kmp
packages such asdlm-kmp
aren't "real" KMPs; they use a hard kernel version dependency rather than KABI dependencies. - Hack on the kernel build scripts to enable modular packaging. Perhaps one-KMP-per-module as a first step, to experiment with module interdependencies. 2nd step would be combining modules into reasonable sets. Alternatively, start with a set of modules to be packaged as KMPs (e.g. device drivers) and increase the set step-by-step.
- Experiment with practical use of the modular kernel. Figure out problems with the interaction of module and package management. Play through the "missing driver" scenario, and try to find a concept for aworkaround.
Later goals
- Develop a modified KMP concept. Make version of the KABI the KMP was compiled against part of the package name rather than the version (instead of
foo-kmp-default-1.0_k5.3.18_59.5
, usefoo-kmp-default-5.3.18_59.5-1.0
, indicating module foo for the KABI of 5.3.18_59.5, version 1.0) - Tackle a few of the challenges above
- Explore possibilities to improve packaging of kernel firmware, too. Currently FW is packaged in big chunks by vendor. Packaging individual drivers might facilitate fine-grained dependencies (driver pulls in required FW packages).
This project is part of:
Hack Week 21 Hack Week 22
Activity
Comments
-
over 2 years ago by mwilck | Reply
Jun 27
I spent the day studying the kernel build scripts. Using them and understanding them are two different things. I'll try to use a similar approach as
kernel-default-base
: Just repackage existing modules. This will speed up development, as I'll avoid long build times for the kernel package. OBS repos created underhome:mwilck:ModularKernel
(not much to see yet). -
over 2 years ago by mwilck | Reply
Later
The kernel-default-image package now packages the whole set of modules from
kernel-default-base
, each module packaged separately. No actual compilation is done, the compiled modules are just taken fromkernel-default
, the same way as it's done inkernel-default-base
. If we ever want to change this, the real challenge will be how to determine the list of subpackages, as it's currently calculated dynamically frommodules.dep
. We would basically need to generate the list of subpackages from the list of.ko
files built during kernel compilation. I am not sure if that's possible. If not, we will have to do at least one "normal" build for every config to derive the module list first before modularly packaged kernels can be built. But we have a long way to go until then, anyway.Dependency resolution works the same way as for
kernel-default-base
; thus it's sufficient to list a set of desired modules or module-name-matching regular expressions, and the scripts will figure out the full set to satisfy all requirements.The module packages have
ksym()
requires and (if they export anything) alsoksym()
provides, as well asmodalias()
supplements.> rpm -qp --supplements ehci-pci-kmp-default-5.14.21-lp154.23.1.g49db222.0.x86_64.rpm modalias(kernel-default:pci:v*d*sv*sd*bc0Csc03i20*) modalias(kernel-default:pci:v0000104Ad0000CC00sv*sd*bc*sc*i*) > rpm -qp --requires ehci-pci-kmp-default-5.14.21-lp154.23.1.g49db222.0.x86_64.rpm coreutils grep kernel-default-image ksym(default:__dynamic_dev_dbg) = 22868a41 ksym(default:__fentry__) = bdfb6dbb ksym(default:__pci_register_driver) = c2126345 ksym(default:__stack_chk_fail) = d0da656b ksym(default:_dev_info) = fe960afa ksym(default:_dev_warn) = 5cba8a10 ksym(default:device_set_wakeup_capable) = 226a1ef2 ksym(default:dma_set_coherent_mask) = 93f12bc3 ksym(default:ehci_init_driver) = d72c5993 ksym(default:ehci_resume) = 645790fb ... > rpm -qp --provides ehci-hcd-kmp-default-5.14.21-lp154.23.1.g49db222.0.x86_64.rpm ehci-hcd-kmp = 5.14.21 ehci-hcd-kmp-default = 5.14.21-lp154.23.1.g49db222.0 ehci-hcd-kmp-default(x86-64) = 5.14.21-lp154.23.1.g49db222.0 kmod(ehci_hcd.ko) ksym(default:ehci_adjust_port_wakeup_flags) = e6bf909e ksym(default:ehci_handshake) = 1456664e ksym(default:ehci_hub_control) = 913627e8 ksym(default:ehci_init_driver) = d72c5993 ksym(default:ehci_reset) = 145925dc ksym(default:ehci_resume) = 645790fb ksym(default:ehci_setup) = 4048a7e9 ksym(default:ehci_suspend) = 2c94b03f
The build log is interesting, too.I had to modify the scripts looking for provides and supplements for this to work. Thus I'm shipping these as part of the package.
Not surprisingly, the package repo contains a long list of packages. Including modules from
-extra
, I built a set of almost 3000 packages. Not quite texlive, but getting closeI had to stop at this point; so I haven't done any installation tests with the KMPs generated this way yet. The dependencies look quite sane though. What's obviously missing at this point is some patterns to allow installing e.g. all netfilter modules. For drivers, modalias should work (
zypper inr --no-recommends
), but I havent't tested it. The repo also urgently needs my performance fixes for depmod from last year, which are unfortunately still unfinished. -
over 2 years ago by michals | Reply
The problem with this approach is that when you include the dependencies the subpackages may overlap, and while rpm itself would be fine with that because the modules coming from one kernel build are identical the packaging policy forbids it.
-
over 2 years ago by tiwai | Reply
What do you mean by "the dependencies the subpackages may overlap"? The same ksym() checksum provided by multiple kmps (of various versions)?
I guess a partial solution would be to embed the hard dependency from the result of depmod. e.g. if a module has dependency on another module abc (as found in depmod), we can put "Requires: abc-kmp-default = %{version}" explicitly at the build time. Also, a softdep could be interpreted with Supplements or such, too.
-
Similar Projects
Hacking on sched_ext by flonnegren
Description
Sched_ext upstream has some interesting issues open for grabs:
Goals
Send patches to sched_ext upstream
Also set up perfetto to trace some of the example schedulers.
Resources
https://github.com/sched-ext/scx
Improve various phones kernel mainline support (Qualcomm, Exynos, MediaTek) by pvorel
Similar to previous hackweeks ( https://hackweek.opensuse.org/projects/improve-qualcomm-soc-msm8994-slash-msm8992-kernel-mainline-support, https://hackweek.opensuse.org/projects/test-mainline-kernel-on-an-older-qualcomm-soc-msm89xx-explore-mainline-kernel-qualcomm-mainlining) try to improve kernel mainline support of various phones.
Model checking the BPF verifier by shunghsiyu
Project Description
BPF verifier plays a crucial role in securing the system (though less so now that unprivileged BPF is disabled by default in both upstream and SLES), and bugs in the verifier has lead to privilege escalation vulnerabilities in the past (e.g. CVE-2021-3490).
One way to check whether the verifer has bugs to use model checking (a formal verification technique), in other words, build a abstract model of how the verifier operates, and then see if certain condition can occur (e.g. incorrect calculation during value tracking of registers) by giving both the model and condition to a solver.
For the solver I will be using the Z3 SMT solver to do the checking since it provide a Python binding that's relatively easy to use.
Goal for this Hackweek
Learn how to use the Z3 Python binding (i.e. Z3Py) to build a model of (part of) the BPF verifier, probably the part that's related to value tracking using tristate numbers (aka tnum), and then check that the algorithm work as intended.
Resources
- Formal Methods for the Informal Engineer: Tutorial #1 - The Z3 Theorem Prover and its accompanying notebook is a great introduction into Z3
- Has a section specifically on model checking
- Software Verification and Analysis Using Z3 a great example of using Z3 for model checking
- Sound, Precise, and Fast Abstract Interpretation with Tristate Numbers - existing work that use formal verification to prove that the multiplication helper used for value tracking work as intended
- [PATCH v5 net-next 00/12] bpf: rewrite value tracking in verifier - initial patch set that adds tristate number to the verifier
Contributing to Linux Kernel security by pperego
Description
A couple of weeks ago, I found this blog post by Gustavo Silva, a Linux Kernel contributor.
I always strived to start again into hacking the Linux Kernel, so I asked Coverity scan dashboard access and I want to contribute to Linux Kernel by fixing some minor issues.
I want also to create a Linux Kernel fuzzing lab using qemu and syzkaller
Goals
- Fix at least 2 security bugs
- Create the fuzzing lab and having it running
The story so far
- Day 1: setting up a virtual machine for kernel development using Tumbleweed. Reading a lot of documentation, taking confidence with Coverity dashboard and with procedures to submit a kernel patch
- Day 2: I read really a lot of documentation and I triaged some findings on Coverity SAST dashboard. I have to confirm that SAST tool are great false positives generator, even for low hanging fruits.
- Day 3: Working on trivial changes after I read this blog post:
https://www.toblux.com/posts/2024/02/linux-kernel-patches.html. I have to take confidence
with the patch preparation and submit process yet.
- First trivial patch sent: using strtruefalse() macro instead of hard-coded strings in a staging driver for a lcd display
- Fix for a dereference before null check issue discovered by Coverity (CID 1601566) https://scan7.scan.coverity.com/#/project-view/52110/11354?selectedIssue=1601566
- Day 4: Triaging more issues found by Coverity.
- The patch for CID 1601566 was refused. The check against the NULL pointer was pointless so I prepared a version 2 of the patch removing the check.
- Fixed another dereference before NULL check in iwlmvmparsewowlaninfo_notif() routine (CID 1601547). This one was already submitted by another kernel hacker :(
- Day 5: Wrapping up. I had to do some minor rework on patch for CID 1601566. I found a stalker bothering me in private emails and people I interacted with me, advised he is a well known bothering person. Markus Elfring for the record.
Wrapping up: being back doing kernel hacking is amazing and I don't want to stop it. My battery pack is completely drained but changing the scope gave me a great twist and I really want to feel this energy not doing a single task for months.
I failed in setting up a fuzzing lab but I was too optimistic for the patch submission process.
The patches
Modernize ocfs2 by goldwynr
Ocfs2 has gone into a stage of neglect and disrepair. Modernize the code to generate enough interest.
Goals: * Change the mount sequence to use fscontext * Move from using bufferhead to bio/folios * Use iomap * Run it through xfstests
Switch software-o-o to parse repomd data by hennevogel
Currently software.opensuse.org search is using the OBS binary search for everything, even for packages inside the openSUSE distributions. Let's switch this to use repomd data from download.opensuse.org
A CLI for Harvester by mohamed.belgaied
[comment]: # Harvester does not officially come with a CLI tool, the user is supposed to interact with Harvester mostly through the UI [comment]: # Though it is theoretically possible to use kubectl to interact with Harvester, the manipulation of Kubevirt YAML objects is absolutely not user friendly. [comment]: # Inspired by tools like multipass from Canonical to easily and rapidly create one of multiple VMs, I began the development of Harvester CLI. Currently, it works but Harvester CLI needs some love to be up-to-date with Harvester v1.0.2 and needs some bug fixes and improvements as well.
Project Description
Harvester CLI is a command line interface tool written in Go, designed to simplify interfacing with a Harvester cluster as a user. It is especially useful for testing purposes as you can easily and rapidly create VMs in Harvester by providing a simple command such as:
harvester vm create my-vm --count 5
to create 5 VMs named my-vm-01
to my-vm-05
.
Harvester CLI is functional but needs a number of improvements: up-to-date functionality with Harvester v1.0.2 (some minor issues right now), modifying the default behaviour to create an opensuse VM instead of an ubuntu VM, solve some bugs, etc.
Github Repo for Harvester CLI: https://github.com/belgaied2/harvester-cli
Done in previous Hackweeks
- Create a Github actions pipeline to automatically integrate Harvester CLI to Homebrew repositories: DONE
- Automatically package Harvester CLI for OpenSUSE / Redhat RPMs or DEBs: DONE
Goal for this Hackweek
The goal for this Hackweek is to bring Harvester CLI up-to-speed with latest Harvester versions (v1.3.X and v1.4.X), and improve the code quality as well as implement some simple features and bug fixes.
Some nice additions might be: * Improve handling of namespaced objects * Add features, such as network management or Load Balancer creation ? * Add more unit tests and, why not, e2e tests * Improve CI * Improve the overall code quality * Test the program and create issues for it
Issue list is here: https://github.com/belgaied2/harvester-cli/issues
Resources
The project is written in Go, and using client-go
the Kubernetes Go Client libraries to communicate with the Harvester API (which is Kubernetes in fact).
Welcome contributions are:
- Testing it and creating issues
- Documentation
- Go code improvement
What you might learn
Harvester CLI might be interesting to you if you want to learn more about:
- GitHub Actions
- Harvester as a SUSE Product
- Go programming language
- Kubernetes API
"autoremove" functionality for zypper by e_bischoff
The purpose would be to have the equivalent of Ubuntu's "apt-get autoremove" functionality.
When you install package P, it might draw in dependancies D1, D2, ... Dn automatically.
When you later uninstall P, the dependancies D1, D2, ..., Dn might remain on your system.
If you keep installing and uninstalling packages, after a while your system remains cluttered with things you don't need.
The idea would be to mark all dependancies that were installed but not explicitely requested as "installed automatically". Then a command like "zypper autoremove" could remove them at once if they are not needed anymore.
Approaches seen online
After scouring forms for solutions these are some alias's used to replicate the functionality
zypper packages --unneeded | awk -F'|' 'NR==0 || NR==1 || NR==2 || NR==3 || NR==4 {next} {print $3}' | grep -v Name | sudo xargs zypper remove --clean-deps
This one is a script and has bashisms
bash mapfile -t unneeded < <(zypper --quiet pa --unneeded | awk '$1 == "i" { print $5, "-", $7 }') (( ${#unneeded@]} )) && sudo zypper --quiet rm --clean-deps --details "${unneeded@]}"
sudo zypper rm $(zypper pa --unneeded | awk '/i / {print $3}' FS='|' | uniq | tr -d ' ')
Based on testing zypper packages --orphaned
provides packages that are not in any repo, even if a user has explicitly installed them, so --orphaned
may not be the way to go, instead focusing on --unneeded
Ansible for add-on management by lmanfredi
Description
Machines can contains various combinations of add-ons and are often modified during the time.
The list of repos can change so I would like to create an automation able to reset the status to a given state, based on metadata available for these machines
Goals
Create an Ansible automation able to take care of add-on (repo list) configuration using metadata as reference
Resources
- Machines
- Repositories
- Developing modules
- Basic VM Guest management
- Module
zypper_repository_list
- ansible-collections community.general
Results
Created WIP project Ansible-add-on-openSUSE