Comparing path names, and the path may be non-existent - linux

I am trying to write a file blacklist kernel module for school. In this module I need to compare paths names from intercepted system calls(which can be relative or absolute) to a list of blacklisted path names(which are all absolute). These paths may or may not exist at the time the module is loaded. I have been told to look at the system calls in /fs/open.c for getting a struct path. I tried user_path but it returns an error if the path is non-existent. Any help would be appreciated.
Edit: Also, I am on the 3.0.4 kernel. I have the strings for blacklisted path names read from the file (yeah I know its bad but this is the way they want it done) and inserted into the internal list. I am just stuck on the comparison of the blacklist path name and path name/file name passed to the intercepted system calls.

Related

in linux cli, if someone says 'create this: /george/trees/poppet' how do I know whether 'poppet' is the 3rd directory or a file?

Clarification: the directory /george/ exists when I am given the task, and I do know how to read the attribute in cli showing that it is a directory. The balance of the path requested does not exist, so the only way I can tell if 'poppet' is a file or directory is by convention. This question comes from an issue I had with interpretation of this line, so am interested in knowing if there is a convention. This occurred using Ubuntu, but would be relevant in any distro, methinks.

How to resolve system directories paths independently of system locale?

TLDR
I need to get paths to system directories like "Screenshots":
On an English system. I can just use this one:
C:/Users/User/Pictures/Screenshots
How do I get the path to "Screenshots" directory on a non-English system?
C:/Users/User/Pictures/[NAME]
Description
I have a file manager app, it displays system directories and loads them on click.
The app can run system commands via Powershell and use Node.js (preferred)
Problem
The problem is, it only works if the system has English system language.
Currently, to resolve the "Screenshots" directory path, the app simply joins the User directory with the word "Screenshots"
const pictures = electronRemote.app.getPath('pictures')
const screenshots = PATH.join(pictures, 'Screenshots')
link to the line in code
Expectedly, the C:/Users/User/Screenshots path only exists on English systems.
One way to solve this is to use short names, at least on Windows, I know that system directories have short names like SCREEN~1 and WALLPA~1 for Screenshots and Wallpapers directories, but if I use these names the paths will look like this:
C:/Users/User/SCREEN~1 instead of C:/Users/User/Screenshots throughout the app.
And even if I were to run these paths through a function to convert it to readable name, how would I know which word to replace it with? I need to get the name in the system's language.
Are these translations stored somewhere on the system? Can I just retrieve the translated directory name and use that in the code above?
Question
How do I make it to get / resolve the actual path of system directories like Screenshots and Wallpapers, independently of system locale?
If you know how to do it, could you please suggest the solution for all platforms (Win, Mac, Linux)?
Should I just use the short names like SCREEN~1 and then automatically replace all the occurrences in UI and also filter all paths through a function that replaces this short name with the actual path throughout the whole app? Seems like a lot of work, this approach

How do I get the filename of an open std::fs::File in Rust?

I have an open std::fs::File, and I want to get it's filename, e.g. as a PathBuf. How do I do that?
The simple solution would be to just save the path used in the call to File::open. Unfortunately, this does not work for me. I am trying to write a program that reads log files, and the program that writes the logs keep changing the filenames as part of it's log rotation. So the file may very well have been renamed since it was opened. This is on Linux, so renaming open files is possible.
How do I get around this issue, and get the current filename of an open file?
On a typical Unix filesystem, a file may have multiple filenames at once, or even none at all. The file metadata is stored in an inode, which has a unique inode number, and this inode number can be linked from any number of directory entries. However, there are no reverse links from the inode back to the directory entries.
Given an open File object in Rust, you can get the inode number using the ino() method. If you know the directory the log file is in, you can use std::fs::read_dir() to iterate over all entries in that directory, and each entry will also have an ino() method, so you can find the one(s) matching your open file object. Of course this approach is subject to race conditions – the directory entry may already be gone again once you try to do anything with it.
On linux, files handles held by the current process can be found under /proc/self/fd. These look and act like symlinks to the original files (though I think they may technically be something else - perhaps someone who knows more can chip in).
You can therefore recover the (possibly changed) file name by constructing the correct path in /proc/self/fd using your file descriptor, and then following the symlink back to the filesystem.
This snippet shows the steps:
use std::fs::read_link;
use std::os::unix::io::AsRawFd;
use std::path::PathBuf;
// if f is your std::fs::File
// first construct the path to the symlink under /proc
let path_in_proc = PathBuf::from(format!("/proc/self/fd/{}", f.as_raw_fd()));
// ...and follow it back to the original file
let new_file_name = read_link(path_in_proc).unwrap();

How to determine if file system path is directory or file?

I'm looking to determine if a file system path is directory or file. I'm not looking to checking for the type an existing path. I'm trying to determine if the path function argument string is a referring to a directory or file.
How do I make a distinction between a file and a directory when this:
/Users/thomas/Desktop/node
The following path could refer to a directory node, or a file node without an extension.
I was thinking about using a trailing / to connote directory.
So this would mean a directory:
/Users/thomas/Desktop/node/
And this would mean a file:
/Users/thomas/Desktop/node
However node's path methods like .resolve() and .join() do not take into consideration the trailing / and always remove it. So is this good practice?
There is no way to check if an arbitrary string is a directory or file if it does not exist.
However for existing paths, you can use fs.stat() on the path, which will give you an object that has methods for checking the path type (e.g. isDirectory(), isFile(), etc).

Resolve filesystem paths (possibly with symlinks) with Node.js

I need a way to verify whether or not a file is under a specific path. If the path is /var/www and the file is /var/www/something/something-else/file, I need to return true. If the file is /var/www/../../etc/passwd, I need to return false.
In PHP land, I usually use a function called realpath():
realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input path and returns the canonicalized absolute pathname.
I run realpath() on both the desired path and the full file path, then determine if the desired path is a substring of the result of the fully resolved file path. If it is, I return true.
Is there a function for Node.js that achieves the same goal? path.resolve() gets me half way, but doesn't handle any symlinks that are actually in the filesystem. fs.readlink() has absolutely no documentation at all, and may not directly apply since I won't always have symlinks.
Must I loop through each part of the path, resolving symlinks as I go, or is there a more canonical method?
Node also has fs.realpath() so that should work the same way as in PHP.

Resources