Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

AppArmor: Move path failure information into aa_get_name and rename

Move the path name lookup failure messages into the main path name lookup
routine, as the information is useful in more than just aa_path_perm.

Also rename aa_get_name to aa_path_name as it is not getting a reference
counted object with a corresponding put fn.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Kees Cook <kees@ubuntu.com>

+29 -19
+2 -3
security/apparmor/domain.c
··· 372 372 state = profile->file.start; 373 373 374 374 /* buffer freed below, name is pointer into buffer */ 375 - error = aa_get_name(&bprm->file->f_path, profile->path_flags, &buffer, 376 - &name); 375 + error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer, 376 + &name, &info); 377 377 if (error) { 378 378 if (profile->flags & 379 379 (PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED)) 380 380 error = 0; 381 - info = "Exec failed name resolution"; 382 381 name = bprm->filename; 383 382 goto audit; 384 383 }
+7 -11
security/apparmor/file.c
··· 278 278 int error; 279 279 280 280 flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0); 281 - error = aa_get_name(path, flags, &buffer, &name); 281 + error = aa_path_name(path, flags, &buffer, &name, &info); 282 282 if (error) { 283 283 if (error == -ENOENT && is_deleted(path->dentry)) { 284 284 /* Access to open files that are deleted are 285 285 * give a pass (implicit delegation) 286 286 */ 287 287 error = 0; 288 + info = NULL; 288 289 perms.allow = request; 289 - } else if (error == -ENOENT) 290 - info = "Failed name lookup - deleted entry"; 291 - else if (error == -ESTALE) 292 - info = "Failed name lookup - disconnected path"; 293 - else if (error == -ENAMETOOLONG) 294 - info = "Failed name lookup - name too long"; 295 - else 296 - info = "Failed name lookup"; 290 + } 297 291 } else { 298 292 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, 299 293 &perms); ··· 358 364 lperms = nullperms; 359 365 360 366 /* buffer freed below, lname is pointer in buffer */ 361 - error = aa_get_name(&link, profile->path_flags, &buffer, &lname); 367 + error = aa_path_name(&link, profile->path_flags, &buffer, &lname, 368 + &info); 362 369 if (error) 363 370 goto audit; 364 371 365 372 /* buffer2 freed below, tname is pointer in buffer2 */ 366 - error = aa_get_name(&target, profile->path_flags, &buffer2, &tname); 373 + error = aa_path_name(&target, profile->path_flags, &buffer2, &tname, 374 + &info); 367 375 if (error) 368 376 goto audit; 369 377
+2 -1
security/apparmor/include/path.h
··· 26 26 PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */ 27 27 }; 28 28 29 - int aa_get_name(struct path *path, int flags, char **buffer, const char **name); 29 + int aa_path_name(struct path *path, int flags, char **buffer, 30 + const char **name, const char **info); 30 31 31 32 #endif /* __AA_PATH_H */
+18 -4
security/apparmor/path.c
··· 157 157 * Returns: %0 else error on failure 158 158 */ 159 159 static int get_name_to_buffer(struct path *path, int flags, char *buffer, 160 - int size, char **name) 160 + int size, char **name, const char **info) 161 161 { 162 162 int adjust = (flags & PATH_IS_DIR) ? 1 : 0; 163 163 int error = d_namespace_path(path, buffer, size - adjust, name, flags); ··· 169 169 */ 170 170 strcpy(&buffer[size - 2], "/"); 171 171 172 + if (info && error) { 173 + if (error == -ENOENT) 174 + *info = "Failed name lookup - deleted entry"; 175 + else if (error == -ESTALE) 176 + *info = "Failed name lookup - disconnected path"; 177 + else if (error == -ENAMETOOLONG) 178 + *info = "Failed name lookup - name too long"; 179 + else 180 + *info = "Failed name lookup"; 181 + } 182 + 172 183 return error; 173 184 } 174 185 175 186 /** 176 - * aa_get_name - compute the pathname of a file 187 + * aa_path_name - compute the pathname of a file 177 188 * @path: path the file (NOT NULL) 178 189 * @flags: flags controlling path name generation 179 190 * @buffer: buffer that aa_get_name() allocated (NOT NULL) 180 191 * @name: Returns - the generated path name if !error (NOT NULL) 192 + * @info: Returns - information on why the path lookup failed (MAYBE NULL) 181 193 * 182 194 * @name is a pointer to the beginning of the pathname (which usually differs 183 195 * from the beginning of the buffer), or NULL. If there is an error @name ··· 202 190 * 203 191 * Returns: %0 else error code if could retrieve name 204 192 */ 205 - int aa_get_name(struct path *path, int flags, char **buffer, const char **name) 193 + int aa_path_name(struct path *path, int flags, char **buffer, const char **name, 194 + const char **info) 206 195 { 207 196 char *buf, *str = NULL; 208 197 int size = 256; ··· 217 204 if (!buf) 218 205 return -ENOMEM; 219 206 220 - error = get_name_to_buffer(path, flags, buf, size, &str); 207 + error = get_name_to_buffer(path, flags, buf, size, &str, info); 221 208 if (error != -ENAMETOOLONG) 222 209 break; 223 210 ··· 225 212 size <<= 1; 226 213 if (size > aa_g_path_max) 227 214 return -ENAMETOOLONG; 215 + *info = NULL; 228 216 } 229 217 *buffer = buf; 230 218 *name = str;