1

getdirentries (および lstat など) の libc システムコールをオーバーライドしたいと考えています。たとえば、lstat と chmod をオーバーライドすることはできますが、getdirentries (および特に fstatfs) をオーバーライドすることはできません。

コード例は次のとおりです。

    #include <errno.h>
    #include <dlfcn.h>
    #include <stdio.h>
    #include <strings.h>
    #include <string.h>
    #include <sys/_timespec.h>
    #include <sys/stat.h>
    #include <sys/mount.h>

    #ifndef RTLD_NEXT
    #define RTLD_NEXT   ((void *) -1l)
    #endif

    int (*getdirentries_orig)(int fd, char *buf, int nbytes, long *basep);
    int (*lstat_orig)(const char *path, struct stat *sb);
    int (*fstatfs_orig)(int fd, struct statfs *buf);
    int (*chmod_orig)(const char *path, mode_t mode);

    #define HOOK(func) func##_##orig = dlsym(RTLD_NEXT,#func)

    int getdirentries(int fd, char *buf, int nbytes, long *basep) {
        HOOK(getdirentries);
        printf("getdirentries\n");
        return getdirentries_orig(fd, buf, nbytes, basep);
    }

    int lstat(const char *path, struct stat *sb) {
        HOOK(lstat);
        printf("lstat\n");
        return (lstat_orig(path, sb));
    }

    int fstatfs(int fd, struct statfs *buf) {
        HOOK(fstatfs);
        printf("fstatfs\n");
        return fstatfs_orig(fd, buf);
    }

    int chmod(const char *path, mode_t mode) {
        HOOK(chmod);
        printf("chmod\n");
        return chmod_orig(path, mode);
    }

これを FreeBSD で次のようにコンパイルします。

cc -Wall -g -O2 -fPIC -shared -o preload.so preload.c

(Linux では、-ldl の追加が必要になる場合があります) LD_PRELOAD=./preload.so bash で使用します。

次に ls -l を発行すると、「lstat」が複数回出力されますが、これで問題ありません。しかし、ls は ktrace によると複数の getdirentries も呼び出し、そのオーバーライド関数は呼び出されません。fstatfs も機能しません。

getdirentries、fstatfs、およびおそらく他のシステムコールをオーバーライドするにはどうすればよいですか? また、この場合、それらが機能しないのはなぜですか?

ありがとう、

4

1 に答える 1

0

結局のところ、libc/readdir.c の readdir() (readdir は ls が呼び出すものであり、getdirentries を呼び出す必要があります) は、getdirentries ではなく _getdirentries を呼び出します。_getdirentries をオーバーライドすると、機能します。fstatfs についても同じなので、これが私のプログラムが機能しなかった理由です。

于 2014-11-27T08:44:07.330 に答える