Re: Error while building a kernel module with mkdir(2)

From: Yuri <yuri_at_aetern.org>
Date: Mon, 18 Sep 2023 21:38:18 UTC
Rocky Hotas wrote:
> Hello!
> I hope this is the right ML to discuss about this issue. I am trying to
> build the example kernel module presented in paragraph 2.1 of
> 
> Designing BSD Rootkits: An Introduction to Kernel Hacking
> by Joseph Kong
> 
> However, I get this error:
> 
> mkdir_hook.c:42:9: error: implicit declaration of function 'mkdir' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
>         return(mkdir(td, syscall_args));
>                ^
> mkdir_hook.c:57:45: error: use of undeclared identifier 'mkdir'
>                         sysent[SYS_mkdir].sy_call = (sy_call_t *)mkdir;
> 
> mkdir(2) requires `#include <sys/stat.h>' and I added it (while it was
> not in the code from the book), but nothing changes.

That include is for userland that needs mkdir(2).  Your wrapper likely
wants to override the in-kernel sys_mkdir() defined in <sys/sysproto.h>.

> What's still wrong?
> 
> After this text, I paste the code and the Makefile (written following
> https://docs.freebsd.org/en/books/arch-handbook/driverbasics/).
> 
> Bye!
> 
> Rocky
> 
> 
> 
> === code: mkdir_hook.c ===
> 
> #include <sys/types.h>
> #include <sys/param.h>          /* defines used in kernel.h */
> #include <sys/proc.h>
> #include <sys/module.h>
> #include <sys/sysent.h>
> #include <sys/kernel.h>         /* types used in module initialization */
> #include <sys/systm.h>          /* uprintf */
> #include <sys/syscall.h>
> #include <sys/sysproto.h>
> #include <sys/stat.h>           /* mkdir(2) */
> 
> 
> /* mkdir system call hook. */
> static int
> mkdir_hook(struct thread *td, void *syscall_args)
> {
>         struct mkdir_args /* {
>                 char *path;
>                 int mode;
>         } */ *uap;
> 
>         uap = (struct mkdir_args *)syscall_args;
>         char path[255];
>         size_t done;
>         int error;
>         error = copyinstr(uap->path, path, 255, &done);
> 
>         if (error != 0)
>                 return(error);
>         /* Print a debug message. */
>         uprintf("The directory \"%s\" will be created with the following"
>                 " permissions: %o\n", path, uap->mode);
> 
>         return(mkdir(td, syscall_args));
> }
> 
> /* The function called at load/unload. */
> static int
> load(struct module *module, int cmd, void *arg)
> {
>         int error = 0;
>         switch (cmd) {
>                 case MOD_LOAD:
>                         /* Replace mkdir with mkdir_hook. */
>                         sysent[SYS_mkdir].sy_call = (sy_call_t *)mkdir_hook;
>                         break;
>                 case MOD_UNLOAD:
>                         /* Change everything back to normal. */
>                         sysent[SYS_mkdir].sy_call = (sy_call_t *)mkdir;
>                         break;
> 
>                 default:
>                         error = EOPNOTSUPP;
>                         break;
>         }
> 
>         return(error);
> }
> 
> static moduledata_t
> mkdir_hook_mod = {
>         "mkdir_hook",   /* module name */
>         load,           /* event handler */
>         NULL            /* extra data */
> };
> 
> DECLARE_MODULE(mkdir_hook, mkdir_hook_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
> 
> 
> 
> === Makefile ===
> 
> KMOD=mkdir_hook
> SRCS=mkdir_hook.c
> .include <bsd.kmod.mk>
>