On 01/11/20, Matthew Wilcox wrote: > On Sun, Nov 01, 2020 at 10:27:38PM +0100, Paweł Jasiak wrote: > > I am trying to run examples from man fanotify.7 but fanotify_mark always > > fail with errno = EFAULT. > > > > fanotify_mark declaration is > > > > SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags, > > __u64, mask, int, dfd, > > const char __user *, pathname) > > Don't worry about that. You aren't calling the SYSCALL, you're calling > glibc and glibc is turning it into a syscall. > > extern int fanotify_mark (int __fanotify_fd, unsigned int __flags, > uint64_t __mask, int __dfd, const char *__pathname) > > > When > > > > fanotify_mark(4, FAN_MARK_ADD | FAN_MARK_ONLYDIR, > > FAN_CREATE | FAN_ONDIR, AT_FDCWD, 0xdeadc0de) > > The last argument is supposed to be a pointer to a string. I'm guessing > there's no string at 0xdeadc0de. You are right but it's not a problem. 0xdeadc0de is just a _well known_ address here only for debug purpose. pathname inside kernel should be a pointer to string located in user space at 0xdeadc0de but it is equal to 0xffffff9c which is AT_FDCWD. If you call fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_ONLYDIR, FAN_CREATE | FAN_ONDIR, AT_FDCWD, argv[1]); from example with *valid* pointer at argv[1] you still get EFAULT because pathname is equal to AT_FDCWD in kernel space -- last argument is not used. In my example in user space we have fanotify_fd = 4 flags = 0x9 mask = 0x40000100 dfd = 0xffffff9c pathname = 0xdeadc0de and in kernel space we have fanotify_fd = 4 flags = 0x9 mask = 0x40000100 dfd = 0 pathname = 0xffffff9c So all arguments after __u64 mask are shifted by one. It looks similar to https://lists.linux.it/pipermail/ltp/2020-June/017436.html -- Paweł Jasiak
Attachment:
signature.asc
Description: PGP signature