We didn't pick this up automatically because its fixes tag is for when
ptrace rules landed upstream. But ubuntu was carrying ptrace rules prior
to this

-- 
You received this bug notification because you are a member of Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/1890848

Title:
  'ptrace trace' needed to readlink() /proc/*/ns/* files on older
  kernels

Status in linux package in Ubuntu:
  Fix Released
Status in linux source package in Xenial:
  Confirmed
Status in linux source package in Bionic:
  Confirmed

Bug description:
  Per 'man namespaces':

  "Permission to dereference or read (readlink(2)) these symbolic links is
  governed by a ptrace access mode PTRACE_MODE_READ_FSCREDS check; see
  ptrace(2)."

  This suggests that a 'ptrace read' rule should be sufficient to
  readlink() /proc/*/ns/*, which is the case with 5.4.0-42.46-generic
  (Ubuntu 20.04 LTS).

  However, on Ubuntu 18.04 LTS and 16.04 LTS, 'ptrace trace' is needed.
  Here is a reproducer:

  $ cat ./readlink-ns.c
  #include <errno.h>
  #include <linux/limits.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/types.h>
  #include <unistd.h>

  void usage() {
        fprintf(stderr, "Usage: readlink-ns -p <pid> -n <ns>\n");
  }

  int main(int argc, char *argv[])
  {
        pid_t pid = 0;
        char *ns = NULL;
        char path[PATH_MAX] = {};
        char rpath[PATH_MAX] = {};
        int c;

        while ((c = getopt(argc, argv, "hn:p:")) != -1) {
                switch(c) {
                        case 'n':
                                ns = optarg;
                                break;
                        case 'p':
                                pid = atoi(optarg);
                                break;
                        case 'h':
                                usage();
                                return 0;
                        case '?':
                                usage();
                                return 1;
                        default:
                                return 1;
                }
        }

        int n = snprintf(path, sizeof(path), "/proc/%d/ns/%s", pid, ns);
        if (n < 0 || (size_t)n >= sizeof(path)) {
                fprintf(stderr, "cannot format string\n");
                return 1;
        }
        path[n] = '\0';
        printf("path:  %s\n", path);

        n = readlink(path, rpath, sizeof(rpath));
        if (n < 0) {
                perror("readlink()");
                return 1;
        } else if (n == sizeof(rpath)) {
                fprintf(stderr, "cannot readlink()\n");
                return 1;
        }
        printf("rpath: %s\n", rpath);

        return 0;
  }

  $ cat ./readlink-ns.apparmor
  #include <tunables/global>

  profile test {
    #include <abstractions/base>

    # focal
    ptrace (read) peer="unconfined",

    # xenial, bionic
    #ptrace (trace) peer="unconfined",
  }

  
  # bionic and xenial need 'ptrace trace'
  $ gcc ./readlink-ns.c && sudo apparmor_parser -r ./readlink-ns.apparmor && 
sudo aa-exec -p test -- ./a.out -p 1 -n pid
  path:  /proc/1/ns/pid
  readlink(): Permission denied

  Denial:
  Aug 07 14:40:59 sec-bionic-amd64 kernel: audit: type=1400 
audit(1596829259.675:872): apparmor="DENIED" operation="ptrace" profile="test" 
pid=1311 comm="a.out" requested_mask="trace" denied_mask="trace" 
peer="unconfined"

  
  # focal needs only 'ptrace read'
  $ gcc ./readlink-ns.c && sudo apparmor_parser -r ./readlink-ns.apparmor && 
sudo aa-exec -p test -- ./a.out -p 1 -n pid
  path:  /proc/1/ns/pid
  rpath: pid:[4026531836]

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1890848/+subscriptions

-- 
Mailing list: https://launchpad.net/~kernel-packages
Post to     : kernel-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~kernel-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to