~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/akari/probe.c

Version: ~ [ linux-5.2-rc4 ] ~ [ linux-5.1.9 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.50 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.125 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.181 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.181 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.68 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * probe.c
  3  *
  4  * Copyright (C) 2010-2013  Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
  5  *
  6  * Functions in this file are doing runtime address resolution based on byte
  7  * code comparison in order to allow LKM-based LSM modules to access built-in
  8  * functions and variables which are not exported to LKMs.
  9  * Since functions in this file are assuming that using identical source code,
 10  * identical kernel config and identical compiler generates identical byte code
 11  * output, functions in this file may not work on some architectures and/or
 12  * environments.
 13  *
 14  * This file is used by AKARI and CaitSith. This file will become unnecessary
 15  * when LKM-based LSM module comes back and TOMOYO 2.x becomes a LKM-based LSM
 16  * module.
 17  */
 18 
 19 #include "probe.h"
 20 
 21 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) || LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 3)
 22 
 23 /**
 24  * probe_kernel_read - Wrapper for kernel_read().
 25  *
 26  * @file:   Pointer to "struct file".
 27  * @offset: Starting position.
 28  * @addr:   Buffer.
 29  * @count:  Size of @addr.
 30  *
 31  * Returns return value from kernel_read().
 32  */
 33 static int __init probe_kernel_read(struct file *file, unsigned long offset,
 34                                     char *addr, unsigned long count)
 35 {
 36 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 8)
 37         /*
 38          * I can't use kernel_read() because seq_read() returns -EPIPE
 39          * if &pos != &file->f_pos .
 40          */
 41         mm_segment_t old_fs;
 42         unsigned long pos = file->f_pos;
 43         int result;
 44         file->f_pos = offset;
 45         old_fs = get_fs();
 46         set_fs(get_ds());
 47         result = vfs_read(file, (void __user *)addr, count, &file->f_pos);
 48         set_fs(old_fs);
 49         file->f_pos = pos;
 50         return result;
 51 #else
 52         return kernel_read(file, offset, addr, count);
 53 #endif
 54 }
 55 
 56 /**
 57  * probe_find_symbol - Find function's address from /proc/kallsyms .
 58  *
 59  * @keyline: Function to find.
 60  *
 61  * Returns address of specified function on success, NULL otherwise.
 62  */
 63 static void *__init probe_find_symbol(const char *keyline)
 64 {
 65         struct file *file = NULL;
 66         char *buf;
 67         unsigned long entry = 0;
 68         {
 69 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
 70                 struct file_system_type *fstype = get_fs_type("proc");
 71                 struct vfsmount *mnt = vfs_kern_mount(fstype, 0, "proc", NULL);
 72 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
 73                 struct file_system_type *fstype = NULL;
 74                 struct vfsmount *mnt = do_kern_mount("proc", 0, "proc", NULL);
 75 #else
 76                 struct file_system_type *fstype = get_fs_type("proc");
 77                 struct vfsmount *mnt = kern_mount(fstype);
 78 #endif
 79                 struct dentry *root;
 80                 struct dentry *dentry;
 81                 /*
 82                  * We embed put_filesystem() here because it is not exported.
 83                  */
 84                 if (fstype)
 85                         module_put(fstype->owner);
 86                 if (IS_ERR(mnt))
 87                         goto out;
 88                 root = dget(mnt->mnt_root);
 89 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16)
 90                 mutex_lock(&root->d_inode->i_mutex);
 91                 dentry = lookup_one_len("kallsyms", root, 8);
 92                 mutex_unlock(&root->d_inode->i_mutex);
 93 #else
 94                 down(&root->d_inode->i_sem);
 95                 dentry = lookup_one_len("kallsyms", root, 8);
 96                 up(&root->d_inode->i_sem);
 97 #endif
 98                 dput(root);
 99                 if (IS_ERR(dentry))
100                         mntput(mnt);
101                 else {
102 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
103                         struct path path = { mnt, dentry };
104                         file = dentry_open(&path, O_RDONLY, current_cred());
105 #else
106                         file = dentry_open(dentry, mnt, O_RDONLY
107 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
108                                            , current_cred()
109 #endif
110                                            );
111 #endif
112                 }
113         }
114         if (IS_ERR(file) || !file)
115                 goto out;
116         buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
117         if (buf) {
118                 int len;
119                 int offset = 0;
120                 while ((len = probe_kernel_read(file, offset, buf,
121                                                 PAGE_SIZE - 1)) > 0) {
122                         char *cp;
123                         buf[len] = '\0';
124                         cp = strrchr(buf, '\n');
125                         if (!cp)
126                                 break;
127                         *(cp + 1) = '\0';
128                         offset += strlen(buf);
129                         cp = strstr(buf, keyline);
130                         if (!cp)
131                                 continue;
132                         *cp = '\0';
133                         while (cp > buf && *(cp - 1) != '\n')
134                                 cp--;
135                         entry = simple_strtoul(cp, NULL, 16);
136                         break;
137                 }
138                 kfree(buf);
139         }
140         filp_close(file, NULL);
141 out:
142         return (void *) entry;
143 }
144 
145 #endif
146 
147 #if defined(LSM_HOOK_INIT)
148 
149 /*
150  * Dummy variable for finding location of
151  * "struct security_hook_heads security_hook_heads".
152  */
153 struct security_hook_heads probe_dummy_security_hook_heads;
154 
155 /**
156  * probe_security_bprm_committed_creds - Dummy function which does identical to security_bprm_committed_creds() in security/security.c.
157  *
158  * @bprm: Pointer to "struct linux_binprm".
159  *
160  * Returns nothing.
161  */
162 void probe_security_bprm_committed_creds(struct linux_binprm *bprm)
163 {
164         do {
165                 struct security_hook_list *p;
166                 list_for_each_entry(p, &probe_dummy_security_hook_heads.
167                                     bprm_committed_creds, list)
168                         p->hook.bprm_committed_creds(bprm);
169         } while (0);
170 }
171 
172 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
173 
174 /*
175  * Dummy variable for finding address of
176  * "struct security_operations *security_ops".
177  */
178 static struct security_operations *probe_dummy_security_ops;
179 
180 /**
181  * probe_security_file_alloc - Dummy function which does identical to security_file_alloc() in security/security.c.
182  *
183  * @file: Pointer to "struct file".
184  *
185  * Returns return value from security_file_alloc().
186  */
187 static int probe_security_file_alloc(struct file *file)
188 {
189         return probe_dummy_security_ops->file_alloc_security(file);
190 }
191 
192 #if defined(CONFIG_ARM)
193 
194 /**
195  * probe_security_ops_on_arm - Find security_ops on ARM.
196  *
197  * @base: Address of security_file_alloc().
198  *
199  * Returns address of security_ops on success, NULL otherwise.
200  */
201 static void * __init probe_security_ops_on_arm(unsigned int *base)
202 {
203         static unsigned int *ip4ret;
204         int i;
205         const unsigned long addr = (unsigned long) &probe_dummy_security_ops;
206         unsigned int *ip = (unsigned int *) probe_security_file_alloc;
207         for (i = 0; i < 32; ip++, i++) {
208                 if (*(ip + 2 + ((*ip & 0xFFF) >> 2)) != addr)
209                         continue;
210                 ip = base + i;
211                 ip4ret = (unsigned int *) (*(ip + 2 + ((*ip & 0xFFF) >> 2)));
212                 return &ip4ret;
213         }
214         ip = (unsigned int *) probe_security_file_alloc;
215         for (i = 0; i < 32; ip++, i++) {
216                 /*
217                  * Find
218                  *   ldr r3, [pc, #offset1]
219                  *   ldr r3, [r3, #offset2]
220                  * sequence.
221                  */
222                 if ((*ip & 0xFFFFF000) != 0xE59F3000 ||
223                     (*(ip + 1) & 0xFFFFF000) != 0xE5933000)
224                         continue;
225                 ip4ret = (unsigned int *) (*(ip + 2 + ((*ip & 0xFFF) >> 2)));
226                 ip4ret += (*(ip + 1) & 0xFFF) >> 2;
227                 if ((unsigned long) ip4ret != addr)
228                         continue;
229                 ip = base + i;
230                 ip4ret = (unsigned int *) (*(ip + 2 + ((*ip & 0xFFF) >> 2)));
231                 ip4ret += (*(ip + 1) & 0xFFF) >> 2;
232                 return &ip4ret;
233         }
234         return NULL;
235 }
236 
237 #endif
238 
239 #endif
240 
241 #if defined(CONFIG_ARM) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
242 /**
243  * probe_find_vfsmount_lock_on_arm - Find vfsmount_lock spinlock on ARM.
244  *
245  * @ip:   Address of dummy function's entry point.
246  * @addr: Address of the variable which is used within @function.
247  * @base: Address of function's entry point.
248  *
249  * Returns address of vfsmount_lock on success, NULL otherwise.
250  */
251 static void * __init probe_find_vfsmount_lock_on_arm(unsigned int *ip,
252                                                      unsigned long addr,
253                                                      unsigned int *base)
254 {
255         int i;
256         for (i = 0; i < 32; ip++, i++) {
257                 static unsigned int *ip4ret;
258                 if (*(ip + 2 + ((*ip & 0xFFF) >> 2)) != addr)
259                         continue;
260                 ip = base + i;
261                 ip4ret = (unsigned int *) (*(ip + 2 + ((*ip & 0xFFF) >> 2)));
262                 return &ip4ret;
263         }
264         return NULL;
265 }
266 #endif
267 
268 /**
269  * probe_find_variable - Find variable's address using dummy.
270  *
271  * @function: Pointer to dummy function's entry point.
272  * @addr:     Address of the variable which is used within @function.
273  * @symbol:   Name of symbol to resolve.
274  *
275  * This trick depends on below assumptions.
276  *
277  * (1) @addr is found within 128 bytes from @function, even if additional
278  *     code (e.g. debug symbols) is added.
279  * (2) It is safe to read 128 bytes from @function.
280  * (3) @addr != Byte code except @addr.
281  */
282 static void * __init probe_find_variable(void *function, unsigned long addr,
283                                          const char *symbol)
284 {
285         int i;
286         u8 *base;
287         u8 *cp = function;
288 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) || LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 3)
289         if (*symbol == ' ')
290                 base = probe_find_symbol(symbol);
291         else
292 #endif
293                 base = __symbol_get(symbol);
294         if (!base)
295                 return NULL;
296 #if defined(CONFIG_ARM) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) && !defined(LSM_HOOK_INIT)
297         if (function == probe_security_file_alloc)
298                 return probe_security_ops_on_arm((unsigned int *) base);
299 #endif
300 #if defined(CONFIG_ARM) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
301         return probe_find_vfsmount_lock_on_arm(function, addr,
302                                                (unsigned int *) base);
303 #endif
304         /* First, assume absolute adressing mode is used. */
305         for (i = 0; i < 128; i++) {
306                 if (*(unsigned long *) cp == addr)
307                         return base + i;
308                 cp++;
309         }
310         /* Next, assume PC-relative addressing mode is used. */
311 #if defined(CONFIG_S390)
312         cp = function;
313         for (i = 0; i < 128; i++) {
314                 if ((unsigned long) (cp + (*(int *) cp) * 2 - 2) == addr) {
315                         static void *cp4ret;
316                         cp = base + i;
317                         cp += (*(int *) cp) * 2 - 2;
318                         cp4ret = cp;
319                         return &cp4ret;
320                 }
321                 cp++;
322         }
323 #endif
324         cp = function;
325         for (i = 0; i < 128; i++) {
326                 if ((unsigned long) (cp + sizeof(int) + *(int *) cp) == addr) {
327                         static void *cp4ret;
328                         cp = base + i;
329                         cp += sizeof(int) + *(int *) cp;
330                         cp4ret = cp;
331                         return &cp4ret;
332                 }
333                 cp++;
334         }
335         cp = function;
336         for (i = 0; i < 128; i++) {
337                 if ((unsigned long) (long) (*(int *) cp) == addr) {
338                         static void *cp4ret;
339                         cp = base + i;
340                         cp = (void *) (long) (*(int *) cp);
341                         cp4ret = cp;
342                         return &cp4ret;
343                 }
344                 cp++;
345         }
346         return NULL;
347 }
348 
349 #if defined(LSM_HOOK_INIT)
350 
351 /**
352  * probe_security_hook_heads - Find address of "struct security_hook_heads security_hook_heads".
353  *
354  * Returns pointer to "struct security_hook_heads" on success, NULL otherwise.
355  */
356 struct security_hook_heads * __init probe_security_hook_heads(void)
357 {
358         const unsigned int offset = offsetof(struct security_hook_heads,
359                                              bprm_committed_creds);
360         void *cp;
361         /* Guess "struct security_hook_heads security_hook_heads;". */
362         cp = probe_find_variable(probe_security_bprm_committed_creds,
363                                  ((unsigned long)
364                                   &probe_dummy_security_hook_heads) + offset,
365                                  " security_bprm_committed_creds\n");
366         if (!cp) {
367                 printk(KERN_ERR
368                        "Can't resolve security_bprm_committed_creds().\n");
369                 return NULL;
370         }
371         /* This should be "struct security_hook_heads security_hook_heads;". */
372         cp = ((void *) (*(unsigned long *) cp)) - offset;
373         printk(KERN_INFO "security_hook_heads=%p\n", cp);
374         return cp;
375 }
376 
377 #else
378 
379 /**
380  * probe_security_ops - Find address of "struct security_operations *security_ops".
381  *
382  * Returns pointer to "struct security_operations" on success, NULL otherwise.
383  */
384 struct security_operations * __init probe_security_ops(void)
385 {
386         struct security_operations **ptr;
387         struct security_operations *ops;
388 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
389         void *cp;
390         /* Guess "struct security_operations *security_ops;". */
391         cp = probe_find_variable(probe_security_file_alloc, (unsigned long)
392                                  &probe_dummy_security_ops,
393                                  " security_file_alloc\n");
394         if (!cp) {
395                 printk(KERN_ERR "Can't resolve security_file_alloc().\n");
396                 return NULL;
397         }
398         /* This should be "struct security_operations *security_ops;". */
399         ptr = *(struct security_operations ***) cp;
400 #else
401         /* This is "struct security_operations *security_ops;". */
402         ptr = (struct security_operations **) __symbol_get("security_ops");
403 #endif
404         if (!ptr) {
405                 printk(KERN_ERR "Can't resolve security_ops structure.\n");
406                 return NULL;
407         }
408         printk(KERN_INFO "security_ops=%p\n", ptr);
409         ops = *ptr;
410         if (!ops) {
411                 printk(KERN_ERR "No security_operations registered.\n");
412                 return NULL;
413         }
414         return ops;
415 }
416 
417 #endif
418 
419 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
420 
421 /**
422  * probe_find_task_by_vpid - Find address of find_task_by_vpid().
423  *
424  * Returns address of find_task_by_vpid() on success, NULL otherwise.
425  */
426 void * __init probe_find_task_by_vpid(void)
427 {
428         void *ptr;
429 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
430         ptr = probe_find_symbol(" find_task_by_vpid\n");
431 #else
432         ptr = __symbol_get("find_task_by_vpid");
433 #endif
434         if (!ptr) {
435                 printk(KERN_ERR "Can't resolve find_task_by_vpid().\n");
436                 return NULL;
437         }
438         printk(KERN_INFO "find_task_by_vpid=%p\n", ptr);
439         return ptr;
440 }
441 
442 /**
443  * probe_find_task_by_pid_ns - Find address of find_task_by_pid().
444  *
445  * Returns address of find_task_by_pid_ns() on success, NULL otherwise.
446  */
447 void * __init probe_find_task_by_pid_ns(void)
448 {
449         void *ptr;
450 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
451         ptr = probe_find_symbol(" find_task_by_pid_ns\n");
452 #else
453         ptr = __symbol_get("find_task_by_pid_ns");
454 #endif
455         if (!ptr) {
456                 printk(KERN_ERR "Can't resolve find_task_by_pid_ns().\n");
457                 return NULL;
458         }
459         printk(KERN_INFO "find_task_by_pid_ns=%p\n", ptr);
460         return ptr;
461 }
462 
463 #endif
464 
465 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
466 
467 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
468 
469 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 3)
470 
471 /* Dummy variable for finding address of "spinlock_t vfsmount_lock". */
472 static spinlock_t probe_dummy_vfsmount_lock __cacheline_aligned_in_smp =
473         SPIN_LOCK_UNLOCKED;
474 
475 static struct list_head *probe_mount_hashtable;
476 static int probe_hash_mask, probe_hash_bits;
477 
478 /**
479  * hash - Copy of hash() in fs/namespace.c.
480  *
481  * @mnt: Pointer to "struct vfsmount".
482  * @dentry: Pointer to "struct dentry".
483  *
484  * Returns hash value.
485  */
486 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
487 {
488         unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
489         tmp += ((unsigned long) dentry / L1_CACHE_BYTES);
490         tmp = tmp + (tmp >> probe_hash_bits);
491         return tmp & probe_hash_mask;
492 }
493 
494 /**
495  * probe_lookup_mnt - Dummy function which does identical to lookup_mnt() in fs/namespace.c.
496  *
497  * @mnt:    Pointer to "struct vfsmount".
498  * @dentry: Pointer to "struct dentry".
499  *
500  * Returns pointer to "struct vfsmount".
501  */
502 static struct vfsmount *probe_lookup_mnt(struct vfsmount *mnt,
503                                          struct dentry *dentry)
504 {
505         struct list_head *head = probe_mount_hashtable + hash(mnt, dentry);
506         struct list_head *tmp = head;
507         struct vfsmount *p, *found = NULL;
508 
509         spin_lock(&probe_dummy_vfsmount_lock);
510         for (;;) {
511                 tmp = tmp->next;
512                 p = NULL;
513                 if (tmp == head)
514                         break;
515                 p = list_entry(tmp, struct vfsmount, mnt_hash);
516                 if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry) {
517                         found = mntget(p);
518                         break;
519                 }
520         }
521         spin_unlock(&probe_dummy_vfsmount_lock);
522         return found;
523 }
524 
525 /**
526  * probe_vfsmount_lock - Find address of "spinlock_t vfsmount_lock".
527  *
528  * Returns address of vfsmount_lock on success, NULL otherwise.
529  */
530 void * __init probe_vfsmount_lock(void)
531 {
532         void *cp;
533         spinlock_t *ptr;
534         /* Guess "spinlock_t vfsmount_lock;". */
535         cp = probe_find_variable(probe_lookup_mnt, (unsigned long)
536                                  &probe_dummy_vfsmount_lock, " lookup_mnt\n");
537         if (!cp) {
538                 printk(KERN_ERR "Can't resolve lookup_mnt().\n");
539                 return NULL;
540         }
541         /* This should be "spinlock_t *vfsmount_lock;". */
542         ptr = *(spinlock_t **) cp;
543         if (!ptr) {
544                 printk(KERN_ERR "Can't resolve vfsmount_lock .\n");
545                 return NULL;
546         }
547         printk(KERN_INFO "vfsmount_lock=%p\n", ptr);
548         return ptr;
549 }
550 
551 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
552 
553 /* Dummy variable for finding address of "spinlock_t vfsmount_lock". */
554 static spinlock_t probe_dummy_vfsmount_lock;
555 
556 /**
557  * probe_follow_up - Dummy function which does identical to follow_up() in fs/namei.c.
558  *
559  * @mnt:    Pointer to "struct vfsmount *".
560  * @dentry: Pointer to "struct dentry *".
561  *
562  * Returns 1 if followed up, 0 otehrwise.
563  */
564 static int probe_follow_up(struct vfsmount **mnt, struct dentry **dentry)
565 {
566         struct vfsmount *parent;
567         struct dentry *mountpoint;
568         spin_lock(&probe_dummy_vfsmount_lock);
569         parent = (*mnt)->mnt_parent;
570         if (parent == *mnt) {
571                 spin_unlock(&probe_dummy_vfsmount_lock);
572                 return 0;
573         }
574         mntget(parent);
575         mountpoint = dget((*mnt)->mnt_mountpoint);
576         spin_unlock(&probe_dummy_vfsmount_lock);
577         dput(*dentry);
578         *dentry = mountpoint;
579         mntput(*mnt);
580         *mnt = parent;
581         return 1;
582 }
583 
584 /**
585  * probe_vfsmount_lock - Find address of "spinlock_t vfsmount_lock".
586  *
587  * Returns address of vfsmount_lock on success, NULL otherwise.
588  */
589 void * __init probe_vfsmount_lock(void)
590 {
591         void *cp;
592         spinlock_t *ptr;
593         /* Guess "spinlock_t vfsmount_lock;". */
594         cp = probe_find_variable(probe_follow_up, (unsigned long)
595                                  &probe_dummy_vfsmount_lock, "follow_up");
596         if (!cp) {
597                 printk(KERN_ERR "Can't resolve follow_up().\n");
598                 return NULL;
599         }
600         /* This should be "spinlock_t *vfsmount_lock;". */
601         ptr = *(spinlock_t **) cp;
602         if (!ptr) {
603                 printk(KERN_ERR "Can't resolve vfsmount_lock .\n");
604                 return NULL;
605         }
606         printk(KERN_INFO "vfsmount_lock=%p\n", ptr);
607         return ptr;
608 }
609 
610 #else
611 
612 /* Dummy variable for finding address of "spinlock_t vfsmount_lock". */
613 static spinlock_t probe_dummy_vfsmount_lock;
614 
615 /**
616  * probe_mnt_pin - Dummy function which does identical to mnt_pin() in fs/namespace.c.
617  *
618  * @mnt: Pointer to "struct vfsmount".
619  *
620  * Returns nothing.
621  */
622 static void probe_mnt_pin(struct vfsmount *mnt)
623 {
624         spin_lock(&probe_dummy_vfsmount_lock);
625         mnt->mnt_pinned++;
626         spin_unlock(&probe_dummy_vfsmount_lock);
627 }
628 
629 /**
630  * probe_vfsmount_lock - Find address of "spinlock_t vfsmount_lock".
631  *
632  * Returns address of vfsmount_lock on success, NULL otherwise.
633  */
634 void * __init probe_vfsmount_lock(void)
635 {
636         void *cp;
637         spinlock_t *ptr;
638         /* Guess "spinlock_t vfsmount_lock;". */
639         cp = probe_find_variable(probe_mnt_pin, (unsigned long)
640                                  &probe_dummy_vfsmount_lock, "mnt_pin");
641         if (!cp) {
642                 printk(KERN_ERR "Can't resolve mnt_pin().\n");
643                 return NULL;
644         }
645         /* This should be "spinlock_t *vfsmount_lock;". */
646         ptr = *(spinlock_t **) cp;
647         if (!ptr) {
648                 printk(KERN_ERR "Can't resolve vfsmount_lock .\n");
649                 return NULL;
650         }
651         printk(KERN_INFO "vfsmount_lock=%p\n", ptr);
652         return ptr;
653 }
654 
655 #endif
656 
657 #else
658 
659 /*
660  * Never mark this variable as __initdata , for this variable might be accessed
661  * by caller of probe_find_vfsmount_lock().
662  */
663 static spinlock_t probe_dummy_vfsmount_lock;
664 
665 /**
666  * probe_vfsmount_lock - Find address of "spinlock_t vfsmount_lock".
667  *
668  * Returns address of vfsmount_lock.
669  */
670 void * __init probe_vfsmount_lock(void)
671 {
672         return &probe_dummy_vfsmount_lock;
673 }
674 
675 #endif
676 
677 #endif
678 
679 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
680 
681 /**
682  * probe___d_path - Find address of "__d_path()".
683  *
684  * Returns address of __d_path() on success, NULL otherwise.
685  */
686 void * __init probe___d_path(void)
687 {
688         void *ptr = probe_find_symbol(" __d_path\n");
689         if (!ptr) {
690                 printk(KERN_ERR "Can't resolve __d_path().\n");
691                 return NULL;
692         }
693         printk(KERN_INFO "__d_path=%p\n", ptr);
694         return ptr;
695 }
696 
697 #endif
698 
699 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
700 
701 /**
702  * probe_d_absolute_path - Find address of "d_absolute_path()".
703  *
704  * Returns address of d_absolute_path() on success, NULL otherwise.
705  */
706 void * __init probe_d_absolute_path(void)
707 {
708         void *ptr = probe_find_symbol(" d_absolute_path\n");
709         if (!ptr) {
710                 printk(KERN_ERR "Can't resolve d_absolute_path().\n");
711                 return NULL;
712         }
713         printk(KERN_INFO "d_absolute_path=%p\n", ptr);
714         return ptr;
715 }
716 
717 #endif
718 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp