0

I want to get the current directory, here is my attempt

asmlinkage ssize_t fake_read(int __fd, void *__buf, size_t __nbytes){

    struct path pwd;
    get_fs_pwd(current->fs,&pwd);
    char x[1000];
    dentry_path_raw(pwd.dentry,x,999);
    fm_alert("read:%s\n",x);
    return real_read(__fd,__buf,__nbytes);
}

However, the output I get is like

[ 2170.293439] fsmonko.fake_read: read:ػ\xffffffaf\xffffff80
[ 2170.293466] fsmonko.fake_read: read:ػ\xffffffaf\xffffff80
[ 2170.293483] fsmonko.fake_read: read:\xffffffd8;\xffffff9b\xffffff84
[ 2170.293500] fsmonko.fake_read: read:ػ\xffffffaf\xffffff80
[ 2170.293524] fsmonko.fake_read: read:ػ\xffffffaf\xffffff80
[ 2170.293550] fsmonko.fake_read: read:ػ\xffffffaf\xffffff80
[ 2170.293556] fsmonko.fake_read: read:\xffffffd8;\xffffff9b\xffffff84

It's supposed to print the readable pwd, what's wrong?

My kernel version is 4.13.0-36-generic Ubuntu 16.04.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
user6456568
  • 579
  • 9
  • 23
  • You really want to avoid putting in magical constants like `1000` and `999` and instead use some kind of kernel-defined "max length" constant instead like `PATH_MAX`. – tadman Oct 22 '18 at 16:07
  • @tadman thanks, but the output is still the same – user6456568 Oct 22 '18 at 16:10
  • That doesn't fix your problem, but it'll avoid a kernel explosion when you hit a path that's too long for your buffer but allowed by Linux. – tadman Oct 22 '18 at 16:12
  • 1
    Maybe check return value? `char *p = dentry_path_raw(..); if (IS_ERR(p)) printk("It failed; errno %ld\n", -PTR_ERR(p));` – Gil Hamilton Oct 22 '18 at 16:13
  • Is your question related [to this question](https://stackoverflow.com/questions/15405842/current-directory-of-a-process-in-linux-kernel)? – tadman Oct 22 '18 at 16:13
  • @GilHamilton I've changed to `char *p = dentry_path_raw(pwd.dentry,x,PATH_MAX-1); if (IS_ERR(p)) fm_alert("It failed; errno %ld\n",-PTR_ERR(p)); else fm_alert("read:%s\n",x);` . But it seems no error and the output is the same. – user6456568 Oct 22 '18 at 16:20

1 Answers1

1

dentry_path_raw places the path at the end of the buffer. The beginning of the buffer (which you are printing) still contains garbage. An actual start of the path is the value dentry_path_raw returns. Try

    char * path = dentry_path_raw(pwd.dentry,x,999);
    fm_alert("read:%s\n", path);
user58697
  • 7,808
  • 1
  • 14
  • 28
  • Thanks, this actually works. But I'm still confused about the connection between the length of `buffer` and `buflen` in `path = dentry_path_raw(dentry, buffer, buflen);` – user6456568 Oct 23 '18 at 03:14
  • @user6456568 The `buflen` parameter tells `dentry_path_raw` how much memory it has to its disposal. Unless you have something weird in mind, just pass the actual size of the `buffer`. – user58697 Oct 23 '18 at 03:36