aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c19
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
160void putname(const char *name) 160void 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
228int permission(struct inode *inode, int mask, struct nameidata *nd) 228int 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);
1126out: 1133out:
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.