0

I'm writing a kernel module, and I need to use the errno variable. I included <linux/errno.h> with no problems, and added extern int errno;, to my code.

I use the variable in the following way: errno = ENOENT;. When I compile the program I get the following warning, and I cannot load the module:

WARNING: "errno" [module path] undefined!

Why is that happening?

I am using a VM of Ubuntu 12.0.4

EDIT: My hooked open syscall looks like this:

asmlinkage int hooked_open(char* path, int flags){
   if(strstr(path, file_to_hide) != NULL){
      return -ENOENT;
   }
   return original_open(path, flags);
}

When running strace cat file_to_hide when the module is loaded the return value is 4294967294, no error.

When running strace on a file that does not exist, return value is -1 and ENOENT is raised. I would like to be able to imitate that.

Yonatan H
  • 43
  • 1
  • 9
  • 2
    Why do you want `errno`? It is not defined nor used in kernel code. – wallyk Dec 28 '20 at 19:12
  • I'm hooking a system call (open) and trying to return errors (for hiding the file) for certain inputs. – Yonatan H Dec 28 '20 at 19:14
  • @YonatanH `errno` is not used to pass failure reasons from Linux kernel system calls back to user space. Look at how [`open()` is implemented](https://elixir.bootlin.com/linux/latest/source/fs/open.c#L928) for how that's done. – Andrew Henle Dec 28 '20 at 20:16
  • Kernel module aside, even in ISO C, you should not be declaring `errno` explicitly as `extern int errno`. The appropriate declaration/definition for `errno` is included inside `errno.h` and it _might_ not be `extern int` – Ajay Brahmakshatriya Dec 28 '20 at 23:35
  • @AndrewHenle I always looked at the implementation of `do_sys_open()` rather that `vfs_open()`. Isn't that the original syscall? – Yonatan H Dec 29 '20 at 11:17
  • @Tsyvarev not completely, I'm trying to make sure the output (in strace) is the same when I encounter the file I want to hide. When returning `-ENOENT` I get only 2's complement of -2, and no error code at all. – Yonatan H Dec 29 '20 at 11:21
  • @YonatanH That depends on how your kernel module is going to hook the system call. The easiest way is probably a Linux Security Module: https://en.wikipedia.org/wiki/Linux_Security_Modules – Andrew Henle Dec 29 '20 at 11:22
  • @AndrewHenle I'm just a begginer with kernel modules, I'm hooking the syscall by overriding it's address in the syscall table. – Yonatan H Dec 29 '20 at 11:27
  • "When returning -ENOENT I get only 2's complement of -2, and no error code at all." - This should work. Probably, you are doing wrong things. Please, **show your code** (add it to the question post). – Tsyvarev Dec 29 '20 at 11:54
  • @Tsyvarev code added – Yonatan H Dec 29 '20 at 14:42
  • Return type for system calls is `long`, not `int`. – Tsyvarev Dec 29 '20 at 15:36
  • @Tsyvarev Thank you very much! I got confused with the open c command. – Yonatan H Dec 29 '20 at 17:45

1 Answers1

1

From man page of errno:

  1. errno is defined by the ISO C standard to be a modifiable lvalue of type int, and must not be explicitly declared;

  2. On some ancient systems, <errno.h> was not present or did not declare errno, so that it was necessary to declare errno manually (i.e., extern int errno). Do not do this. It long ago ceased to be necessary, and it will cause problems with modern versions of the C library.

There is no need to explicitly declare errno.

Krishna Kanth Yenumula
  • 2,533
  • 2
  • 14
  • 26