diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/namei.c b/fs/namei.c index 21eba95368f2..758bae739305 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -235,12 +235,21 @@ int generic_permission(struct inode *inode, int mask) | |||
235 | if (ret != -EACCES) | 235 | if (ret != -EACCES) |
236 | return ret; | 236 | return ret; |
237 | 237 | ||
238 | if (S_ISDIR(inode->i_mode)) { | ||
239 | /* DACs are overridable for directories */ | ||
240 | if (ns_capable(inode_userns(inode), CAP_DAC_OVERRIDE)) | ||
241 | return 0; | ||
242 | if (!(mask & MAY_WRITE)) | ||
243 | if (ns_capable(inode_userns(inode), CAP_DAC_READ_SEARCH)) | ||
244 | return 0; | ||
245 | return -EACCES; | ||
246 | } | ||
238 | /* | 247 | /* |
239 | * Read/write DACs are always overridable. | 248 | * Read/write DACs are always overridable. |
240 | * Executable DACs are overridable for all directories and | 249 | * Executable DACs are overridable when there is |
241 | * for non-directories that have least one exec bit set. | 250 | * at least one exec bit set. |
242 | */ | 251 | */ |
243 | if (!(mask & MAY_EXEC) || execute_ok(inode)) | 252 | if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO)) |
244 | if (ns_capable(inode_userns(inode), CAP_DAC_OVERRIDE)) | 253 | if (ns_capable(inode_userns(inode), CAP_DAC_OVERRIDE)) |
245 | return 0; | 254 | return 0; |
246 | 255 | ||
@@ -248,7 +257,7 @@ int generic_permission(struct inode *inode, int mask) | |||
248 | * Searching includes executable on directories, else just read. | 257 | * Searching includes executable on directories, else just read. |
249 | */ | 258 | */ |
250 | mask &= MAY_READ | MAY_WRITE | MAY_EXEC; | 259 | mask &= MAY_READ | MAY_WRITE | MAY_EXEC; |
251 | if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))) | 260 | if (mask == MAY_READ) |
252 | if (ns_capable(inode_userns(inode), CAP_DAC_READ_SEARCH)) | 261 | if (ns_capable(inode_userns(inode), CAP_DAC_READ_SEARCH)) |
253 | return 0; | 262 | return 0; |
254 | 263 | ||