1f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda/*
2f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda * security/tomoyo/tomoyo.c
3f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda *
40f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Copyright (C) 2005-2011  NTT DATA CORPORATION
5f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda */
6f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
7f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda#include <linux/security.h>
8f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda#include "common.h"
9f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
100f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
110f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_cred_alloc_blank - Target for security_cred_alloc_blank().
120f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
130f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @new: Pointer to "struct cred".
140f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @gfp: Memory allocation flags.
150f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
160f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0.
170f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
18ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howellsstatic int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
19ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells{
20ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells	new->security = NULL;
21ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells	return 0;
22ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells}
23ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells
240f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
250f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_cred_prepare - Target for security_prepare_creds().
260f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
270f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @new: Pointer to "struct cred".
280f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @old: Pointer to "struct cred".
290f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @gfp: Memory allocation flags.
300f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
310f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0.
320f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
33f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
34f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda			       gfp_t gfp)
35f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
36ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	struct tomoyo_domain_info *domain = old->security;
37ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	new->security = domain;
38ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	if (domain)
39ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa		atomic_inc(&domain->users);
40f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	return 0;
41f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
42f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
430f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
440f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_cred_transfer - Target for security_transfer_creds().
450f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
460f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @new: Pointer to "struct cred".
470f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @old: Pointer to "struct cred".
480f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
49ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howellsstatic void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
50ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells{
51ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	tomoyo_cred_prepare(new, old, 0);
52ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa}
53ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa
540f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
550f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_cred_free - Target for security_cred_free().
560f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
570f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @cred: Pointer to "struct cred".
580f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
59ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handastatic void tomoyo_cred_free(struct cred *cred)
60ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa{
61ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	struct tomoyo_domain_info *domain = cred->security;
62ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	if (domain)
63ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa		atomic_dec(&domain->users);
64ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells}
65ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells
660f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
670f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_bprm_set_creds - Target for security_bprm_set_creds().
680f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
690f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @bprm: Pointer to "struct linux_binprm".
700f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
710f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
720f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
73f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
74f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
75b1338d199dda6681d9af0297928af0a7eb9cba7bHerton Ronaldo Krzesinski	int rc;
76b1338d199dda6681d9af0297928af0a7eb9cba7bHerton Ronaldo Krzesinski
77b1338d199dda6681d9af0297928af0a7eb9cba7bHerton Ronaldo Krzesinski	rc = cap_bprm_set_creds(bprm);
78b1338d199dda6681d9af0297928af0a7eb9cba7bHerton Ronaldo Krzesinski	if (rc)
79b1338d199dda6681d9af0297928af0a7eb9cba7bHerton Ronaldo Krzesinski		return rc;
80b1338d199dda6681d9af0297928af0a7eb9cba7bHerton Ronaldo Krzesinski
81f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	/*
82f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 * Do only if this function is called for the first time of an execve
83f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 * operation.
84f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 */
85f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	if (bprm->cred_prepared)
86f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda		return 0;
877986cf28bc5050967a7056d6eadda7f16f84eaabTetsuo Handa#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
88f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	/*
89f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
90f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 * for the first time.
91f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 */
92f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	if (!tomoyo_policy_loaded)
93f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda		tomoyo_load_policy(bprm->filename);
947986cf28bc5050967a7056d6eadda7f16f84eaabTetsuo Handa#endif
95f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	/*
96ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	 * Release reference to "struct tomoyo_domain_info" stored inside
97ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	 * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
98ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	 * stored inside "bprm->cred->security" will be acquired later inside
99ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	 * tomoyo_find_next_domain().
100ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	 */
101ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	atomic_dec(&((struct tomoyo_domain_info *)
102ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa		     bprm->cred->security)->users);
103ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	/*
104f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 * Tell tomoyo_bprm_check_security() is called for the first time of an
105f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 * execve operation.
106f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 */
107f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	bprm->cred->security = NULL;
108f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	return 0;
109f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
110f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
1110f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
1120f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_bprm_check_security - Target for security_bprm_check().
1130f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1140f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @bprm: Pointer to "struct linux_binprm".
1150f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1160f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
1170f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
118f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_bprm_check_security(struct linux_binprm *bprm)
119f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
120f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct tomoyo_domain_info *domain = bprm->cred->security;
121f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
122f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	/*
123f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 * Execute permission is checked against pathname passed to do_execve()
124f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 * using current domain.
125f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 */
126fdb8ebb729bbb640e64028a4f579a02ebc405727Tetsuo Handa	if (!domain) {
127fdb8ebb729bbb640e64028a4f579a02ebc405727Tetsuo Handa		const int idx = tomoyo_read_lock();
128fdb8ebb729bbb640e64028a4f579a02ebc405727Tetsuo Handa		const int err = tomoyo_find_next_domain(bprm);
129fdb8ebb729bbb640e64028a4f579a02ebc405727Tetsuo Handa		tomoyo_read_unlock(idx);
130fdb8ebb729bbb640e64028a4f579a02ebc405727Tetsuo Handa		return err;
131fdb8ebb729bbb640e64028a4f579a02ebc405727Tetsuo Handa	}
132f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	/*
133f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 * Read permission is checked against interpreters using next domain.
134f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	 */
1350f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa	return tomoyo_check_open_permission(domain, &bprm->file->f_path,
1360f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa					    O_RDONLY);
137f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
138f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
1390f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
1400f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_inode_getattr - Target for security_inode_getattr().
1410f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1420f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @mnt:    Pointer to "struct vfsmount".
1430f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @dentry: Pointer to "struct dentry".
1440f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1450f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
1460f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
1477c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handastatic int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
1487c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handa{
1497c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handa	struct path path = { mnt, dentry };
15097fb35e413f256ded07b88c73b3d932ec31ea84eTetsuo Handa	return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path, NULL);
1517c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handa}
1527c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handa
1530f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
1540f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_truncate - Target for security_path_truncate().
1550f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1560f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @path: Pointer to "struct path".
1570f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1580f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
1590f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
160ea0d3ab239fba48d6e998b19c28d78f765963007Tetsuo Handastatic int tomoyo_path_truncate(struct path *path)
161f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
16297fb35e413f256ded07b88c73b3d932ec31ea84eTetsuo Handa	return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL);
163f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
164f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
1650f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
1660f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_unlink - Target for security_path_unlink().
1670f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1680f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @parent: Pointer to "struct path".
1690f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @dentry: Pointer to "struct dentry".
1700f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1710f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
1720f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
173f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
174f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
175f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct path path = { parent->mnt, dentry };
17697fb35e413f256ded07b88c73b3d932ec31ea84eTetsuo Handa	return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
177f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
178f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
1790f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
1800f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_mkdir - Target for security_path_mkdir().
1810f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1820f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @parent: Pointer to "struct path".
1830f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @dentry: Pointer to "struct dentry".
1840f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @mode:   DAC permission mode.
1850f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1860f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
1870f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
188f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
1894572befe248fd0d94aedc98775e3f0ddc8a26651Al Viro			     umode_t mode)
190f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
191f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct path path = { parent->mnt, dentry };
192a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa	return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path,
193a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa				       mode & S_IALLUGO);
194f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
195f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
1960f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
1970f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_rmdir - Target for security_path_rmdir().
1980f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
1990f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @parent: Pointer to "struct path".
2000f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @dentry: Pointer to "struct dentry".
2010f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
2020f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
2030f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
204f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
205f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
206f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct path path = { parent->mnt, dentry };
20797fb35e413f256ded07b88c73b3d932ec31ea84eTetsuo Handa	return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
208f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
209f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
2100f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
2110f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_symlink - Target for security_path_symlink().
2120f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
2130f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @parent:   Pointer to "struct path".
2140f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @dentry:   Pointer to "struct dentry".
2150f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @old_name: Symlink's content.
2160f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
2170f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
2180f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
219f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
220f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda			       const char *old_name)
221f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
222f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct path path = { parent->mnt, dentry };
22397fb35e413f256ded07b88c73b3d932ec31ea84eTetsuo Handa	return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
224f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
225f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
2260f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
2270f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_mknod - Target for security_path_mknod().
2280f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
2290f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @parent: Pointer to "struct path".
2300f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @dentry: Pointer to "struct dentry".
2310f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @mode:   DAC permission mode.
2320f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @dev:    Device attributes.
2330f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
2340f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
2350f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
236f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
23704fc66e789a896e684bfdca30208e57eb832dd96Al Viro			     umode_t mode, unsigned int dev)
238f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
239f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct path path = { parent->mnt, dentry };
2407ef612331fb219620cc1abfc2446bb027d388aa0Tetsuo Handa	int type = TOMOYO_TYPE_CREATE;
241a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa	const unsigned int perm = mode & S_IALLUGO;
242f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
243f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	switch (mode & S_IFMT) {
244f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	case S_IFCHR:
2457ef612331fb219620cc1abfc2446bb027d388aa0Tetsuo Handa		type = TOMOYO_TYPE_MKCHAR;
246f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda		break;
247f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	case S_IFBLK:
2487ef612331fb219620cc1abfc2446bb027d388aa0Tetsuo Handa		type = TOMOYO_TYPE_MKBLOCK;
249f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda		break;
250a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa	default:
251a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa		goto no_dev;
252a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa	}
25375093152a97ee0ec281895b4f6229ff3c481fd64Tetsuo Handa	return tomoyo_mkdev_perm(type, &path, perm, dev);
254a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa no_dev:
255a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa	switch (mode & S_IFMT) {
256f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	case S_IFIFO:
2577ef612331fb219620cc1abfc2446bb027d388aa0Tetsuo Handa		type = TOMOYO_TYPE_MKFIFO;
258f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda		break;
259f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	case S_IFSOCK:
2607ef612331fb219620cc1abfc2446bb027d388aa0Tetsuo Handa		type = TOMOYO_TYPE_MKSOCK;
261f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda		break;
262f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	}
263a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa	return tomoyo_path_number_perm(type, &path, perm);
264f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
265f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
2660f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
2670f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_link - Target for security_path_link().
2680f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
2690f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @old_dentry: Pointer to "struct dentry".
2700f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @new_dir:    Pointer to "struct path".
2710f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @new_dentry: Pointer to "struct dentry".
2720f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
2730f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
2740f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
275f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
276f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda			    struct dentry *new_dentry)
277f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
278f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct path path1 = { new_dir->mnt, old_dentry };
279f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct path path2 = { new_dir->mnt, new_dentry };
28097d6931ead3e89a764cdaa3ad0924037367f0d34Tetsuo Handa	return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
281f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
282f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
2830f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
2840f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_rename - Target for security_path_rename().
2850f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
2860f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @old_parent: Pointer to "struct path".
2870f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @old_dentry: Pointer to "struct dentry".
2880f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @new_parent: Pointer to "struct path".
2890f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @new_dentry: Pointer to "struct dentry".
2900f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
2910f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
2920f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
293f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_path_rename(struct path *old_parent,
294f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda			      struct dentry *old_dentry,
295f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda			      struct path *new_parent,
296f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda			      struct dentry *new_dentry)
297f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
298f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct path path1 = { old_parent->mnt, old_dentry };
299f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct path path2 = { new_parent->mnt, new_dentry };
30097d6931ead3e89a764cdaa3ad0924037367f0d34Tetsuo Handa	return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
301f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
302f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
3030f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
3040f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_file_fcntl - Target for security_file_fcntl().
3050f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3060f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @file: Pointer to "struct file".
3070f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @cmd:  Command for fcntl().
3080f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @arg:  Argument for @cmd.
3090f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3100f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
3110f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
312f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
313f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda			     unsigned long arg)
314f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
3157c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handa	if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
3167c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handa		return 0;
3177c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handa	return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
3187c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handa					    O_WRONLY | (arg & O_APPEND));
319f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
320f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
3210f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
32283d498569e9a7a4b92c4c5d3566f2d6a604f28c9Eric Paris * tomoyo_file_open - Target for security_file_open().
3230f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3240f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @f:    Pointer to "struct file".
3250f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @cred: Pointer to "struct cred".
3260f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3270f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
3280f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
32983d498569e9a7a4b92c4c5d3566f2d6a604f28c9Eric Parisstatic int tomoyo_file_open(struct file *f, const struct cred *cred)
330f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
331f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	int flags = f->f_flags;
332f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	/* Don't check read permission here if called from do_execve(). */
333f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	if (current->in_execve)
334f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda		return 0;
335f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
336f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
337f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
3380f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
3390f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_file_ioctl - Target for security_file_ioctl().
3400f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3410f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @file: Pointer to "struct file".
3420f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @cmd:  Command for ioctl().
3430f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @arg:  Argument for @cmd.
3440f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3450f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
3460f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
347937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handastatic int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
348937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa			     unsigned long arg)
349937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa{
350a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa	return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd);
351937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa}
352937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa
3530f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
3540f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_chmod - Target for security_path_chmod().
3550f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
356cdcf116d44e78c7216ba9f8be9af1cdfca7af728Al Viro * @path: Pointer to "struct path".
357cdcf116d44e78c7216ba9f8be9af1cdfca7af728Al Viro * @mode: DAC permission mode.
3580f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3590f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
3600f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
361cdcf116d44e78c7216ba9f8be9af1cdfca7af728Al Virostatic int tomoyo_path_chmod(struct path *path, umode_t mode)
362937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa{
363cdcf116d44e78c7216ba9f8be9af1cdfca7af728Al Viro	return tomoyo_path_number_perm(TOMOYO_TYPE_CHMOD, path,
364a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7Tetsuo Handa				       mode & S_IALLUGO);
365937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa}
366937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa
3670f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
3680f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_chown - Target for security_path_chown().
3690f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3700f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @path: Pointer to "struct path".
3710f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @uid:  Owner ID.
3720f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @gid:  Group ID.
3730f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3740f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
3750f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
376d2b31ca644fdc8704de3367a6a56a5c958c77f53Eric W. Biedermanstatic int tomoyo_path_chown(struct path *path, kuid_t uid, kgid_t gid)
377937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa{
378937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	int error = 0;
379d2b31ca644fdc8704de3367a6a56a5c958c77f53Eric W. Biederman	if (uid_valid(uid))
380d2b31ca644fdc8704de3367a6a56a5c958c77f53Eric W. Biederman		error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path,
381d2b31ca644fdc8704de3367a6a56a5c958c77f53Eric W. Biederman						from_kuid(&init_user_ns, uid));
382d2b31ca644fdc8704de3367a6a56a5c958c77f53Eric W. Biederman	if (!error && gid_valid(gid))
383d2b31ca644fdc8704de3367a6a56a5c958c77f53Eric W. Biederman		error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path,
384d2b31ca644fdc8704de3367a6a56a5c958c77f53Eric W. Biederman						from_kgid(&init_user_ns, gid));
385937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	return error;
386937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa}
387937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa
3880f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
3890f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_path_chroot - Target for security_path_chroot().
3900f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3910f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @path: Pointer to "struct path".
3920f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
3930f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
3940f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
395937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handastatic int tomoyo_path_chroot(struct path *path)
396937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa{
39797fb35e413f256ded07b88c73b3d932ec31ea84eTetsuo Handa	return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL);
398937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa}
399937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa
4000f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
4010f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_sb_mount - Target for security_sb_mount().
4020f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
4030f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @dev_name: Name of device file. Maybe NULL.
4040f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @path:     Pointer to "struct path".
4050f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @type:     Name of filesystem type. Maybe NULL.
4060f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @flags:    Mount options.
4070f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @data:     Optional data. Maybe NULL.
4080f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
4090f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
4100f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
411808d4e3cfdcc52b19276175464f6dbca4df13b09Al Virostatic int tomoyo_sb_mount(const char *dev_name, struct path *path,
412808d4e3cfdcc52b19276175464f6dbca4df13b09Al Viro			   const char *type, unsigned long flags, void *data)
413937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa{
4142106ccd972dcd9fda7df9b181505fac1741b3508Tetsuo Handa	return tomoyo_mount_permission(dev_name, path, type, flags, data);
415937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa}
416937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa
4170f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
4180f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_sb_umount - Target for security_sb_umount().
4190f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
4200f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @mnt:   Pointer to "struct vfsmount".
4210f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @flags: Unmount options.
4220f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
4230f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
4240f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
425937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handastatic int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
426937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa{
427937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	struct path path = { mnt, mnt->mnt_root };
42897fb35e413f256ded07b88c73b3d932ec31ea84eTetsuo Handa	return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
429937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa}
430937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa
4310f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
4320f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_sb_pivotroot - Target for security_sb_pivotroot().
4330f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
4340f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @old_path: Pointer to "struct path".
4350f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * @new_path: Pointer to "struct path".
4360f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
4370f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0 on success, negative value otherwise.
4380f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
439937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handastatic int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
440937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa{
44197d6931ead3e89a764cdaa3ad0924037367f0d34Tetsuo Handa	return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
442937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa}
443937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa
444059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa/**
445059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * tomoyo_socket_listen - Check permission for listen().
446059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa *
447059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @sock:    Pointer to "struct socket".
448059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @backlog: Backlog parameter.
449059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa *
450059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * Returns 0 on success, negative value otherwise.
451059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa */
452059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handastatic int tomoyo_socket_listen(struct socket *sock, int backlog)
453059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa{
454059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa	return tomoyo_socket_listen_permission(sock);
455059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa}
456059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa
457059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa/**
458059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * tomoyo_socket_connect - Check permission for connect().
459059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa *
460059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @sock:     Pointer to "struct socket".
461059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @addr:     Pointer to "struct sockaddr".
462059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @addr_len: Size of @addr.
463059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa *
464059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * Returns 0 on success, negative value otherwise.
465059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa */
466059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handastatic int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr,
467059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa				 int addr_len)
468059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa{
469059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa	return tomoyo_socket_connect_permission(sock, addr, addr_len);
470059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa}
471059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa
472059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa/**
473059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * tomoyo_socket_bind - Check permission for bind().
474059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa *
475059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @sock:     Pointer to "struct socket".
476059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @addr:     Pointer to "struct sockaddr".
477059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @addr_len: Size of @addr.
478059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa *
479059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * Returns 0 on success, negative value otherwise.
480059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa */
481059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handastatic int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr,
482059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa			      int addr_len)
483059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa{
484059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa	return tomoyo_socket_bind_permission(sock, addr, addr_len);
485059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa}
486059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa
487059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa/**
488059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * tomoyo_socket_sendmsg - Check permission for sendmsg().
489059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa *
490059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @sock: Pointer to "struct socket".
491059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @msg:  Pointer to "struct msghdr".
492059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * @size: Size of message.
493059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa *
494059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa * Returns 0 on success, negative value otherwise.
495059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa */
496059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handastatic int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
497059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa				 int size)
498059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa{
499059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa	return tomoyo_socket_sendmsg_permission(sock, msg, size);
500059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa}
501059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa
502c3fa109a5894077d1eaf8731ea741a15dd117b3cTetsuo Handa/*
503c3fa109a5894077d1eaf8731ea741a15dd117b3cTetsuo Handa * tomoyo_security_ops is a "struct security_operations" which is used for
504c3fa109a5894077d1eaf8731ea741a15dd117b3cTetsuo Handa * registering TOMOYO.
505c3fa109a5894077d1eaf8731ea741a15dd117b3cTetsuo Handa */
506f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic struct security_operations tomoyo_security_ops = {
507f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.name                = "tomoyo",
508ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells	.cred_alloc_blank    = tomoyo_cred_alloc_blank,
509f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.cred_prepare        = tomoyo_cred_prepare,
510ee18d64c1f632043a02e6f5ba5e045bb26a5465fDavid Howells	.cred_transfer	     = tomoyo_cred_transfer,
511ec8e6a4e062e2edebef91e930c20572c9f4c0ddaTetsuo Handa	.cred_free           = tomoyo_cred_free,
512f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.bprm_set_creds      = tomoyo_bprm_set_creds,
513f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.bprm_check_security = tomoyo_bprm_check_security,
514f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.file_fcntl          = tomoyo_file_fcntl,
51583d498569e9a7a4b92c4c5d3566f2d6a604f28c9Eric Paris	.file_open           = tomoyo_file_open,
516f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.path_truncate       = tomoyo_path_truncate,
517f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.path_unlink         = tomoyo_path_unlink,
518f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.path_mkdir          = tomoyo_path_mkdir,
519f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.path_rmdir          = tomoyo_path_rmdir,
520f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.path_symlink        = tomoyo_path_symlink,
521f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.path_mknod          = tomoyo_path_mknod,
522f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.path_link           = tomoyo_path_link,
523f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	.path_rename         = tomoyo_path_rename,
5247c75964f432d14062d8eccfc916aa290f56b5aabTetsuo Handa	.inode_getattr       = tomoyo_inode_getattr,
525937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	.file_ioctl          = tomoyo_file_ioctl,
526937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	.path_chmod          = tomoyo_path_chmod,
527937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	.path_chown          = tomoyo_path_chown,
528937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	.path_chroot         = tomoyo_path_chroot,
529937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	.sb_mount            = tomoyo_sb_mount,
530937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	.sb_umount           = tomoyo_sb_umount,
531937bf6133b21b16965f75223085f4314ae32b8ebTetsuo Handa	.sb_pivotroot        = tomoyo_sb_pivotroot,
532059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa	.socket_bind         = tomoyo_socket_bind,
533059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa	.socket_connect      = tomoyo_socket_connect,
534059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa	.socket_listen       = tomoyo_socket_listen,
535059d84dbb3897d4ee494a9c842c5dda54316cb47Tetsuo Handa	.socket_sendmsg      = tomoyo_socket_sendmsg,
536f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda};
537f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
538fdb8ebb729bbb640e64028a4f579a02ebc405727Tetsuo Handa/* Lock for GC. */
539505f14f7b8d446b8e4bc2a6cfc723afbbb365f65Lai JiangshanDEFINE_SRCU(tomoyo_ss);
540fdb8ebb729bbb640e64028a4f579a02ebc405727Tetsuo Handa
5410f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa/**
5420f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * tomoyo_init - Register TOMOYO Linux as a LSM module.
5430f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa *
5440f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Returns 0.
5450f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa */
546f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedastatic int __init tomoyo_init(void)
547f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda{
548f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	struct cred *cred = (struct cred *) current_cred();
549f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
550f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	if (!security_module_enable(&tomoyo_security_ops))
551f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda		return 0;
552f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	/* register ourselves with the security framework */
553505f14f7b8d446b8e4bc2a6cfc723afbbb365f65Lai Jiangshan	if (register_security(&tomoyo_security_ops))
554f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda		panic("Failure registering TOMOYO Linux");
555f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	printk(KERN_INFO "TOMOYO Linux initialized\n");
556f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	cred->security = &tomoyo_kernel_domain;
557c3ef1500ec833890275172c7d063333404b64d60Tetsuo Handa	tomoyo_mm_init();
558f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda	return 0;
559f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda}
560f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takeda
561f7433243770c77979c396b4c7449a10e9b3521dbKentaro Takedasecurity_initcall(tomoyo_init);
562