[PATCH 3.18.y 3/5] security_d_instantiate(): move to the point prior to attaching dentry to inode

From: Seung-Woo Kim
Date: Thu Aug 09 2018 - 05:53:49 EST


From: Al Viro <viro@xxxxxxxxxxxxxxxxxx>

commit b96809173e94ea2fa8c19c2e40e8545a1821bf57 upstream.

Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>

[sw0312.kim: backport to 3.18]
Signed-off-by: Seung-Woo Kim <sw0312.kim@xxxxxxxxxxx>
---
fs/dcache.c | 18 +++++++-----------
1 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/fs/dcache.c b/fs/dcache.c
index a34d401..6a4290a 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1729,12 +1729,12 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
void d_instantiate(struct dentry *entry, struct inode * inode)
{
BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
+ security_d_instantiate(entry, inode);
if (inode)
spin_lock(&inode->i_lock);
__d_instantiate(entry, inode);
if (inode)
spin_unlock(&inode->i_lock);
- security_d_instantiate(entry, inode);
}
EXPORT_SYMBOL(d_instantiate);

@@ -1795,16 +1795,15 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)

BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));

+ security_d_instantiate(entry, inode);
if (inode)
spin_lock(&inode->i_lock);
result = __d_instantiate_unique(entry, inode);
if (inode)
spin_unlock(&inode->i_lock);

- if (!result) {
- security_d_instantiate(entry, inode);
+ if (!result)
return NULL;
- }

BUG_ON(!d_unhashed(result));
iput(inode);
@@ -1826,6 +1825,7 @@ int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode)
{
BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));

+ security_d_instantiate(entry, inode);
spin_lock(&inode->i_lock);
if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) {
spin_unlock(&inode->i_lock);
@@ -1834,7 +1834,6 @@ int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode)
}
__d_instantiate(entry, inode);
spin_unlock(&inode->i_lock);
- security_d_instantiate(entry, inode);

return 0;
}
@@ -1930,6 +1929,7 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
goto out_iput;
}

+ security_d_instantiate(tmp, inode);
spin_lock(&inode->i_lock);
res = __d_find_any_alias(inode);
if (res) {
@@ -1953,13 +1953,10 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
hlist_bl_unlock(&tmp->d_sb->s_anon);
spin_unlock(&tmp->d_lock);
spin_unlock(&inode->i_lock);
- security_d_instantiate(tmp, inode);

return tmp;

out_iput:
- if (res && !IS_ERR(res))
- security_d_instantiate(res, inode);
iput(inode);
return res;
}
@@ -2817,6 +2814,7 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
return ERR_CAST(inode);

if (inode && S_ISDIR(inode->i_mode)) {
+ security_d_instantiate(dentry, inode);
spin_lock(&inode->i_lock);
new = __d_find_any_alias(inode);
if (new) {
@@ -2836,13 +2834,11 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
__d_move(new, dentry, false);
write_sequnlock(&rename_lock);
spin_unlock(&inode->i_lock);
- security_d_instantiate(new, inode);
iput(inode);
} else {
/* already taking inode->i_lock, so d_add() by hand */
__d_instantiate(dentry, inode);
spin_unlock(&inode->i_lock);
- security_d_instantiate(dentry, inode);
d_rehash(dentry);
}
} else {
@@ -2876,6 +2872,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
goto out_nolock;
}

+ security_d_instantiate(dentry, inode);
spin_lock(&inode->i_lock);

if (S_ISDIR(inode->i_mode)) {
@@ -2927,7 +2924,6 @@ found:
spin_unlock(&inode->i_lock);
out_nolock:
if (actual == dentry) {
- security_d_instantiate(dentry, inode);
return NULL;
}

--
1.7.4.1