aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-06-20 19:55:42 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 01:43:30 -0400
commitd594e7ec4da6c1a527dea4965eee37cd785792b8 (patch)
treeb1c50c217309934a25449052625747927cbe4b45
parenteecdd358b467405a084d400d5ec571bbdbfe97a3 (diff)
massage generic_permission() to treat directories on a separate path
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namei.c17
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