Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/caitsith-patch/caitsith/realpath.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 386 - (hide annotations) (download) (as text)
Mon Nov 13 11:36:37 2023 UTC (4 months, 4 weeks ago) by kumaneko
File MIME type: text/x-csrc
File size: 16931 byte(s)


1 kumaneko 71 /*
2     * realpath.c
3     *
4     * Copyright (C) 2005-2012 NTT DATA CORPORATION
5     *
6 kumaneko 378 * Version: 0.2.11 2023/05/27
7 kumaneko 71 */
8    
9     #include "caitsith.h"
10 kumaneko 280
11 kumaneko 71 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
12     #include <linux/nsproxy.h>
13     #include <linux/mnt_namespace.h>
14     #endif
15 kumaneko 324 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
16     #include <linux/proc_fs.h>
17     #endif
18 kumaneko 71
19     /***** SECTION1: Constants definition *****/
20    
21     /***** SECTION2: Structure definition *****/
22    
23     /***** SECTION3: Prototype definition section *****/
24    
25 kumaneko 139 static char *cs_get_absolute_path(const struct path *path, char * const buffer,
26 kumaneko 71 const int buflen);
27     static char *cs_get_dentry_path(struct dentry *dentry, char * const buffer,
28     const int buflen);
29     static char *cs_get_local_path(struct dentry *dentry, char * const buffer,
30     const int buflen);
31     static int cs_const_part_length(const char *filename);
32    
33     /***** SECTION4: Standalone functions section *****/
34    
35     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
36    
37     /**
38     * cs_realpath_lock - Take locks for __d_path().
39     *
40     * Returns nothing.
41     */
42     static inline void cs_realpath_lock(void)
43     {
44     /* dcache_lock is locked by __d_path(). */
45     /* vfsmount_lock is locked by __d_path(). */
46     }
47    
48     /**
49     * cs_realpath_unlock - Release locks for __d_path().
50     *
51     * Returns nothing.
52     */
53     static inline void cs_realpath_unlock(void)
54     {
55     /* vfsmount_lock is unlocked by __d_path(). */
56     /* dcache_lock is unlocked by __d_path(). */
57     }
58    
59     #elif LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 36)
60    
61     /**
62     * cs_realpath_lock - Take locks for __d_path().
63     *
64     * Returns nothing.
65     */
66     static inline void cs_realpath_lock(void)
67     {
68     spin_lock(&dcache_lock);
69     /* vfsmount_lock is locked by __d_path(). */
70     }
71    
72     /**
73     * cs_realpath_unlock - Release locks for __d_path().
74     *
75     * Returns nothing.
76     */
77     static inline void cs_realpath_unlock(void)
78     {
79     /* vfsmount_lock is unlocked by __d_path(). */
80     spin_unlock(&dcache_lock);
81     }
82    
83     #elif defined(D_PATH_DISCONNECT) && !defined(CONFIG_SUSE_KERNEL)
84    
85     /**
86     * cs_realpath_lock - Take locks for __d_path().
87     *
88     * Returns nothing.
89     *
90     * Original unambiguous-__d_path.diff in patches.apparmor.tar.bz2 inversed the
91     * order of holding dcache_lock and vfsmount_lock. That patch was applied on
92     * (at least) SUSE 11.1 and Ubuntu 8.10 and Ubuntu 9.04 kernels.
93     *
94     * However, that patch was updated to use original order and the updated patch
95     * is applied to (as far as I know) only SUSE kernels.
96     *
97     * Therefore, I need to use original order for SUSE 11.1 kernels and inversed
98     * order for other kernels. I detect it by checking D_PATH_DISCONNECT and
99     * CONFIG_SUSE_KERNEL. I don't know whether other distributions are using the
100     * updated patch or not. If you got deadlock, check fs/dcache.c for locking
101     * order, and add " && 0" to this "#elif " block if fs/dcache.c uses original
102     * order.
103     */
104     static inline void cs_realpath_lock(void)
105     {
106     spin_lock(caitsith_exports.vfsmount_lock);
107     spin_lock(&dcache_lock);
108     }
109    
110     /**
111     * cs_realpath_unlock - Release locks for __d_path().
112     *
113     * Returns nothing.
114     */
115     static inline void cs_realpath_unlock(void)
116     {
117     spin_unlock(&dcache_lock);
118     spin_unlock(caitsith_exports.vfsmount_lock);
119     }
120    
121     #else
122    
123     /**
124     * cs_realpath_lock - Take locks for __d_path().
125     *
126     * Returns nothing.
127     */
128     static inline void cs_realpath_lock(void)
129     {
130     spin_lock(&dcache_lock);
131     spin_lock(caitsith_exports.vfsmount_lock);
132     }
133    
134     /**
135     * cs_realpath_unlock - Release locks for __d_path().
136     *
137     * Returns nothing.
138     */
139     static inline void cs_realpath_unlock(void)
140     {
141     spin_unlock(caitsith_exports.vfsmount_lock);
142     spin_unlock(&dcache_lock);
143     }
144    
145     #endif
146    
147     /***** SECTION5: Variables definition section *****/
148    
149     /***** SECTION6: Dependent functions section *****/
150    
151     /**
152     * cs_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
153     *
154     * @path: Pointer to "struct path".
155     * @buffer: Pointer to buffer to return value in.
156     * @buflen: Sizeof @buffer.
157     *
158     * Returns the buffer on success, an error code otherwise.
159     *
160     * Caller holds the dcache_lock and vfsmount_lock.
161     * Based on __d_path() in fs/dcache.c
162     */
163 kumaneko 139 static char *cs_get_absolute_path(const struct path *path, char * const buffer,
164 kumaneko 71 const int buflen)
165     {
166     #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
167     if (buflen < 256)
168     return ERR_PTR(-ENOMEM);
169     return caitsith_exports.d_absolute_path(path, buffer, buflen - 1);
170     #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
171     /*
172     * __d_path() will start returning NULL by backporting commit 02125a82
173     * "fix apparmor dereferencing potentially freed dentry, sanitize
174     * __d_path() API".
175     *
176     * Unfortunately, __d_path() after applying that commit always returns
177     * NULL when root is empty. d_absolute_path() is provided for TOMOYO
178     * 2.x and AppArmor but CaitSith does not use it, for CaitSith
179     * might be built as a loadable kernel module and there is no warrantee
180     * that CaitSith is recompiled after applying that commit. Also,
181     * I don't want to search /proc/kallsyms for d_absolute_path() because
182     * I want to keep CaitSith architecture independent. Thus, supply
183     * non empty root like AppArmor's d_namespace_path() did.
184     */
185     static bool cs_no_empty;
186     char *pos;
187 kumaneko 211
188 kumaneko 71 if (buflen < 256)
189     return ERR_PTR(-ENOMEM);
190     if (!cs_no_empty) {
191     struct path root = { };
192 kumaneko 211
193 kumaneko 71 pos = caitsith_exports.__d_path(path, &root, buffer,
194     buflen - 1);
195     } else {
196     pos = NULL;
197     }
198     if (!pos) {
199     struct task_struct *task = current;
200     struct path root;
201     struct path tmp;
202 kumaneko 211
203 kumaneko 71 spin_lock(&task->fs->lock);
204     root.mnt = task->nsproxy->mnt_ns->root;
205     root.dentry = root.mnt->mnt_root;
206     path_get(&root);
207     spin_unlock(&task->fs->lock);
208     tmp = root;
209     pos = caitsith_exports.__d_path(path, &tmp, buffer,
210     buflen - 1);
211     path_put(&root);
212     if (pos)
213     return pos;
214     /* Remember if __d_path() needs non empty root. */
215     cs_no_empty = true;
216     pos = ERR_PTR(-EINVAL);
217     }
218     return pos;
219     #else
220     char *pos = buffer + buflen - 1;
221     struct dentry *dentry = path->dentry;
222     struct vfsmount *vfsmnt = path->mnt;
223     const char *name;
224     int len;
225    
226     if (buflen < 256)
227     goto out;
228    
229     *pos = '\0';
230     for (;;) {
231     struct dentry *parent;
232 kumaneko 211
233 kumaneko 71 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
234     if (vfsmnt->mnt_parent == vfsmnt)
235     break;
236     dentry = vfsmnt->mnt_mountpoint;
237     vfsmnt = vfsmnt->mnt_parent;
238     continue;
239     }
240     parent = dentry->d_parent;
241     name = dentry->d_name.name;
242     len = dentry->d_name.len;
243     pos -= len;
244     if (pos <= buffer)
245     goto out;
246     memmove(pos, name, len);
247     *--pos = '/';
248     dentry = parent;
249     }
250     if (*pos == '/')
251     pos++;
252     len = dentry->d_name.len;
253     pos -= len;
254     if (pos < buffer)
255     goto out;
256     memmove(pos, dentry->d_name.name, len);
257     return pos;
258     out:
259     return ERR_PTR(-ENOMEM);
260     #endif
261     }
262    
263     /**
264     * cs_get_dentry_path - Get the path of a dentry.
265     *
266     * @dentry: Pointer to "struct dentry".
267     * @buffer: Pointer to buffer to return value in.
268     * @buflen: Sizeof @buffer.
269     *
270     * Returns the buffer on success, an error code otherwise.
271     *
272     * Based on dentry_path() in fs/dcache.c
273     */
274     static char *cs_get_dentry_path(struct dentry *dentry, char * const buffer,
275     const int buflen)
276     {
277     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
278     if (buflen < 256)
279     return ERR_PTR(-ENOMEM);
280     /* rename_lock is locked/unlocked by dentry_path_raw(). */
281     return dentry_path_raw(dentry, buffer, buflen - 1);
282     #else
283     char *pos = buffer + buflen - 1;
284 kumaneko 211
285 kumaneko 71 if (buflen < 256)
286     return ERR_PTR(-ENOMEM);
287     *pos = '\0';
288     spin_lock(&dcache_lock);
289     while (!IS_ROOT(dentry)) {
290     struct dentry *parent = dentry->d_parent;
291     const char *name = dentry->d_name.name;
292     const int len = dentry->d_name.len;
293 kumaneko 211
294 kumaneko 71 pos -= len;
295     if (pos <= buffer) {
296     pos = ERR_PTR(-ENOMEM);
297     break;
298     }
299     memmove(pos, name, len);
300     *--pos = '/';
301     dentry = parent;
302     }
303     spin_unlock(&dcache_lock);
304     if (pos == buffer + buflen - 1)
305     *--pos = '/';
306     return pos;
307     #endif
308     }
309    
310     /**
311     * cs_get_local_path - Get the path of a dentry.
312     *
313     * @dentry: Pointer to "struct dentry".
314     * @buffer: Pointer to buffer to return value in.
315     * @buflen: Sizeof @buffer.
316     *
317     * Returns the buffer on success, an error code otherwise.
318     */
319     static char *cs_get_local_path(struct dentry *dentry, char * const buffer,
320     const int buflen)
321     {
322     struct super_block *sb = dentry->d_sb;
323     char *pos = cs_get_dentry_path(dentry, buffer, buflen);
324 kumaneko 211
325 kumaneko 71 if (IS_ERR(pos))
326     return pos;
327     /* Convert from $PID to self if $PID is current thread. */
328     if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') {
329     char *ep;
330     const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10);
331 kumaneko 211
332 kumaneko 324 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
333 kumaneko 71 if (*ep == '/' && pid && pid ==
334 kumaneko 326 task_tgid_nr_ns(current, proc_pid_ns(sb))) {
335 kumaneko 324 pos = ep - 5;
336     if (pos < buffer)
337     goto out;
338     memmove(pos, "/self", 5);
339     }
340     #else
341     if (*ep == '/' && pid && pid ==
342 kumaneko 71 task_tgid_nr_ns(current, sb->s_fs_info)) {
343     pos = ep - 5;
344     if (pos < buffer)
345     goto out;
346     memmove(pos, "/self", 5);
347     }
348 kumaneko 324 #endif
349 kumaneko 71 goto prepend_filesystem_name;
350     }
351     /* Use filesystem name for unnamed devices. */
352     if (!MAJOR(sb->s_dev))
353     goto prepend_filesystem_name;
354     {
355 kumaneko 187 struct inode *inode = d_backing_inode(sb->s_root);
356 kumaneko 211
357 kumaneko 71 /*
358     * Use filesystem name if filesystems does not support rename()
359     * operation.
360     */
361 kumaneko 125 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
362 kumaneko 71 if (inode->i_op && !inode->i_op->rename)
363     goto prepend_filesystem_name;
364 kumaneko 198 #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
365 kumaneko 125 if (!inode->i_op->rename && !inode->i_op->rename2)
366     goto prepend_filesystem_name;
367 kumaneko 198 #else
368     if (!inode->i_op->rename)
369     goto prepend_filesystem_name;
370 kumaneko 125 #endif
371 kumaneko 71 }
372     /* Prepend device name. */
373     {
374     char name[64];
375     int name_len;
376     const dev_t dev = sb->s_dev;
377 kumaneko 211
378 kumaneko 71 name[sizeof(name) - 1] = '\0';
379     snprintf(name, sizeof(name) - 1, "dev(%u,%u):", MAJOR(dev),
380     MINOR(dev));
381     name_len = strlen(name);
382     pos -= name_len;
383     if (pos < buffer)
384     goto out;
385     memmove(pos, name, name_len);
386     return pos;
387     }
388     /* Prepend filesystem name. */
389     prepend_filesystem_name:
390     {
391     const char *name = sb->s_type->name;
392     const int name_len = strlen(name);
393 kumaneko 211
394 kumaneko 71 pos -= name_len + 1;
395     if (pos < buffer)
396     goto out;
397     memmove(pos, name, name_len);
398     pos[name_len] = ':';
399     }
400     return pos;
401     out:
402     return ERR_PTR(-ENOMEM);
403     }
404    
405     /**
406     * cs_realpath - Returns realpath(3) of the given pathname but ignores chroot'ed root.
407     *
408     * @path: Pointer to "struct path".
409     *
410     * Returns the realpath of the given @path on success, NULL otherwise.
411     *
412     * This function uses kzalloc(), so caller must kfree() if this function
413     * didn't return NULL.
414     */
415 kumaneko 139 char *cs_realpath(const struct path *path)
416 kumaneko 71 {
417     char *buf = NULL;
418     char *name = NULL;
419     unsigned int buf_len = PAGE_SIZE / 2;
420     struct dentry *dentry = path->dentry;
421     struct super_block *sb;
422 kumaneko 211
423 kumaneko 71 if (!dentry)
424     return NULL;
425     sb = dentry->d_sb;
426     while (1) {
427     char *pos;
428     struct inode *inode;
429 kumaneko 211
430 kumaneko 71 buf_len <<= 1;
431     kfree(buf);
432     buf = kmalloc(buf_len, GFP_NOFS);
433     if (!buf)
434     break;
435     /* To make sure that pos is '\0' terminated. */
436     buf[buf_len - 1] = '\0';
437 kumaneko 290 /* For "pipe:[\$]" and "socket:[\$]". */
438 kumaneko 71 if (dentry->d_op && dentry->d_op->d_dname) {
439     pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1);
440     goto encode;
441     }
442 kumaneko 187 inode = d_backing_inode(sb->s_root);
443 kumaneko 71 /*
444 kumaneko 280 * Use local name for "filesystems without rename() operation
445     * and device file" or "path without vfsmount" or "absolute
446     * name is unavailable" cases.
447 kumaneko 71 */
448 kumaneko 125 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
449 kumaneko 280 if (!path->mnt ||
450     (inode->i_op && !inode->i_op->rename &&
451     !(sb->s_type->fs_flags & FS_REQUIRES_DEV)))
452 kumaneko 71 pos = ERR_PTR(-EINVAL);
453     else {
454     /* Get absolute name for the rest. */
455     cs_realpath_lock();
456     pos = cs_get_absolute_path(path, buf, buf_len - 1);
457     cs_realpath_unlock();
458     }
459 kumaneko 198 #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
460 kumaneko 125 if (!path->mnt ||
461 kumaneko 280 (!inode->i_op->rename && !inode->i_op->rename2 &&
462     !(sb->s_type->fs_flags & FS_REQUIRES_DEV)))
463 kumaneko 186 pos = ERR_PTR(-EINVAL);
464 kumaneko 125 else
465     pos = cs_get_absolute_path(path, buf, buf_len - 1);
466 kumaneko 198 #else
467 kumaneko 280 if (!path->mnt ||
468     (!inode->i_op->rename &&
469     !(sb->s_type->fs_flags & FS_REQUIRES_DEV)))
470 kumaneko 198 pos = ERR_PTR(-EINVAL);
471     else
472     pos = cs_get_absolute_path(path, buf, buf_len - 1);
473 kumaneko 125 #endif
474 kumaneko 186 if (pos == ERR_PTR(-EINVAL))
475     pos = cs_get_local_path(path->dentry, buf,
476     buf_len - 1);
477 kumaneko 71 encode:
478     if (IS_ERR(pos))
479     continue;
480     name = cs_encode(pos);
481     break;
482     }
483     kfree(buf);
484     if (!name)
485     cs_warn_oom(__func__);
486     return name;
487     }
488    
489     /**
490     * cs_encode2 - Encode binary string to ascii string.
491     *
492     * @str: String in binary format. Maybe NULL.
493     * @str_len: Size of @str in byte.
494     *
495     * Returns pointer to @str in ascii format on success, NULL otherwise.
496     *
497     * This function uses kzalloc(), so caller must kfree() if this function
498     * didn't return NULL.
499     */
500     char *cs_encode2(const char *str, int str_len)
501     {
502     int i;
503     int len;
504     const char *p = str;
505     char *cp;
506     char *cp0;
507 kumaneko 211
508 kumaneko 71 if (!p)
509     return NULL;
510     len = str_len;
511     for (i = 0; i < str_len; i++) {
512     const unsigned char c = p[i];
513 kumaneko 211
514 kumaneko 71 if (!(c > ' ' && c < 127 && c != '\\'))
515     len += 3;
516     }
517     len++;
518     cp = kzalloc(len, GFP_NOFS);
519     if (!cp)
520     return NULL;
521     cp0 = cp;
522     p = str;
523     for (i = 0; i < str_len; i++) {
524     const unsigned char c = p[i];
525 kumaneko 211
526 kumaneko 71 if (c > ' ' && c < 127 && c != '\\') {
527     *cp++ = c;
528     } else {
529     *cp++ = '\\';
530     *cp++ = (c >> 6) + '0';
531     *cp++ = ((c >> 3) & 7) + '0';
532     *cp++ = (c & 7) + '0';
533     }
534     }
535     return cp0;
536     }
537    
538     /**
539     * cs_encode - Encode binary string to ascii string.
540     *
541     * @str: String in binary format. Maybe NULL.
542     *
543     * Returns pointer to @str in ascii format on success, NULL otherwise.
544     *
545     * This function uses kzalloc(), so caller must kfree() if this function
546     * didn't return NULL.
547     */
548     char *cs_encode(const char *str)
549     {
550     return str ? cs_encode2(str, strlen(str)) : NULL;
551     }
552    
553     /**
554     * cs_const_part_length - Evaluate the initial length without a pattern in a token.
555     *
556     * @filename: The string to evaluate. Maybe NULL.
557     *
558     * Returns the initial length without a pattern in @filename.
559     */
560     static int cs_const_part_length(const char *filename)
561     {
562     char c;
563     int len = 0;
564 kumaneko 211
565 kumaneko 71 if (!filename)
566     return 0;
567     while (1) {
568     c = *filename++;
569     if (!c)
570     break;
571     if (c != '\\') {
572     len++;
573     continue;
574     }
575     c = *filename++;
576     switch (c) {
577     case '0': /* "\ooo" */
578     case '1':
579     case '2':
580     case '3':
581     c = *filename++;
582 kumaneko 169 if (c < '0' || c > '7')
583     break;
584     c = *filename++;
585     if (c < '0' || c > '7')
586     break;
587     len += 4;
588     continue;
589 kumaneko 71 }
590     break;
591     }
592     return len;
593     }
594    
595     /**
596     * cs_fill_path_info - Fill in "struct cs_path_info" members.
597     *
598     * @ptr: Pointer to "struct cs_path_info" to fill in.
599     *
600     * Returns nothing.
601     *
602     * The caller sets "struct cs_path_info"->name.
603     */
604     void cs_fill_path_info(struct cs_path_info *ptr)
605     {
606     const char *name = ptr->name;
607     const int len = strlen(name);
608 kumaneko 211
609 kumaneko 71 ptr->total_len = len;
610     ptr->const_len = cs_const_part_length(name);
611 kumaneko 196 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
612     ptr->hash = full_name_hash(NULL, name, len);
613     #else
614 kumaneko 71 ptr->hash = full_name_hash(name, len);
615 kumaneko 196 #endif
616 kumaneko 71 }
617    
618     /**
619     * cs_get_exe - Get cs_realpath() of current process.
620     *
621     * Returns the cs_realpath() of current process on success, NULL otherwise.
622     *
623     * This function uses kzalloc(), so the caller must kfree()
624     * if this function didn't return NULL.
625     */
626     char *cs_get_exe(void)
627     {
628     struct mm_struct *mm;
629 kumaneko 139 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
630 kumaneko 71 struct vm_area_struct *vma;
631     #endif
632 kumaneko 139 struct file *exe_file;
633 kumaneko 211
634 kumaneko 359 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
635 kumaneko 71 if (current->flags & PF_KTHREAD)
636     return kstrdup("<kernel>", GFP_NOFS);
637 kumaneko 359 #else
638     if (segment_eq(get_fs(), KERNEL_DS))
639     return kstrdup("<kernel>", GFP_NOFS);
640     #endif
641 kumaneko 71 mm = current->mm;
642     if (!mm)
643     goto task_has_no_mm;
644 kumaneko 359 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
645     /* Not using get_mm_exe_file() as it is not exported. */
646     rcu_read_lock();
647     exe_file = rcu_dereference(mm->exe_file);
648 kumaneko 386 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)
649     if (exe_file && !get_file_rcu(&exe_file))
650     exe_file = NULL;
651     #else
652 kumaneko 359 if (exe_file && !get_file_rcu(exe_file))
653     exe_file = NULL;
654 kumaneko 386 #endif
655 kumaneko 359 rcu_read_unlock();
656     #elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
657 kumaneko 310 exe_file = get_mm_exe_file(mm);
658     #else
659 kumaneko 71 down_read(&mm->mmap_sem);
660 kumaneko 139 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
661     /* Not using get_mm_exe_file() as it is not exported. */
662     exe_file = mm->exe_file;
663 kumaneko 71 #else
664 kumaneko 139 exe_file = NULL;
665 kumaneko 71 for (vma = mm->mmap; vma; vma = vma->vm_next) {
666     if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
667 kumaneko 139 exe_file = vma->vm_file;
668 kumaneko 71 break;
669     }
670     }
671     #endif
672 kumaneko 139 if (exe_file)
673     get_file(exe_file);
674 kumaneko 71 up_read(&mm->mmap_sem);
675 kumaneko 310 #endif
676 kumaneko 139 if (exe_file) {
677     char *cp = cs_realpath(&exe_file->f_path);
678 kumaneko 211
679 kumaneko 139 fput(exe_file);
680 kumaneko 71 return cp;
681 kumaneko 139 }
682 kumaneko 71 task_has_no_mm:
683     /* I'don't know. */
684     return kstrdup("<unknown>", GFP_NOFS);
685     }
686    
687     /**
688     * cs_get_exename - Get cs_realpath() of current process.
689     *
690     * @buf: Pointer to "struct cs_path_info".
691     *
692     * Returns true on success, false otherwise.
693     *
694     * This function uses kzalloc(), so the caller must kfree()
695     * if this function returned true.
696     */
697     bool cs_get_exename(struct cs_path_info *buf)
698     {
699     buf->name = cs_get_exe();
700     if (buf->name) {
701     cs_fill_path_info(buf);
702     return true;
703     }
704     return false;
705     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26