diff options
| author | John Johansen <john.johansen@canonical.com> | 2014-07-25 07:02:10 -0400 |
|---|---|---|
| committer | John Johansen <john.johansen@canonical.com> | 2016-07-12 11:43:10 -0400 |
| commit | bd35db8b8ca6e27fc17a9057ef78e1ddfc0de351 (patch) | |
| tree | 08f18c58688ca936e41f9963e820d42d7e029bcd | |
| parent | f2e561d190da7ff5ee265fa460e2d7f753dddfda (diff) | |
apparmor: internal paths should be treated as disconnected
Internal mounts are not mounted anywhere and as such should be treated
as disconnected paths.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
| -rw-r--r-- | security/apparmor/path.c | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/security/apparmor/path.c b/security/apparmor/path.c index f2616780065a..a8fc7d08c144 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | #include "include/path.h" | 25 | #include "include/path.h" |
| 26 | #include "include/policy.h" | 26 | #include "include/policy.h" |
| 27 | 27 | ||
| 28 | |||
| 29 | /* modified from dcache.c */ | 28 | /* modified from dcache.c */ |
| 30 | static int prepend(char **buffer, int buflen, const char *str, int namelen) | 29 | static int prepend(char **buffer, int buflen, const char *str, int namelen) |
| 31 | { | 30 | { |
| @@ -39,6 +38,38 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen) | |||
| 39 | 38 | ||
| 40 | #define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT) | 39 | #define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT) |
| 41 | 40 | ||
| 41 | /* If the path is not connected to the expected root, | ||
| 42 | * check if it is a sysctl and handle specially else remove any | ||
| 43 | * leading / that __d_path may have returned. | ||
| 44 | * Unless | ||
| 45 | * specifically directed to connect the path, | ||
| 46 | * OR | ||
| 47 | * if in a chroot and doing chroot relative paths and the path | ||
| 48 | * resolves to the namespace root (would be connected outside | ||
| 49 | * of chroot) and specifically directed to connect paths to | ||
| 50 | * namespace root. | ||
| 51 | */ | ||
| 52 | static int disconnect(const struct path *path, char *buf, char **name, | ||
| 53 | int flags) | ||
| 54 | { | ||
| 55 | int error = 0; | ||
| 56 | |||
| 57 | if (!(flags & PATH_CONNECT_PATH) && | ||
| 58 | !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) && | ||
| 59 | our_mnt(path->mnt))) { | ||
| 60 | /* disconnected path, don't return pathname starting | ||
| 61 | * with '/' | ||
| 62 | */ | ||
| 63 | error = -EACCES; | ||
| 64 | if (**name == '/') | ||
| 65 | *name = *name + 1; | ||
| 66 | } else if (**name != '/') | ||
| 67 | /* CONNECT_PATH with missing root */ | ||
| 68 | error = prepend(name, *name - buf, "/", 1); | ||
| 69 | |||
| 70 | return error; | ||
| 71 | } | ||
| 72 | |||
| 42 | /** | 73 | /** |
| 43 | * d_namespace_path - lookup a name associated with a given path | 74 | * d_namespace_path - lookup a name associated with a given path |
| 44 | * @path: path to lookup (NOT NULL) | 75 | * @path: path to lookup (NOT NULL) |
| @@ -74,7 +105,8 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen, | |||
| 74 | * control instead of hard coded /proc | 105 | * control instead of hard coded /proc |
| 75 | */ | 106 | */ |
| 76 | return prepend(name, *name - buf, "/proc", 5); | 107 | return prepend(name, *name - buf, "/proc", 5); |
| 77 | } | 108 | } else |
| 109 | return disconnect(path, buf, name, flags); | ||
| 78 | return 0; | 110 | return 0; |
| 79 | } | 111 | } |
| 80 | 112 | ||
| @@ -120,32 +152,8 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen, | |||
| 120 | goto out; | 152 | goto out; |
| 121 | } | 153 | } |
| 122 | 154 | ||
| 123 | /* If the path is not connected to the expected root, | 155 | if (!connected) |
| 124 | * check if it is a sysctl and handle specially else remove any | 156 | error = disconnect(path, buf, name, flags); |
| 125 | * leading / that __d_path may have returned. | ||
| 126 | * Unless | ||
| 127 | * specifically directed to connect the path, | ||
| 128 | * OR | ||
| 129 | * if in a chroot and doing chroot relative paths and the path | ||
| 130 | * resolves to the namespace root (would be connected outside | ||
| 131 | * of chroot) and specifically directed to connect paths to | ||
| 132 | * namespace root. | ||
| 133 | */ | ||
| 134 | if (!connected) { | ||
| 135 | if (!(flags & PATH_CONNECT_PATH) && | ||
| 136 | !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) && | ||
| 137 | our_mnt(path->mnt))) { | ||
| 138 | /* disconnected path, don't return pathname starting | ||
| 139 | * with '/' | ||
| 140 | */ | ||
| 141 | error = -EACCES; | ||
| 142 | if (*res == '/') | ||
| 143 | *name = res + 1; | ||
| 144 | } else if (*res != '/') | ||
| 145 | /* CONNECT_PATH with missing root */ | ||
| 146 | error = prepend(name, *name - buf, "/", 1); | ||
| 147 | |||
| 148 | } | ||
| 149 | 157 | ||
| 150 | out: | 158 | out: |
| 151 | return error; | 159 | return error; |
