aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-29 16:30:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-29 16:30:16 -0400
commit91fc957a61fac43f05dfbe1877bc371271f4dd5f (patch)
tree9e1219feef5ddda76ddc9da03c2952720b9dbb30
parent3d661e2a2d1cf0ad1ce54d690f05e755da59e6c9 (diff)
parent1fba5868eed82766fb374c7d367166706f9269d5 (diff)
Merge tag 'afs-fixes-20180529' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull AFS fixes from David Howells: - fix a BUG triggerable from faccessat() - fix the mounting of backup volumes * tag 'afs-fixes-20180529' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: afs: Fix mounting of backup volumes afs: Fix directory permissions check
-rw-r--r--fs/afs/security.c10
-rw-r--r--fs/afs/vlclient.c19
2 files changed, 13 insertions, 16 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))
diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c
index 1ed7e2fd2f35..c3b740813fc7 100644
--- a/fs/afs/vlclient.c
+++ b/fs/afs/vlclient.c
@@ -23,7 +23,7 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
23 struct afs_uvldbentry__xdr *uvldb; 23 struct afs_uvldbentry__xdr *uvldb;
24 struct afs_vldb_entry *entry; 24 struct afs_vldb_entry *entry;
25 bool new_only = false; 25 bool new_only = false;
26 u32 tmp, nr_servers; 26 u32 tmp, nr_servers, vlflags;
27 int i, ret; 27 int i, ret;
28 28
29 _enter(""); 29 _enter("");
@@ -55,6 +55,7 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
55 new_only = true; 55 new_only = true;
56 } 56 }
57 57
58 vlflags = ntohl(uvldb->flags);
58 for (i = 0; i < nr_servers; i++) { 59 for (i = 0; i < nr_servers; i++) {
59 struct afs_uuid__xdr *xdr; 60 struct afs_uuid__xdr *xdr;
60 struct afs_uuid *uuid; 61 struct afs_uuid *uuid;
@@ -64,12 +65,13 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
64 if (tmp & AFS_VLSF_DONTUSE || 65 if (tmp & AFS_VLSF_DONTUSE ||
65 (new_only && !(tmp & AFS_VLSF_NEWREPSITE))) 66 (new_only && !(tmp & AFS_VLSF_NEWREPSITE)))
66 continue; 67 continue;
67 if (tmp & AFS_VLSF_RWVOL) 68 if (tmp & AFS_VLSF_RWVOL) {
68 entry->fs_mask[i] |= AFS_VOL_VTM_RW; 69 entry->fs_mask[i] |= AFS_VOL_VTM_RW;
70 if (vlflags & AFS_VLF_BACKEXISTS)
71 entry->fs_mask[i] |= AFS_VOL_VTM_BAK;
72 }
69 if (tmp & AFS_VLSF_ROVOL) 73 if (tmp & AFS_VLSF_ROVOL)
70 entry->fs_mask[i] |= AFS_VOL_VTM_RO; 74 entry->fs_mask[i] |= AFS_VOL_VTM_RO;
71 if (tmp & AFS_VLSF_BACKVOL)
72 entry->fs_mask[i] |= AFS_VOL_VTM_BAK;
73 if (!entry->fs_mask[i]) 75 if (!entry->fs_mask[i])
74 continue; 76 continue;
75 77
@@ -89,15 +91,14 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
89 for (i = 0; i < AFS_MAXTYPES; i++) 91 for (i = 0; i < AFS_MAXTYPES; i++)
90 entry->vid[i] = ntohl(uvldb->volumeId[i]); 92 entry->vid[i] = ntohl(uvldb->volumeId[i]);
91 93
92 tmp = ntohl(uvldb->flags); 94 if (vlflags & AFS_VLF_RWEXISTS)
93 if (tmp & AFS_VLF_RWEXISTS)
94 __set_bit(AFS_VLDB_HAS_RW, &entry->flags); 95 __set_bit(AFS_VLDB_HAS_RW, &entry->flags);
95 if (tmp & AFS_VLF_ROEXISTS) 96 if (vlflags & AFS_VLF_ROEXISTS)
96 __set_bit(AFS_VLDB_HAS_RO, &entry->flags); 97 __set_bit(AFS_VLDB_HAS_RO, &entry->flags);
97 if (tmp & AFS_VLF_BACKEXISTS) 98 if (vlflags & AFS_VLF_BACKEXISTS)
98 __set_bit(AFS_VLDB_HAS_BAK, &entry->flags); 99 __set_bit(AFS_VLDB_HAS_BAK, &entry->flags);
99 100
100 if (!(tmp & (AFS_VLF_RWEXISTS | AFS_VLF_ROEXISTS | AFS_VLF_BACKEXISTS))) { 101 if (!(vlflags & (AFS_VLF_RWEXISTS | AFS_VLF_ROEXISTS | AFS_VLF_BACKEXISTS))) {
101 entry->error = -ENOMEDIUM; 102 entry->error = -ENOMEDIUM;
102 __set_bit(AFS_VLDB_QUERY_ERROR, &entry->flags); 103 __set_bit(AFS_VLDB_QUERY_ERROR, &entry->flags);
103 } 104 }