aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-05-16 16:25:46 -0400
committerDavid Howells <dhowells@redhat.com>2018-05-16 16:35:23 -0400
commit378831e4daec75fbba6d3612bcf3b4dd00ddbf08 (patch)
tree66cdf5ae7efa2fe90491caa6cd15c6158791f17e /fs/afs
parent21b9f1c7e319f654de3b2574fe8d4e4114c9143f (diff)
afs: Fix directory permissions check
Doing faccessat("/afs/some/directory", 0) triggers a BUG in the permissions check code. Fix this by just removing the BUG section. If no permissions are asked for, just return okay if the file exists. Also: (1) Split up the directory check so that it has separate if-statements rather than if-else-if (e.g. checking for MAY_EXEC shouldn't skip the check for MAY_READ and MAY_WRITE). (2) Check for MAY_CHDIR as MAY_EXEC. Without the main fix, the following BUG may occur: kernel BUG at fs/afs/security.c:386! invalid opcode: 0000 [#1] SMP PTI ... RIP: 0010:afs_permission+0x19d/0x1a0 [kafs] ... Call Trace: ? inode_permission+0xbe/0x180 ? do_faccessat+0xdc/0x270 ? do_syscall_64+0x60/0x1f0 ? entry_SYSCALL_64_after_hwframe+0x49/0xbe Fixes: 00d3b7a4533e ("[AFS]: Add security support.") Reported-by: Jonathan Billings <jsbillings@jsbillings.org> Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs')
-rw-r--r--fs/afs/security.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/fs/afs/security.c b/fs/afs/security.c
index 1992b0ffa543..81dfedb7879f 100644
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -372,18 +372,14 @@ int afs_permission(struct inode *inode, int mask)
372 mask, access, S_ISDIR(inode->i_mode) ? "dir" : "file"); 372 mask, access, S_ISDIR(inode->i_mode) ? "dir" : "file");
373 373
374 if (S_ISDIR(inode->i_mode)) { 374 if (S_ISDIR(inode->i_mode)) {
375 if (mask & MAY_EXEC) { 375 if (mask & (MAY_EXEC | MAY_READ | MAY_CHDIR)) {
376 if (!(access & AFS_ACE_LOOKUP)) 376 if (!(access & AFS_ACE_LOOKUP))
377 goto permission_denied; 377 goto permission_denied;
378 } else if (mask & MAY_READ) { 378 }
379 if (!(access & AFS_ACE_LOOKUP)) 379 if (mask & MAY_WRITE) {
380 goto permission_denied;
381 } else if (mask & MAY_WRITE) {
382 if (!(access & (AFS_ACE_DELETE | /* rmdir, unlink, rename from */ 380 if (!(access & (AFS_ACE_DELETE | /* rmdir, unlink, rename from */
383 AFS_ACE_INSERT))) /* create, mkdir, symlink, rename to */ 381 AFS_ACE_INSERT))) /* create, mkdir, symlink, rename to */
384 goto permission_denied; 382 goto permission_denied;
385 } else {
386 BUG();
387 } 383 }
388 } else { 384 } else {
389 if (!(access & AFS_ACE_LOOKUP)) 385 if (!(access & AFS_ACE_LOOKUP))