lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <201002260322.o1Q3Mc3r000644@www262.sakura.ne.jp>
Date:	Fri, 26 Feb 2010 12:22:38 +0900
From:	Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
To:	john.johansen@...onical.com
Cc:	linux-security-module@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [AppArmor #4 0/12] AppArmor security module

Regarding path.c

"struct task_struct" has "struct fs_struct *fs" and "struct nsproxy *nsproxy".
The former is used for holding current process's root directory and current
directory.
The latter is used for holding current process's namespace information.

I'm not sure, but I think we can directly fetch current process's namespace's
root by dereferencing current->nsproxy->mnt_ns , and therefore simplify
d_namespace_path() as follows.

 36 static int d_namespace_path(struct path *path, char *buf, int buflen,
 37                             char **name, int flags)
 38 {
 39         struct path root, tmp, ns_root = { };

	/* Remove "ns_root" as only "root" and "tmp" are used. */

 40         char *res;
 41         int deleted, connected;
 42         int error = 0;
 43 

	if (flags & PATH_CHROOT_REL) {

 44         read_lock(&current->fs->lock);
 45         root = current->fs->root;
 46         /* released below */
 47         path_get(&root);
 48         read_unlock(&current->fs->lock);
 49 

	} else {
		root.mnt = current->nsproxy->root;
		root.dentry = root.mnt->mnt_root;
		/* released below */
		path_get(&root);
	}

	/*

 50         spin_lock(&vfsmount_lock);
 51         if (root.mnt && root.mnt->mnt_ns)
 52                 /* released below */
 53                 ns_root.mnt = mntget(root.mnt->mnt_ns->root);
 54         if (ns_root.mnt)
 55                 /* released below */
 56                 ns_root.dentry = dget(ns_root.mnt->mnt_root);
 57         spin_unlock(&vfsmount_lock);
 58 

	*/

 59         spin_lock(&dcache_lock);
 60         /* There is a race window between path lookup here and the
 61          * need to strip the " (deleted) string that __d_path applies
 62          * Detect the race and relookup the path
 63          *
 64          * The stripping of (deleted) is a hack that could be removed
 65          * with an updated __d_path
 66          */
 67         do {

		/*

 68                 if (flags & PATH_CHROOT_REL)

		*/

 69                         tmp = root;

		/*

 70                 else
 71                         tmp = ns_root;

		*/

 72                 deleted = d_unlinked(path->dentry);
 73                 res = __d_path(path, &tmp, buf, buflen);
 74 
 75         } while (deleted != d_unlinked(path->dentry));
 76         spin_unlock(&dcache_lock);
 77 
 78         *name = res;
 79         /* handle error conditions - and still allow a partial path to
 80          * be returned.
 81          */
 82         if (IS_ERR(res)) {
 83                 error = PTR_ERR(res);
 84                 *name = buf;
 85                 goto out;
 86         }
 87         if (deleted) {
 88                 /* On some filesystems, newly allocated dentries appear to the
 89                  * security_path hooks as a deleted dentry except without an
 90                  * inode allocated.
 91                  *
 92                  * Remove the appended deleted text and return as string for
 93                  * normal mediation, or auditing.  The (deleted) string is
 94                  * guarenteed to be added in this case, so just strip it.
 95                  */
 96                 buf[buflen - 11] = 0;   /* - (len(" (deleted)") +\0) */
 97 
 98                 if (path->dentry->d_inode && !(flags & PATH_MEDIATE_DELETED)) {
 99                         error = -ENOENT;
100                         goto out;
101                 }
102         }
103 

	/*

104         if (flags & PATH_CHROOT_REL)

	*/

105                 connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt;

	/*

106         else
107                 connected = tmp.dentry == ns_root.dentry &&
108                         tmp.mnt == ns_root.mnt;

	*/

109 
110         if (!connected && 
111             !(flags & PATH_CONNECT_PATH) &&
112             !((flags & PATH_CHROOT_REL) && (flags & PATH_CHROOT_NSCONNECT) &&
113               (tmp.dentry == ns_root.dentry && tmp.mnt == ns_root.mnt))) {

	/* Change from "ns_root" to "root". */

114                 /* disconnected path, don't return pathname starting with '/' */
115                 error = -ESTALE;
116                 if (*res == '/')
117                         *name = res + 1;
118         }
119 
120 out:
121         path_put(&root);

	/*

122         path_put(&ns_root);

	*/

123 
124         return error;
125 }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ