diff options
Diffstat (limited to 'security/tomoyo/realpath.c')
-rw-r--r-- | security/tomoyo/realpath.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 6ff8c21e4fff..85e6e31dd1e5 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
@@ -94,11 +94,13 @@ static char *tomoyo_get_absolute_path(const struct path *path, char * const buff | |||
94 | const int buflen) | 94 | const int buflen) |
95 | { | 95 | { |
96 | char *pos = ERR_PTR(-ENOMEM); | 96 | char *pos = ERR_PTR(-ENOMEM); |
97 | |||
97 | if (buflen >= 256) { | 98 | if (buflen >= 256) { |
98 | /* go to whatever namespace root we are under */ | 99 | /* go to whatever namespace root we are under */ |
99 | pos = d_absolute_path(path, buffer, buflen - 1); | 100 | pos = d_absolute_path(path, buffer, buflen - 1); |
100 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { | 101 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { |
101 | struct inode *inode = d_backing_inode(path->dentry); | 102 | struct inode *inode = d_backing_inode(path->dentry); |
103 | |||
102 | if (inode && S_ISDIR(inode->i_mode)) { | 104 | if (inode && S_ISDIR(inode->i_mode)) { |
103 | buffer[buflen - 2] = '/'; | 105 | buffer[buflen - 2] = '/'; |
104 | buffer[buflen - 1] = '\0'; | 106 | buffer[buflen - 1] = '\0'; |
@@ -123,10 +125,12 @@ static char *tomoyo_get_dentry_path(struct dentry *dentry, char * const buffer, | |||
123 | const int buflen) | 125 | const int buflen) |
124 | { | 126 | { |
125 | char *pos = ERR_PTR(-ENOMEM); | 127 | char *pos = ERR_PTR(-ENOMEM); |
128 | |||
126 | if (buflen >= 256) { | 129 | if (buflen >= 256) { |
127 | pos = dentry_path_raw(dentry, buffer, buflen - 1); | 130 | pos = dentry_path_raw(dentry, buffer, buflen - 1); |
128 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { | 131 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { |
129 | struct inode *inode = d_backing_inode(dentry); | 132 | struct inode *inode = d_backing_inode(dentry); |
133 | |||
130 | if (inode && S_ISDIR(inode->i_mode)) { | 134 | if (inode && S_ISDIR(inode->i_mode)) { |
131 | buffer[buflen - 2] = '/'; | 135 | buffer[buflen - 2] = '/'; |
132 | buffer[buflen - 1] = '\0'; | 136 | buffer[buflen - 1] = '\0'; |
@@ -150,12 +154,14 @@ static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer, | |||
150 | { | 154 | { |
151 | struct super_block *sb = dentry->d_sb; | 155 | struct super_block *sb = dentry->d_sb; |
152 | char *pos = tomoyo_get_dentry_path(dentry, buffer, buflen); | 156 | char *pos = tomoyo_get_dentry_path(dentry, buffer, buflen); |
157 | |||
153 | if (IS_ERR(pos)) | 158 | if (IS_ERR(pos)) |
154 | return pos; | 159 | return pos; |
155 | /* Convert from $PID to self if $PID is current thread. */ | 160 | /* Convert from $PID to self if $PID is current thread. */ |
156 | if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') { | 161 | if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') { |
157 | char *ep; | 162 | char *ep; |
158 | const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10); | 163 | const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10); |
164 | |||
159 | if (*ep == '/' && pid && pid == | 165 | if (*ep == '/' && pid && pid == |
160 | task_tgid_nr_ns(current, sb->s_fs_info)) { | 166 | task_tgid_nr_ns(current, sb->s_fs_info)) { |
161 | pos = ep - 5; | 167 | pos = ep - 5; |
@@ -170,6 +176,7 @@ static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer, | |||
170 | goto prepend_filesystem_name; | 176 | goto prepend_filesystem_name; |
171 | { | 177 | { |
172 | struct inode *inode = d_backing_inode(sb->s_root); | 178 | struct inode *inode = d_backing_inode(sb->s_root); |
179 | |||
173 | /* | 180 | /* |
174 | * Use filesystem name if filesystem does not support rename() | 181 | * Use filesystem name if filesystem does not support rename() |
175 | * operation. | 182 | * operation. |
@@ -182,6 +189,7 @@ static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer, | |||
182 | char name[64]; | 189 | char name[64]; |
183 | int name_len; | 190 | int name_len; |
184 | const dev_t dev = sb->s_dev; | 191 | const dev_t dev = sb->s_dev; |
192 | |||
185 | name[sizeof(name) - 1] = '\0'; | 193 | name[sizeof(name) - 1] = '\0'; |
186 | snprintf(name, sizeof(name) - 1, "dev(%u,%u):", MAJOR(dev), | 194 | snprintf(name, sizeof(name) - 1, "dev(%u,%u):", MAJOR(dev), |
187 | MINOR(dev)); | 195 | MINOR(dev)); |
@@ -197,6 +205,7 @@ prepend_filesystem_name: | |||
197 | { | 205 | { |
198 | const char *name = sb->s_type->name; | 206 | const char *name = sb->s_type->name; |
199 | const int name_len = strlen(name); | 207 | const int name_len = strlen(name); |
208 | |||
200 | pos -= name_len + 1; | 209 | pos -= name_len + 1; |
201 | if (pos < buffer) | 210 | if (pos < buffer) |
202 | goto out; | 211 | goto out; |
@@ -223,10 +232,10 @@ static char *tomoyo_get_socket_name(const struct path *path, char * const buffer | |||
223 | struct inode *inode = d_backing_inode(path->dentry); | 232 | struct inode *inode = d_backing_inode(path->dentry); |
224 | struct socket *sock = inode ? SOCKET_I(inode) : NULL; | 233 | struct socket *sock = inode ? SOCKET_I(inode) : NULL; |
225 | struct sock *sk = sock ? sock->sk : NULL; | 234 | struct sock *sk = sock ? sock->sk : NULL; |
235 | |||
226 | if (sk) { | 236 | if (sk) { |
227 | snprintf(buffer, buflen, "socket:[family=%u:type=%u:" | 237 | snprintf(buffer, buflen, "socket:[family=%u:type=%u:protocol=%u]", |
228 | "protocol=%u]", sk->sk_family, sk->sk_type, | 238 | sk->sk_family, sk->sk_type, sk->sk_protocol); |
229 | sk->sk_protocol); | ||
230 | } else { | 239 | } else { |
231 | snprintf(buffer, buflen, "socket:[unknown]"); | 240 | snprintf(buffer, buflen, "socket:[unknown]"); |
232 | } | 241 | } |
@@ -255,12 +264,14 @@ char *tomoyo_realpath_from_path(const struct path *path) | |||
255 | unsigned int buf_len = PAGE_SIZE / 2; | 264 | unsigned int buf_len = PAGE_SIZE / 2; |
256 | struct dentry *dentry = path->dentry; | 265 | struct dentry *dentry = path->dentry; |
257 | struct super_block *sb; | 266 | struct super_block *sb; |
267 | |||
258 | if (!dentry) | 268 | if (!dentry) |
259 | return NULL; | 269 | return NULL; |
260 | sb = dentry->d_sb; | 270 | sb = dentry->d_sb; |
261 | while (1) { | 271 | while (1) { |
262 | char *pos; | 272 | char *pos; |
263 | struct inode *inode; | 273 | struct inode *inode; |
274 | |||
264 | buf_len <<= 1; | 275 | buf_len <<= 1; |
265 | kfree(buf); | 276 | kfree(buf); |
266 | buf = kmalloc(buf_len, GFP_NOFS); | 277 | buf = kmalloc(buf_len, GFP_NOFS); |
@@ -323,6 +334,7 @@ char *tomoyo_realpath_nofollow(const char *pathname) | |||
323 | 334 | ||
324 | if (pathname && kern_path(pathname, 0, &path) == 0) { | 335 | if (pathname && kern_path(pathname, 0, &path) == 0) { |
325 | char *buf = tomoyo_realpath_from_path(&path); | 336 | char *buf = tomoyo_realpath_from_path(&path); |
337 | |||
326 | path_put(&path); | 338 | path_put(&path); |
327 | return buf; | 339 | return buf; |
328 | } | 340 | } |