How can I get a filename from a file descriptor inside a kernel module?
Don't call SYS_readlink
- use the same method that procfs
does when one of those links is read. Start with the code in proc_pid_readlink()
and proc_fd_link()
in fs/proc/base.c
.
Broadly, given an int fd
and a struct files_struct *files
from the task you're interested in (which you have taken a reference to), you want to do:
char *tmp;
char *pathname;
struct file *file;
struct path *path;
spin_lock(&files->file_lock);
file = fcheck_files(files, fd);
if (!file) {
spin_unlock(&files->file_lock);
return -ENOENT;
}
path = &file->f_path;
path_get(path);
spin_unlock(&files->file_lock);
tmp = (char *)__get_free_page(GFP_KERNEL);
if (!tmp) {
path_put(path);
return -ENOMEM;
}
pathname = d_path(path, tmp, PAGE_SIZE);
path_put(path);
if (IS_ERR(pathname)) {
free_page((unsigned long)tmp);
return PTR_ERR(pathname);
}
/* do something here with pathname */
free_page((unsigned long)tmp);
If your code is running in process-context (eg. invoked through a syscall) and the file descriptor is from the current process, then you can use current->files
for the current task's struct files_struct *
.
Related videos on Youtube
Siddhant
I'm an experienced software developer located in Munich, Germany. I've been writing Python code close to 10 years now. I've had the chance to use it at almost all the companies where I've worked so far, and also currently maintain a few open source projects written in the language. The technologies I'm currently focusing on include Python, Tornado, Django, Vue.js, Terraform, SaltStack, AWS, and a few others in the Backend/DevOps space.
Updated on June 04, 2022Comments
-
Siddhant almost 2 years
I need to get the name of a file from a given file descriptor, inside a small linux kernel module that I wrote. I tried the solution given at Getting Filename from file descriptor in C, but for some reason, it prints out garbage values (on using
readlink
on/proc/self/fd/NNN
as mentioned in the solution). How can I do it? -
Siddhant over 12 yearsNice. That worked. Thanks! Quick question though. What purpose do the
path_get
andpath_put
calls serve (because removing them doesn't have much of an effect on my program)? Also, any idea why wouldn'tsys_readlink
work? -
caf over 12 years@Siddhant: The
path_get()
andpath_put()
calls are required for correctness, because they pin the path so that it doesn't go away while you are trying to work with it (all thestruct path
contains is a pair of pointers, to astruct vfsmount
and astruct dentry
). -
sherrellbc almost 9 yearsAlso, why is it necessary to call
path_get
and get a reference to the path structure? -
sherrellbc almost 9 yearsIs there a reason or benefit of allocating a single page from memory as opposed to using
kmalloc
? Is it simply because you know a page would fit the worst-case requirement for the path data? It seems that the whole mess witihIS_ERR
andPTR_ERR
could be avoided by simply using the latter memory allocation method. -
caf almost 9 years@sherrellbc: Right, the pagesize is an upper limit on the possible size of the pathname, so there's no point in using
kmalloc()
- the return value ofd_path()
has to be tested withIS_ERR()
regardless. It is necessary to callpath_get()
to prevent the path from going away after we release->file_lock
(because at that point, the file could be closed by another thread in parallel). We don't want to keep->file_lock
held for longer than necessary because it's a spinlock. -
caf almost 9 yearsIn fact I'm not even sure if it's allowed to call
d_path()
while holding a spinlock. -
Nitinkumar Ambekar over 8 yearsIf your code is running in process-context ... then you can use current->files for the current task's files_struct. See this answer.
-
wallek876 over 4 yearsWouldn't be possible in this case to use,
rcu_read_lock()/rcu_read_unlock()
, instead ofspin_lock/spin_unlock
? it seems that is only reading the values of the files struct without updating them. -
caf over 4 years@wallek876: I believe that using RCU protection for this would require taking a reference on the
struct file
itself instead, because the file reference count can be decremented to zero while the RCU lock is held. -
teknopaul almost 3 yearsWhats wrong with just
strcpy(n, file->f_path.dentry->d_name.name);
-
caf almost 3 years@teknopaul: That will only look at the final component of the path, not the full pathname. It also races with dcache modifications like renames.