blob: 41d323385f2754066248b31377077a435b278cc2 [file] [log] [blame]
Lorenz Brunc7b036b2023-06-01 12:23:57 +02001package kmod
2
3import (
4 "errors"
5 "fmt"
6 "syscall"
7 "unsafe"
8
9 "golang.org/x/sys/unix"
10)
11
12// LoadModule loads a kernel module into the kernel.
13func LoadModule(file syscall.Conn, params string, flags uintptr) error {
14 sc, err := file.SyscallConn()
15 if err != nil {
16 return fmt.Errorf("failed getting SyscallConn handle: %w", err)
17 }
18 paramsRaw, err := unix.BytePtrFromString(params)
19 if err != nil {
20 return errors.New("invalid null byte in params")
21 }
Tim Windelschmidt06c19642024-04-23 15:07:40 +020022 var errNo unix.Errno
Lorenz Brunc7b036b2023-06-01 12:23:57 +020023 ctrlErr := sc.Control(func(fd uintptr) {
Tim Windelschmidt06c19642024-04-23 15:07:40 +020024 _, _, errNo = unix.Syscall(unix.SYS_FINIT_MODULE, fd, uintptr(unsafe.Pointer(paramsRaw)), flags)
Lorenz Brunc7b036b2023-06-01 12:23:57 +020025 })
26 if ctrlErr != nil {
27 return fmt.Errorf("unable to get control handle: %w", ctrlErr)
28 }
Tim Windelschmidt06c19642024-04-23 15:07:40 +020029 if errNo != unix.Errno(0) {
30 return errNo
Lorenz Brunc7b036b2023-06-01 12:23:57 +020031 }
32 return nil
33}
34
35// UnloadModule unloads a kernel module from the kernel.
36func UnloadModule(name string, flags uintptr) error {
37 nameRaw, err := unix.BytePtrFromString(name)
38 if err != nil {
39 return errors.New("invalid null byte in name")
40 }
Tim Windelschmidt06c19642024-04-23 15:07:40 +020041 _, _, errNo := unix.Syscall(unix.SYS_DELETE_MODULE, uintptr(unsafe.Pointer(nameRaw)), flags, 0)
42 if errNo != unix.Errno(0) {
43 return errNo
Lorenz Brunc7b036b2023-06-01 12:23:57 +020044 }
Tim Windelschmidt06c19642024-04-23 15:07:40 +020045 return nil
Lorenz Brunc7b036b2023-06-01 12:23:57 +020046}