[英]fstat() does not work as expected inside a preloaded mmap() system call
I am trying to get the device minor and major numbers from fstat()
. 我正在尝试从fstat()
获得设备的次要和主要数字。 The call to fstat()
is done inside a preloaded mmap()
system call: 对fstat()
的调用是在预加载的mmap()
系统调用中完成的:
// preload.so
// compile with:
// gcc -ldl -Wall -shared -fPIC -o preload.so -D_GNU_SOURCE preload.c
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#if __GNUC__ >= 4
#define PUBLIC __attribute__ ((visibility("default")))
#else
#define PUBLIC
#endif
PUBLIC void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) {
printf("preload\n");
struct stat sb;
if (fstat(fd, &sb) == -1)
printf("fstat() failed\n");
else
printf("%u %u\n", major(sb.st_rdev), minor(sb.st_rdev));
typedef void*(*mmap_t)(void *, size_t, int, int, int, off_t);
mmap_t o_mmap = dlsym(RTLD_NEXT, "mmap");
return (*o_mmap)(start, length, prot, flags, fd, offset);
}
The above library can then intercept any mmap() system call from any given program: 然后,上述库可以拦截来自任何给定程序的任何mmap()系统调用:
$ LD_PRELOAD=./preload.so ./my_prog
Why do I keep obtaining 0 and 0 as major and minor number, although my_prog
attempts to mmap()
a device after opening a real device node? 尽管my_prog
在打开实际设备节点后尝试对设备进行mmap()
,但为什么我仍继续获得0和0作为主设备号和次设备号?
Is there any way to obtain the major and minor numbers from within the preloaded mmap() system call without any other informations except the arguments passed to the function itself? 有什么方法可以从预加载的mmap()系统调用中获取主号和副号,而无需传递任何其他信息(传递给函数本身的参数除外)?
mmap() will be called by a lot of other code as well, eg mmap()也将被许多其他代码调用,例如
In the first case, the mmap()'ed file is just a regular file, and will have have a minor/major of 0. In the second case, the fd passed in is not a valid fd - the app should pass -1 as the fd, but it might not.. 在第一种情况下,mmap()编辑的文件只是常规文件,次要/主要为0。在第二种情况下,传入的fd不是有效的fd-应用程序应通过-1作为fd,但事实并非如此。
You're likely seeing these mmap() calls from the runtime and indirectly from other library calls your application does, not just the mmap() call of a device that your app does. 您可能会在运行时看到这些mmap()调用,而在应用程序中间接看到其他库调用,而不仅仅是应用程序所执行的设备的mmap()调用。
On eg Linux/glibc, and possibly other systems as well, I'd presume an mmap()
call could be compiled to call mmap64()
instead, depending on compiler flags that's used to enable large file support. 在例如Linux / glibc以及可能的其他系统上,我假设可以编译mmap()
调用来代替调用mmap64()
,具体取决于用于启用大文件支持的编译器标志。 You might need to intercept mmap64()
as well as mmap()
您可能需要拦截mmap64()
和mmap()
It's unclear what you're really trying to do, but you could 目前尚不清楚您真正要做什么,但是您可以
struct stat
.st_mode for S_ISCHR() or S_ISBLK() (see the stat man page) to know if mmap() was for a device file 检查S_ISCHR()或S_ISBLK()的struct stat
.st_mode(请参阅stat手册页)以了解mmap()是否用于设备文件 sb.st_rdev
is for the major/minor number your interested in, take action. 如果sb.st_rdev
是您感兴趣的主要/次要号码,请采取措施。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.