diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/fs/namei.c b/fs/namei.c index e01070d7bf58..432d6bc6fab0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -159,7 +159,7 @@ char * getname(const char __user * filename) | |||
159 | #ifdef CONFIG_AUDITSYSCALL | 159 | #ifdef CONFIG_AUDITSYSCALL |
160 | void putname(const char *name) | 160 | void putname(const char *name) |
161 | { | 161 | { |
162 | if (unlikely(current->audit_context)) | 162 | if (unlikely(!audit_dummy_context())) |
163 | audit_putname(name); | 163 | audit_putname(name); |
164 | else | 164 | else |
165 | __putname(name); | 165 | __putname(name); |
@@ -227,10 +227,10 @@ int generic_permission(struct inode *inode, int mask, | |||
227 | 227 | ||
228 | int permission(struct inode *inode, int mask, struct nameidata *nd) | 228 | int permission(struct inode *inode, int mask, struct nameidata *nd) |
229 | { | 229 | { |
230 | umode_t mode = inode->i_mode; | ||
230 | int retval, submask; | 231 | int retval, submask; |
231 | 232 | ||
232 | if (mask & MAY_WRITE) { | 233 | if (mask & MAY_WRITE) { |
233 | umode_t mode = inode->i_mode; | ||
234 | 234 | ||
235 | /* | 235 | /* |
236 | * Nobody gets write access to a read-only fs. | 236 | * Nobody gets write access to a read-only fs. |
@@ -247,6 +247,13 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
247 | } | 247 | } |
248 | 248 | ||
249 | 249 | ||
250 | /* | ||
251 | * MAY_EXEC on regular files requires special handling: We override | ||
252 | * filesystem execute permissions if the mode bits aren't set. | ||
253 | */ | ||
254 | if ((mask & MAY_EXEC) && S_ISREG(mode) && !(mode & S_IXUGO)) | ||
255 | return -EACCES; | ||
256 | |||
250 | /* Ordinary permission routines do not understand MAY_APPEND. */ | 257 | /* Ordinary permission routines do not understand MAY_APPEND. */ |
251 | submask = mask & ~MAY_APPEND; | 258 | submask = mask & ~MAY_APPEND; |
252 | if (inode->i_op && inode->i_op->permission) | 259 | if (inode->i_op && inode->i_op->permission) |
@@ -1125,7 +1132,7 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
1125 | retval = link_path_walk(name, nd); | 1132 | retval = link_path_walk(name, nd); |
1126 | out: | 1133 | out: |
1127 | if (likely(retval == 0)) { | 1134 | if (likely(retval == 0)) { |
1128 | if (unlikely(current->audit_context && nd && nd->dentry && | 1135 | if (unlikely(!audit_dummy_context() && nd && nd->dentry && |
1129 | nd->dentry->d_inode)) | 1136 | nd->dentry->d_inode)) |
1130 | audit_inode(name, nd->dentry->d_inode); | 1137 | audit_inode(name, nd->dentry->d_inode); |
1131 | } | 1138 | } |
@@ -1357,7 +1364,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir) | |||
1357 | return -ENOENT; | 1364 | return -ENOENT; |
1358 | 1365 | ||
1359 | BUG_ON(victim->d_parent->d_inode != dir); | 1366 | BUG_ON(victim->d_parent->d_inode != dir); |
1360 | audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino); | 1367 | audit_inode_child(victim->d_name.name, victim->d_inode, dir); |
1361 | 1368 | ||
1362 | error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); | 1369 | error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); |
1363 | if (error) | 1370 | if (error) |
@@ -1659,6 +1666,7 @@ do_last: | |||
1659 | * It already exists. | 1666 | * It already exists. |
1660 | */ | 1667 | */ |
1661 | mutex_unlock(&dir->d_inode->i_mutex); | 1668 | mutex_unlock(&dir->d_inode->i_mutex); |
1669 | audit_inode_update(path.dentry->d_inode); | ||
1662 | 1670 | ||
1663 | error = -EEXIST; | 1671 | error = -EEXIST; |
1664 | if (flag & O_EXCL) | 1672 | if (flag & O_EXCL) |
@@ -1669,6 +1677,7 @@ do_last: | |||
1669 | if (flag & O_NOFOLLOW) | 1677 | if (flag & O_NOFOLLOW) |
1670 | goto exit_dput; | 1678 | goto exit_dput; |
1671 | } | 1679 | } |
1680 | |||
1672 | error = -ENOENT; | 1681 | error = -ENOENT; |
1673 | if (!path.dentry->d_inode) | 1682 | if (!path.dentry->d_inode) |
1674 | goto exit_dput; | 1683 | goto exit_dput; |
@@ -1765,6 +1774,8 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir) | |||
1765 | if (nd->last_type != LAST_NORM) | 1774 | if (nd->last_type != LAST_NORM) |
1766 | goto fail; | 1775 | goto fail; |
1767 | nd->flags &= ~LOOKUP_PARENT; | 1776 | nd->flags &= ~LOOKUP_PARENT; |
1777 | nd->flags |= LOOKUP_CREATE; | ||
1778 | nd->intent.open.flags = O_EXCL; | ||
1768 | 1779 | ||
1769 | /* | 1780 | /* |
1770 | * Do the final lookup. | 1781 | * Do the final lookup. |