1

One possible way is that, compare given inode with list of inodes in that directory. The list of inodes could be predetermined or it can be calculated run time, both ways have their own problems:

  • Predetermined list: List can be changed during this operation, i.e. files could be added or removed from that directory.

  • Run time list: If that directory has too many files, it's too much overhead for each access of any file in the system.

Is there any efficient solution/way for this? I have tried by comparing file by it's path, which was really a bad idea.

Nitinkumar Ambekar
  • 969
  • 20
  • 39
  • Why do you want to do this? It's generally discouraged for kernel modules to interact with the filesystem. – John Kugelman Sep 07 '15 at 06:45
  • @JohnKugelman, I just need to know if any file in my **foo** directory is being accessed by unwanted process. `fanotify` is also a good solution but it does't do it recursively. – Nitinkumar Ambekar Sep 07 '15 at 06:50
  • And why do you want to know that? Why does your kernel module know about directories at all? See [this LKML message](http://lkml.iu.edu/hypermail/linux/kernel/0005.3/0061.html): "Coding a kernel module is not like coding a user-mode program. You should never write a module that requires reading or writing to any logical device. The kernel is the thing that translates physical I/O to logical I/O. Attempting to perform logical I/O in the kernel is effectively going backwards.... it is possible to do file I/O in the kernel, but doing so is a severe violation of standard practice." – John Kugelman Sep 07 '15 at 06:55
  • @JohnKugelman, yes I agree, but there is no way to do this in user space. If you know any, please suggest. – Nitinkumar Ambekar Sep 07 '15 at 06:58
  • Ultimately I want to protect my directory from other process/users, so that they wouldn't be able to modify that. Only my process should be able to modify the data in that directory. – Nitinkumar Ambekar Sep 07 '15 at 07:11
  • @NTN: In your user-space program you can just create a directory with permissions `0700`, which forbid *other* users to access it. This is very common approach. – Tsyvarev Sep 07 '15 at 10:15
  • @Tsyvarev, `root` or `sudoers` can change the permission of any file and then delete it. Directory is supposed to be safe when my process is not running. File permission is not enough in this case. – Nitinkumar Ambekar Sep 07 '15 at 10:28
  • It would be another solution to get `filename` by `inode`, then check if belongs to interested path. But `inode` may belongs to many paths! I don't know if there is any way to deal with this. – Nitinkumar Ambekar Sep 07 '15 at 10:45
  • `root` has many ways to harm system. If you do not trust root, the only way is to store data on different machine(server) and interact with client, e.g., by network. Protecting from root is not a work for kernel or kernel module. (E.g., root can just `rmmod` your module). – Tsyvarev Sep 07 '15 at 11:02
  • @Tsyvarev, I agree, `root` is God! But at least I should make it hard to remove protected data, so that processes running with `root` privilege would not be able to modify data easily. – Nitinkumar Ambekar Sep 07 '15 at 11:10
  • It would be great if there would be file dependency for applications in `Linux`, like installed packages are depends on other packages, removing one such package will also remove all supporting ones. Similarly removing such dependent file(s) may ask for un-installation the related application to the `root`. – Nitinkumar Ambekar Sep 07 '15 at 11:26
  • As example, your dedicated process can store modification time of public file in some secret file, and then check it. In any case, you hardly make kernel-side protection stronger that user-side protection at the same cost(work and time). – Tsyvarev Sep 07 '15 at 11:46
  • @Tsyvarev, really. It's hard to make kernel-side protection stronger than user side, at least for `root` users. – Nitinkumar Ambekar Sep 07 '15 at 11:55
  • Is it possible to find out basic path such as `/opt/foo_dir/` by processing another fake path like `/tmp/link_to_opt/foo_dir/`? Notice that, path may also contain `./` in between. – Nitinkumar Ambekar Sep 07 '15 at 12:01

1 Answers1

0

Either if you do it in kernel mode or in user mode has no advantages. To see if an inode is indeed in some directory you have to read that directory as files are located in directories normally as a linear list. This can lead your process blocking for directory blocks to be present if not cached and, in that time, the directory contents can be modified. Only if you maintain the directory inode blocked while doing that operation can help, but this can add severe performance restrictions to your operating system. Another issue is that each filesystem is free to implement directory contents in it's own format. In userland you get an uniform directory format, but in kernel mode you have to deal with the different approaches for different filesystem types. Why do you need to know that? I can't imagine a scenario where this can be needed. Perhaps you can redesign your algorithm for the directory contents to be unnecessary.

By the way, dealing with complete paths or searching directories have obscure race conditions that can deal your system blocked someway. What can happen if, in the middle of your seach, somebody tries to unlink the inode you are searching for; or the directory contents must be modified; or some other process is using namei() to traverse through your directory upwards; or downwards. Have you think in all these possibilities?

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31
  • If you could have read all comments below the question, you might have noticed that, I am doing this to protect application specific files. There are two ways to do this, check by `path` or by `inode` being accessed. Yes, it is almost not possible to find out whether an `inode` belongs to some directory, therefore I am going with `path`, because it is the only way to do this as compared to another solution. [This answer](http://stackoverflow.com/a/28224286/2706918) would make it easy to get `absolute path` to compare. – Nitinkumar Ambekar Sep 08 '15 at 10:17
  • unix/linux was designed with the principle of implementing policy in user plane. Have you considered doing it in user space with SeLinux approach? If you finally follow this approach you'll have to pass regression tests to the whole kernel as, by specification, the linux kernel is subject to the same race conditions and issues as unix sysv was. As `namei()` routine just locks the inodes on _passing through_ there's strong possibilities of incurring in the same issues that the famous book *The design of the UNIX operating system* by Maurice J.Bach – Luis Colorado Sep 08 '15 at 10:59
  • ... pointed out already in 1986. The design guidelines were write functionality, not policy in the kernel and probably most modules in kernel depend on this principle. Probably you had better to change your design than to depend on this feature. Nothing in users' space depends on knowing about inode numbers. – Luis Colorado Sep 08 '15 at 11:00