Landlock and O_PATH

"S.M Mukarram Nainar" <[email protected]> Mon, 21 Feb 2022 15:16:08 -0500
Newsgroups dev.linux.lists.landlock
Message-ID <87v8x83rhz.fsf@bentou.i-did-not-set--mail-host-address--so-tickle-me>
Hi! First I want to say that I'm happy landlock exists, its featureset
was dearly missed for a while, so thanks for that.

I was recently experimenting with Landlock to see how it works, and I
had a question.

Following the example, I locked the program down as follows:

```c
  struct landlock_ruleset_attr ruleset_attr = {
    .handled_access_fs =
    /* Files */
    LANDLOCK_ACCESS_FS_EXECUTE |
    LANDLOCK_ACCESS_FS_WRITE_FILE |
    LANDLOCK_ACCESS_FS_READ_FILE |

    /* the directory */
    LANDLOCK_ACCESS_FS_READ_DIR |

    /* inside the directory */
    LANDLOCK_ACCESS_FS_REMOVE_DIR |
    LANDLOCK_ACCESS_FS_REMOVE_FILE |
    LANDLOCK_ACCESS_FS_MAKE_CHAR |
    LANDLOCK_ACCESS_FS_MAKE_DIR |
    LANDLOCK_ACCESS_FS_MAKE_REG |
    LANDLOCK_ACCESS_FS_MAKE_SOCK |
    LANDLOCK_ACCESS_FS_MAKE_FIFO |
    LANDLOCK_ACCESS_FS_MAKE_BLOCK |
    LANDLOCK_ACCESS_FS_MAKE_SYM,
  };
  int ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
  if (ruleset_fd < 0) {
    perror("no");
    return 1;
  }
  if ((prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))) {
    perror("prctl error");
    close(ruleset_fd);
    return 1;
  }
  if (landlock_restrict_self(ruleset_fd, 0) != 0) {
    perror("can't do it");
    close(ruleset_fd);
    return 1;
  }
  int fd_dir = open("/home/asdasda/", O_PATH);
  if (fd_dir < 0) {
    perror("open dir fail");
  }
```

However, open(2) with O_PATH still works. For example:

```c
  int fd_dir = open("/home/asdasda/", O_PATH);
  if (fd_dir < 0) {
    perror("open dir fail");
  }
```
This does not fail, and can basically be used as a directory oracle. Is
  this the desired behaviour? I found it surprising and expected
  FS_READ_DIR to block this as well.

Thanks,
Mukarram