Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# To use this config with your editor, follow the instructions at:
# http://editorconfig.org

root = true

[*]
charset = utf-8
insert_final_newline = true
indent_style = space
indent_size = 4

[Makefile]
indent_style = tab
17 changes: 15 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
dist/*
*.o
/dist
dkms
dkms.8
dkms.bash-completion
dkms.zsh-completion
dkms_framework.conf
dkms_autoinstaller
dkms.service
dkms_common.postinst
debian_kernel_install.d
debian_kernel_postinst.d
debian_kernel_preinst.d
debian_kernel_prerm.d
redhat_kernel_install.d

test_cmd_expected_output.log
test_cmd_output.log
9 changes: 4 additions & 5 deletions COPYING
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

Expand Down Expand Up @@ -304,8 +304,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
with this program; if not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

Expand All @@ -329,8 +328,8 @@ necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.

<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
<signature of Moe Ghoul>, 1 April 1989
Moe Ghoul, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
Expand Down
45 changes: 21 additions & 24 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
RELEASE_DATE := "1 October 2024"
RELEASE_DATE := "12 Sep 2025"
RELEASE_MAJOR := 3
RELEASE_MINOR := 1
RELEASE_MICRO := 0
RELEASE_MINOR := 2
RELEASE_MICRO := 2
RELEASE_NAME := dkms
RELEASE_VERSION := $(RELEASE_MAJOR).$(RELEASE_MINOR).$(RELEASE_MICRO)
RELEASE_STRING := $(RELEASE_NAME)-$(RELEASE_VERSION)
Expand Down Expand Up @@ -29,7 +29,7 @@ SED_SUBSTITUTIONS = \
%: %.in
$(SED) $(SED_SUBSTITUTIONS) $< > $@

all: \
GENERATED= \
dkms \
dkms.8 \
dkms_autoinstaller \
Expand All @@ -38,23 +38,17 @@ all: \
dkms_common.postinst \
dkms_framework.conf \
dkms.service \
kernel_install.d_dkms \
kernel_postinst.d_dkms \
kernel_prerm.d_dkms
debian_kernel_install.d \
debian_kernel_postinst.d \
debian_kernel_preinst.d \
debian_kernel_prerm.d \
redhat_kernel_install.d

all: $(GENERATED)

clean:
-rm -rf dist/
-rm -rf dkms
-rm -rf dkms.8
-rm -rf dkms_autoinstaller
-rm -rf dkms.bash-completion
-rm -rf dkms.zsh-completion
-rm -rf dkms_common.postinst
-rm -rf dkms_framework.conf
-rm -rf dkms.service
-rm -rf kernel_install.d_dkms
-rm -rf kernel_postinst.d_dkms
-rm -rf kernel_prerm.d_dkms
$(RM) $(GENERATED)

install: all
$(if $(strip $(VAR)),$(error Setting VAR is not supported))
Expand All @@ -65,29 +59,32 @@ ifneq (,$(DESTDIR))
$(if $(filter $(DESTDIR)%,$(KCONF)),$(error Using a DESTDIR as prefix for KCONF is no longer supported))
endif
install -D -m 0755 dkms $(DESTDIR)$(SBIN)/dkms
install -D -m 0755 dkms_common.postinst $(DESTDIR)$(LIBDIR)/common.postinst
install -D -m 0755 dkms_autoinstaller $(DESTDIR)$(LIBDIR)/dkms_autoinstaller
$(if $(strip $(ETC)),$(error Setting ETC is not supported))
install -D -m 0644 dkms_framework.conf $(DESTDIR)/etc/dkms/framework.conf
install -d -m 0755 $(DESTDIR)/etc/dkms/framework.conf.d
$(if $(strip $(BASHDIR)),$(error Setting BASHDIR is not supported))
install -D -m 0644 dkms.bash-completion $(DESTDIR)/usr/share/bash-completion/completions/dkms
install -D -m 0644 dkms.zsh-completion $(DESTDIR)/usr/share/zsh/site-functions/_dkms
install -D -m 0644 dkms.8 $(DESTDIR)/usr/share/man/man8/dkms.8
install -D -m 0755 kernel_install.d_dkms $(DESTDIR)$(KINSTALL)/40-dkms.install
install -D -m 0755 kernel_postinst.d_dkms $(DESTDIR)$(KCONF)/postinst.d/dkms
install -D -m 0755 kernel_prerm.d_dkms $(DESTDIR)$(KCONF)/prerm.d/dkms

install-redhat: install
ifneq (,$(DESTDIR))
$(if $(filter $(DESTDIR)%,$(SYSTEMD)),$(error Using a DESTDIR as prefix for SYSTEMD is no longer supported))
endif
install -D -m 0644 dkms.service $(DESTDIR)$(SYSTEMD)/dkms.service
install -D -m 0755 redhat_kernel_install.d $(DESTDIR)$(KINSTALL)/40-dkms.install
install -D -m 0755 dkms_common.postinst $(DESTDIR)$(LIBDIR)/common.postinst

install-debian: install
$(if $(strip $(SHAREDIR)),$(error Setting SHAREDIR is not supported))
install -D -m 0755 dkms_autoinstaller $(DESTDIR)$(LIBDIR)/dkms_autoinstaller
install -D -m 0755 dkms_apport.py $(DESTDIR)/usr/share/apport/package-hooks/dkms_packages.py
install -D -m 0755 kernel_postinst.d_dkms $(DESTDIR)$(KCONF)/header_postinst.d/dkms
install -D -m 0755 dkms_common.postinst $(DESTDIR)$(LIBDIR)/common.postinst
install -D -m 0755 debian_kernel_install.d $(DESTDIR)$(KINSTALL)/40-dkms.install
install -D -m 0755 debian_kernel_postinst.d $(DESTDIR)$(KCONF)/postinst.d/dkms
install -D -m 0755 debian_kernel_postinst.d $(DESTDIR)$(KCONF)/header_postinst.d/dkms
install -D -m 0755 debian_kernel_preinst.d $(DESTDIR)$(KCONF)/preinst.d/dkms
install -D -m 0755 debian_kernel_prerm.d $(DESTDIR)$(KCONF)/prerm.d/dkms

install-doc:
$(if $(strip $(DOC)),$(error Setting DOCDIR is not supported))
Expand Down
164 changes: 79 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,134 +1,124 @@
Dynamic Kernel Module System (DKMS)
==
This intention of this README is to explain how DKMS can be used in conjunction
with tarballs which contain a dkms.conf file within them.
# Dynamic Kernel Module System (DKMS)

This intention of this README is to explain how DKMS can be used in conjunction with tarballs which contain a dkms.conf file within them.

The DKMS project (and any updates) can be found at: https://github.com/dell/dkms

Installation
--

Installation is performed from the source directory with one of the following
commands:
## Installation

Installation is performed from the source directory with one of the following commands:

```
make install
make install-debian
make install-redhat
```

Distribution specific installations (RPM, DEB, etc.) are not contained in this
source repository.
Distribution specific installations (RPM, DEB, etc.) are not contained in this source repository.


Installation via DKMS Tarballs
--
## Installation of DKMS Tarballs

DKMS can install directly from the following:

1. Generic module source tarballs which contain a dkms.conf file
2. Specially created DKMS tarballs with module source, pre-built module
binaries and a dkms.conf file
3. Specially created DKMS tarballs with pre-built module binaries and a
dkms.conf file
4. Manual placement of module source and dkms.conf file into
`/usr/src/<module>-<moduleversion>/` directory
2. Specially created DKMS tarballs with module source, pre-built module binaries and a `dkms.conf` file
3. Specially created DKMS tarballs with pre-built module binaries and a `dkms.conf` file
4. Manual placement of module source and `dkms.conf` file into `/usr/src/<module>-<moduleversion>/` directory

In order to load any tarball into the DKMS tree, you must use the following
command:
In order to load any tarball into the DKMS tree, you must use the following command:

```
# dkms ldtarball /path/to/dkms_enabled.tar.gz
```

This command will first inspect the tarball to ensure that it contains a
dkms.conf configuration file for that module. If it cannot find this file
anywhere within the archive, then the ldtarball will fail.

From here, it will place the source in the tarball into
`/usr/src/<module>-<moduleversion>/`. If source already exists in the directory,
it will not overwrite it unless the --force option is specified. If the tarball
is of type "c" above and does not contain source, it will only continue to load
the tarball if existing module source is found in
`/usr/src/<module>-<moduleversion>/` or if the --force option is specified.
This command will first inspect the tarball to ensure that it contains a `dkms.conf` configuration file for that module.
If it cannot find this file anywhere within the archive, then the `ldtarball` command will fail.

Continuing on, if the tarball is of type "b" or "c" it will then load any
pre-built binaries found within the tarball into the dkms tree, but will stop
short of installing them. Thus, all pre-built binaries will then be of in the
*built* state when checked from the `dkms status` command. You can then use the
`dkms install` command to install any of these binaries.
From here, it will place the source in the tarball into `/usr/src/<module>-<moduleversion>/`.
If source already exists in the directory, it will not overwrite it unless the `--force` option is specified.
If the tarball is of type "c" above and does not contain source, it will only continue to load the tarball if existing module source is found in `/usr/src/<module>-<moduleversion>/` or if the `--force` option is specified.

To create a tarball of type "1" above, you need only to take module source and a
dkms.conf file for that module and create a tarball from them. Tarballs of
type *2* or type *3* are created with the `dkms mktarball` command. To create
a type *3* tarball, you must specify the flag `--binaries-only` with the
`mktarball`.
Continuing on, if the tarball is of type "b" or "c" it will then load any pre-built binaries found within the tarball into the DKMS tree, but will stop short of installing them.
Thus, all pre-built binaries will then be of in the *built* state when checked from the `dkms status` command. You can then use the `dkms install` command to install any of these binaries.

To create a tarball of type "1" above, you need only to take module source and a `dkms.conf` file for that module and create a tarball from them.
Tarballs of type *2* or type *3* are created with the `dkms mktarball` command.
To create a type *3* tarball, you must specify the flag `--binaries-only` along with the `mktarball` command.

### Installation on Systems with no Module Source and/or Compiler

Installation on Systems with no Module Source and/or Compiler
--
If you choose not to load module source on your system or if you choose not to load a compiler such as gcc onto your system, DKMS can still be used to install modules.
It does this through use of DKMS binary only tarballs as explained in this README under tarballs of type *c*.

If you choose not to load module source on your system or if you choose not to
load a compiler such as gcc onto your system, DKMS can still be used to install
modules. It does this through use of DKMS binary only tarballs as explained in
this README under tarballs of type *c*.

If your system does not have module source, loading the dkms tarball will fail
because of this. To avoid this, use the --force flag, as such:
If your system does not have module source, loading the dkms tarball will fail because of this.
To avoid this, use the `--force` flag, as such:

```
# dkms ldtarball /path/to/dkms_enabled.tar.gz --force
```

This will load the pre-built binaries into the dkms tree, and create the
directory `/usr/src/<module>-<moduleversion>/` which will only contain the
module's dkms.conf configuration file. Once the tarball is loaded, you can then
use `dkms install` to install any of the pre-built modules.
This will load the pre-built binaries into the dkms tree, and create the directory `/usr/src/<module>-<moduleversion>/` which will only contain the module's `dkms.conf` configuration file.
Once the tarball is loaded, you can then use `dkms install` to install any of the pre-built modules.

Of course, since the module source will not be located in your DKMS tree, you will not be able to build any modules with DKMS for this package.

Of course, since module source will not be located in your dkms tree, you will
not be able to build any modules with DKMS for this package.

Module signing
--
## Module signing

By default, DKMS generates a self signed certificate for signing modules at
build time and signs every module that it builds before it gets compressed in
the configured kernel compression mechanism of choice.
By default, DKMS generates a self signed certificate for signing modules at build time and signs every module that it builds before it gets compressed in the configured kernel compression mechanism of choice.

This requires the `openssl` command to be present on the system.
Private key and certificate are auto generated the first time DKMS is run and placed in `/var/lib/dkms`.
These certificate files can be pre-populated with your own certificates of choice.

Private key and certificate are auto generated the first time DKMS is run and
placed in `/var/lib/dkms`. These certificate files can be pre-populated with
your own certificates of choice.
The location as well can be changed by setting the appropriate variables in `/etc/dkms/framework.conf`.
For example, to allow usage of the system default Ubuntu `update-secureboot-policy` set the configuration file as follows:

The location as well can be changed by setting the appropriate variables in
`/etc/dkms/framework.conf`. For example, to allow usage of the system default
Ubuntu `update-secureboot-policy` set the configuration file as follows:
```
mok_signing_key="/var/lib/shim-signed/mok/MOK.priv"
mok_certificate="/var/lib/shim-signed/mok/MOK.der"
```
NOTE: If any of the files specified by `mok_signing_key` and
`mok_certificate` are non-existant, dkms will re-create both files.

The paths specified in `mok_signing_key`, `mok_certificate` and `sign_file` can
use the variable `${kernelver}` to represent the target kernel version.
NOTE: If any of the files specified by `mok_signing_key` and `mok_certificate` are non-existant, DKMS will re-create both files.

The paths specified in `mok_signing_key`, `mok_certificate` and `sign_file` can use the variable `${kernelver}` to represent the target kernel version.

```
sign_file="/lib/modules/${kernelver}/build/scripts/sign-file"
```

The variable `mok_signing_key` can also be a `pkcs11:...` string for a [PKCS#11
engine](https://www.rfc-editor.org/rfc/rfc7512), as long as the `sign_file`
program supports it.
The variable `mok_signing_key` can also be a `pkcs11:...` string for a [PKCS#11 engine](https://www.rfc-editor.org/rfc/rfc7512), as long as the `sign_file` program supports it.

### Code Signing extended key usage validation

Your kernel might be patched and compiled with the option `CONFIG_CHECK_CODESIGN_EKU` to assist with compliance to the NIAP Protection Profile for General Purpose Operating Systems.
Page 35 of [version 4.3 of the specification](https://www.niap-ccevs.org/protectionprofiles/469) states:

Secure Boot
--
```
* The OS shall validate the extendedKeyUsage field according to the following rules:
* Certificates used for trusted updates and executable code integrity
verification shall have the Code Signing Purpose (id-kp 3 with OID
1.3.6.1.5.5.7.3.3) in the extendedKeyUsage field.
```

On an UEFI system with Secure Boot enabled, modules require signing (as
described in the above paragraph) before they can be loaded and the firmware of
the system must know the correct public certificate to verify the module
signature.
So from DKMS 3.1.7 the MOK self signed certificate is now generated with the `extendedKeyUsage` set to `codeSigning`.
This requires version *1.1.1 or newer* of the `openssl` command to be present on the system.

In case your system is validating the extended key usage and you have autogenerated keys from a DKMS version prior to 3.1.7, the keys need to be regenerated.
For example, assuming the default configuration:

```
# rm -fr /var/lib/dkms/mok.{key,pub}
# dkms generate_mok
Signing key: /var/lib/dkms/mok.key
Public certificate (MOK): /var/lib/dkms/mok.pub
```


## Secure Boot

On an UEFI system with Secure Boot enabled, modules require signing (as described in the above paragraph) before they can be loaded and the firmware of the system must know the correct public certificate to verify the module signature.

For importing the MOK certificate make sure `mokutil` is installed.

Expand Down Expand Up @@ -189,11 +179,15 @@ signer: DKMS module signing key

The module can now be loaded without issues.

Further Documentation
--
### MOK certificate encryption algorithm

UEFI specification 2.11 [contains a list of valid encryption keys](https://uefi.org/specs/UEFI/2.11/37_Secure_Technologies.html#encryption-algorithm-properties) for the MOK certificate.
The list is quite limited, basically offering only RSA as a valid key type.
For maximum compatibility, DKMS generates the MOK certificate with a *2048 bit RSA key with SHA-2 256 as a digest*.


## Further Documentation

Once DKMS is installed, you can reference its man page for further information
on different DKMS options and also to understand the formatting of a module's
dkms.conf configuration file.
Once DKMS is installed, you can reference its man page for further information on different DKMS options and also to understand the formatting of a module's `dkms.conf` configuration file.

The DKMS project is located at: https://github.com/dell/dkms
Loading
Loading