aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor/path.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:20:30 -0500
committerGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:21:47 -0500
commitd392da5207352f09030e95d9ea335a4225667ec0 (patch)
tree7d6cd1932afcad0a5619a5c504a6d93ca318187c /security/apparmor/path.c
parente39d5ef678045d61812c1401f04fe8edb14d6359 (diff)
parent387c31c7e5c9805b0aef8833d1731a5fe7bdea14 (diff)
Merge v2.6.37-rc8 into powerpc/next
Diffstat (limited to 'security/apparmor/path.c')
-rw-r--r--security/apparmor/path.c49
1 files changed, 13 insertions, 36 deletions
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 96bab9469d48..36cc0cc39e78 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -59,40 +59,21 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
59{ 59{
60 struct path root, tmp; 60 struct path root, tmp;
61 char *res; 61 char *res;
62 int deleted, connected; 62 int connected, error = 0;
63 int error = 0;
64 63
65 /* Get the root we want to resolve too */ 64 /* Get the root we want to resolve too, released below */
66 if (flags & PATH_CHROOT_REL) { 65 if (flags & PATH_CHROOT_REL) {
67 /* resolve paths relative to chroot */ 66 /* resolve paths relative to chroot */
68 read_lock(&current->fs->lock); 67 get_fs_root(current->fs, &root);
69 root = current->fs->root;
70 /* released below */
71 path_get(&root);
72 read_unlock(&current->fs->lock);
73 } else { 68 } else {
74 /* resolve paths relative to namespace */ 69 /* resolve paths relative to namespace */
75 root.mnt = current->nsproxy->mnt_ns->root; 70 root.mnt = current->nsproxy->mnt_ns->root;
76 root.dentry = root.mnt->mnt_root; 71 root.dentry = root.mnt->mnt_root;
77 /* released below */
78 path_get(&root); 72 path_get(&root);
79 } 73 }
80 74
81 spin_lock(&dcache_lock); 75 tmp = root;
82 /* There is a race window between path lookup here and the 76 res = __d_path(path, &tmp, buf, buflen);
83 * need to strip the " (deleted) string that __d_path applies
84 * Detect the race and relookup the path
85 *
86 * The stripping of (deleted) is a hack that could be removed
87 * with an updated __d_path
88 */
89 do {
90 tmp = root;
91 deleted = d_unlinked(path->dentry);
92 res = __d_path(path, &tmp, buf, buflen);
93
94 } while (deleted != d_unlinked(path->dentry));
95 spin_unlock(&dcache_lock);
96 77
97 *name = res; 78 *name = res;
98 /* handle error conditions - and still allow a partial path to 79 /* handle error conditions - and still allow a partial path to
@@ -103,21 +84,17 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
103 *name = buf; 84 *name = buf;
104 goto out; 85 goto out;
105 } 86 }
106 if (deleted) {
107 /* On some filesystems, newly allocated dentries appear to the
108 * security_path hooks as a deleted dentry except without an
109 * inode allocated.
110 *
111 * Remove the appended deleted text and return as string for
112 * normal mediation, or auditing. The (deleted) string is
113 * guaranteed to be added in this case, so just strip it.
114 */
115 buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */
116 87
117 if (path->dentry->d_inode && !(flags & PATH_MEDIATE_DELETED)) { 88 /* Handle two cases:
89 * 1. A deleted dentry && profile is not allowing mediation of deleted
90 * 2. On some filesystems, newly allocated dentries appear to the
91 * security_path hooks as a deleted dentry except without an inode
92 * allocated.
93 */
94 if (d_unlinked(path->dentry) && path->dentry->d_inode &&
95 !(flags & PATH_MEDIATE_DELETED)) {
118 error = -ENOENT; 96 error = -ENOENT;
119 goto out; 97 goto out;
120 }
121 } 98 }
122 99
123 /* Determine if the path is connected to the expected root */ 100 /* Determine if the path is connected to the expected root */