diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-29 16:30:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-29 16:30:16 -0400 |
commit | 91fc957a61fac43f05dfbe1877bc371271f4dd5f (patch) | |
tree | 9e1219feef5ddda76ddc9da03c2952720b9dbb30 | |
parent | 3d661e2a2d1cf0ad1ce54d690f05e755da59e6c9 (diff) | |
parent | 1fba5868eed82766fb374c7d367166706f9269d5 (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.c | 10 | ||||
-rw-r--r-- | fs/afs/vlclient.c | 19 |
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 | } |