コード例 #1
0
/**
 * ecryptfs_interpose
 * @lower_dentry: Existing dentry in the lower filesystem
 * @dentry: ecryptfs' dentry
 * @sb: ecryptfs's super_block
 *
 * Interposes upper and lower dentries.
 *
 * Returns zero on success; non-zero otherwise
 */
static int ecryptfs_interpose(struct dentry *lower_dentry,
			      struct dentry *dentry, struct super_block *sb)
{
	struct inode *inode = ecryptfs_get_inode(lower_dentry->d_inode, sb);

	if (IS_ERR(inode))
		return PTR_ERR(inode);

	d_instantiate(dentry, inode);
	if(d_unhashed(dentry))
		d_rehash(dentry);

#ifdef CONFIG_SDP
	if(S_ISDIR(inode->i_mode) && dentry) {
		if(IS_UNDER_ROOT(dentry)) {
			struct ecryptfs_mount_crypt_stat *mount_crypt_stat  =
					&ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
			int engineid;
			printk("Creating a directoy under root directory of current partition.\n");

			if(is_chamber_directory(mount_crypt_stat, dentry->d_name.name, &engineid)) {
				printk("This is a chamber directory engine[%d]\n", engineid);
				set_chamber_flag(engineid, inode);
			}
		} else if(IS_SENSITIVE_DENTRY(dentry->d_parent)) {
			/*
			 * When parent directory is sensitive
			 */
			struct ecryptfs_crypt_stat *crypt_stat =
					&ecryptfs_inode_to_private(inode)->crypt_stat;
			struct ecryptfs_crypt_stat *parent_crypt_stat =
					&ecryptfs_inode_to_private(dentry->d_parent->d_inode)->crypt_stat;

			//TODO : remove this log
			DEK_LOGE("Parent %s[id:%d] is sensitive. so this directory is sensitive too\n",
					dentry->d_parent->d_name.name, parent_crypt_stat->engine_id);
			crypt_stat->flags |= ECRYPTFS_DEK_IS_SENSITIVE;
			crypt_stat->engine_id = parent_crypt_stat->engine_id;
		}
	}
#endif

	return 0;
}
コード例 #2
0
ファイル: inode.c プロジェクト: sawdoctor/Googy-Max-N4-Kernel
/**
 * ecryptfs_interpose
 * @lower_dentry: Existing dentry in the lower filesystem
 * @dentry: ecryptfs' dentry
 * @sb: ecryptfs's super_block
 *
 * Interposes upper and lower dentries.
 *
 * Returns zero on success; non-zero otherwise
 */
static int ecryptfs_interpose(struct dentry *lower_dentry,
			      struct dentry *dentry, struct super_block *sb)
{
	struct inode *inode = ecryptfs_get_inode(lower_dentry->d_inode, sb);

	if (IS_ERR(inode))
		return PTR_ERR(inode);
	d_instantiate(dentry, inode);

#ifdef CONFIG_SDP
	if(S_ISDIR(inode->i_mode) && dentry) {
	    if(IS_UNDER_ROOT(dentry)) {
	        struct ecryptfs_mount_crypt_stat *mount_crypt_stat  =
	                &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
	        printk("Creating a directoy under root directory of current partition.\n");

	        if(is_chamber_directory(mount_crypt_stat, (char *)dentry->d_name.name)) {
	            printk("This is a chamber directory\n");
	            set_chamber_flag(inode);
	        }
	    } else if(IS_SENSITIVE_DENTRY(dentry->d_parent)) {
	        /*
	         * When parent directory is sensitive
	         */
	        struct ecryptfs_crypt_stat *crypt_stat =
	                &ecryptfs_inode_to_private(inode)->crypt_stat;

	        printk("Parent %s is sensitive. so this directory is sensitive too\n",
	                dentry->d_parent->d_name.name);
	        crypt_stat->flags |= ECRYPTFS_DEK_IS_SENSITIVE;
	    }
	}
#endif

	return 0;
}
コード例 #3
0
ファイル: inode.c プロジェクト: sawdoctor/Googy-Max-N4-Kernel
/**
 * ecryptfs_lookup_interpose - Dentry interposition for a lookup
 */
static int ecryptfs_lookup_interpose(struct dentry *dentry,
				     struct dentry *lower_dentry,
				     struct inode *dir_inode)
{
	struct inode *inode, *lower_inode = lower_dentry->d_inode;
	struct ecryptfs_dentry_info *dentry_info;
	struct vfsmount *lower_mnt;
	int rc = 0;

	dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL);
	if (!dentry_info) {
		printk(KERN_ERR "%s: Out of memory whilst attempting "
		       "to allocate ecryptfs_dentry_info struct\n",
			__func__);
		dput(lower_dentry);
		return -ENOMEM;
	}

	lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
	fsstack_copy_attr_atime(dir_inode, lower_dentry->d_parent->d_inode);
	BUG_ON(!lower_dentry->d_count);

	ecryptfs_set_dentry_private(dentry, dentry_info);
	ecryptfs_set_dentry_lower(dentry, lower_dentry);
	ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt);

	if (!lower_dentry->d_inode) {
		/* We want to add because we couldn't find in lower */
		d_add(dentry, NULL);
		return 0;
	}
	inode = __ecryptfs_get_inode(lower_inode, dir_inode->i_sb);
	if (IS_ERR(inode)) {
		printk(KERN_ERR "%s: Error interposing; rc = [%ld]\n",
		       __func__, PTR_ERR(inode));
		return PTR_ERR(inode);
	}
	if (S_ISREG(inode->i_mode)) {
		rc = ecryptfs_i_size_read(dentry, inode);
		if (rc) {
			make_bad_inode(inode);
			return rc;
		}
	}

#ifdef CONFIG_SDP
	if (S_ISDIR(inode->i_mode) && dentry) {
	    if(IS_UNDER_ROOT(dentry)) {
	        struct ecryptfs_mount_crypt_stat *mount_crypt_stat  =
	                &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
	        printk("Lookup a directoy under root directory of current partition.\n");

	        if(is_chamber_directory(mount_crypt_stat, (char *)dentry->d_name.name)) {
	            /*
	             * When this directory is under ROOT directory and the name is registered
	             * as Chamber.
	             */
	            printk("This is a chamber directory\n");
	            set_chamber_flag(inode);
	        }
	    } else if(IS_SENSITIVE_DENTRY(dentry->d_parent)) {
	        /*
	         * When parent directory is sensitive
	         */
	        struct ecryptfs_crypt_stat *crypt_stat =
	                &ecryptfs_inode_to_private(inode)->crypt_stat;

	        printk("Parent %s is sensitive. so this directory is sensitive too\n",
	                dentry->d_parent->d_name.name);
	        crypt_stat->flags |= ECRYPTFS_DEK_IS_SENSITIVE;
	    }
	}
#endif

	if (inode->i_state & I_NEW)
		unlock_new_inode(inode);
	d_add(dentry, inode);

	return rc;
}
コード例 #4
0
static int
ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
		struct inode *new_dir, struct dentry *new_dentry)
{
	int rc;
	struct dentry *lower_old_dentry;
	struct dentry *lower_new_dentry;
	struct dentry *lower_old_dir_dentry;
	struct dentry *lower_new_dir_dentry;
	struct dentry *trap = NULL;
	struct inode *target_inode;
#ifdef CONFIG_DLP
	sdp_fs_command_t *cmd1 = NULL;
	unsigned long old_inode = old_dentry->d_inode->i_ino;
#endif
#ifdef CONFIG_SDP
	sdp_fs_command_t *cmd = NULL;
	int rename_event = 0x00;
	struct ecryptfs_crypt_stat *crypt_stat =
			&(ecryptfs_inode_to_private(old_dentry->d_inode)->crypt_stat);
	struct ecryptfs_crypt_stat *parent_crypt_stat =
	        &(ecryptfs_inode_to_private(old_dentry->d_parent->d_inode)->crypt_stat);
	struct ecryptfs_crypt_stat *new_parent_crypt_stat =
	        &(ecryptfs_inode_to_private(new_dentry->d_parent->d_inode)->crypt_stat);
	struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
			&ecryptfs_superblock_to_private(old_dentry->d_sb)->mount_crypt_stat;

#if ECRYPTFS_SDP_RENAME_DEBUG
	printk("You're renaming %s to %s\n",
			old_dentry->d_name.name,
			new_dentry->d_name.name);
	printk("old_dentry[%p] : %s [parent %s : %s] inode:%p\n",
			old_dentry, old_dentry->d_name.name,
			old_dentry->d_parent->d_name.name,
			IS_SENSITIVE_DENTRY(old_dentry->d_parent) ? "sensitive" : "protected",
					old_dentry->d_inode);
	printk("new_dentry[%p] : %s [parent %s : %s] inode:%p\n",
			new_dentry, new_dentry->d_name.name,
			new_dentry->d_parent->d_name.name,
			IS_SENSITIVE_DENTRY(new_dentry->d_parent) ? "sensitive" : "protected",
					new_dentry->d_inode);
#endif

	if(IS_CHAMBER_DENTRY(old_dentry)) {
		printk("Rename trial on chamber : failed\n");
		return -EIO;
	}

#if 0 // kernel panic. new_crypt_stat->engine_id
	if(IS_SENSITIVE_DENTRY(old_dentry->d_parent) &&
			IS_SENSITIVE_DENTRY(new_dentry->d_parent)) {
		if(crypt_stat->engine_id != new_crypt_stat->engine_id) {
			printk("Rename chamber file to another chamber : failed\n");
			return -EIO;
		}
	}
#endif

	if(IS_SENSITIVE_DENTRY(old_dentry->d_parent)) {
	    if(ecryptfs_is_sdp_locked(parent_crypt_stat->engine_id)) {
			printk("Rename/move trial in locked state\n");
			return -EIO;
		}
	}

	if(IS_SENSITIVE_DENTRY(old_dentry->d_parent) &&
			IS_SENSITIVE_DENTRY(new_dentry->d_parent)) {
		if(parent_crypt_stat->engine_id != new_parent_crypt_stat->engine_id) {
	        printk("Can't move between chambers\n");
			return -EIO;
		}
	}

	if(IS_SENSITIVE_DENTRY(old_dentry->d_parent) &&
			!IS_SENSITIVE_DENTRY(new_dentry->d_parent))		
		rename_event |= ECRYPTFS_EVT_RENAME_OUT_OF_CHAMBER;

	if(!IS_SENSITIVE_DENTRY(old_dentry->d_parent) &&
			IS_SENSITIVE_DENTRY(new_dentry->d_parent))
		rename_event |= ECRYPTFS_EVT_RENAME_TO_CHAMBER;
#endif

	lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
	lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
	dget(lower_old_dentry);
	dget(lower_new_dentry);
	lower_old_dir_dentry = dget_parent(lower_old_dentry);
	lower_new_dir_dentry = dget_parent(lower_new_dentry);
	target_inode = new_dentry->d_inode;
	trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
	/* source should not be ancestor of target */
	if (trap == lower_old_dentry) {
		rc = -EINVAL;
		goto out_lock;
	}
	/* target should not be ancestor of source */
	if (trap == lower_new_dentry) {
		rc = -ENOTEMPTY;
		goto out_lock;
	}
	rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
			lower_new_dir_dentry->d_inode, lower_new_dentry);
	if (rc)
		goto out_lock;
	if (target_inode)
		fsstack_copy_attr_all(target_inode,
				      ecryptfs_inode_to_lower(target_inode));
	fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
	if (new_dir != old_dir)
		fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);

#ifdef CONFIG_SDP
	if(!rc) {
		crypt_stat = &(ecryptfs_inode_to_private(old_dentry->d_inode)->crypt_stat);

		if(rename_event > 0) {
			switch(rename_event) {
			case ECRYPTFS_EVT_RENAME_TO_CHAMBER:
                cmd = sdp_fs_command_alloc(FSOP_SDP_SET_SENSITIVE, current->pid,
                		mount_crypt_stat->userid, mount_crypt_stat->partition_id,
                        old_dentry->d_inode->i_ino,
                        GFP_NOFS);
				break;
			case ECRYPTFS_EVT_RENAME_OUT_OF_CHAMBER:
                cmd = sdp_fs_command_alloc(FSOP_SDP_SET_PROTECTED, current->pid,
                		mount_crypt_stat->userid, mount_crypt_stat->partition_id,
                        old_dentry->d_inode->i_ino,
                        GFP_NOFS);
				break;
			default:
                cmd = NULL;
				break;
			}
		}
#if ECRYPTFS_SDP_RENAME_DEBUG
		printk("[end of rename] old_dentry[%p] : %s [parent %s : %s] inode:%p\n",
				old_dentry, old_dentry->d_name.name,
				old_dentry->d_parent->d_name.name,
				IS_SENSITIVE_DENTRY(old_dentry->d_parent) ? "sensitive" : "protected",
						old_dentry->d_inode);
		printk("[end of rename] new_dentry[%p] : %s [parent %s : %s] inode:%p\n",
				new_dentry, new_dentry->d_name.name,
				new_dentry->d_parent->d_name.name,
				IS_SENSITIVE_DENTRY(new_dentry->d_parent) ? "sensitive" : "protected",
						new_dentry->d_inode);
#endif

    }
#endif

out_lock:
	unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
	dput(lower_new_dir_dentry);
	dput(lower_old_dir_dentry);
	dput(lower_new_dentry);
	dput(lower_old_dentry);

#ifdef CONFIG_SDP
	if(!rc && cmd != NULL) {
	    sdp_fs_request(cmd, ecryptfs_fs_request_callback);
	    sdp_fs_command_free(cmd);
	}
#endif

#ifdef CONFIG_DLP
	//create new init command and send--Handle transient case MS-Apps
	if(crypt_stat->flags & ECRYPTFS_DLP_ENABLED) {
		if(!rc && (in_egroup_p(AID_KNOX_DLP) || in_egroup_p(AID_KNOX_DLP_RESTRICTED))){
            cmd1 = sdp_fs_command_alloc(FSOP_DLP_FILE_RENAME,
						current->tgid, mount_crypt_stat->userid, mount_crypt_stat->partition_id,
						old_inode, GFP_KERNEL);
            //send cmd
			if(cmd1) {
                sdp_fs_request(cmd1, NULL);
                sdp_fs_command_free(cmd1);
			}
		}
	}
    //end- Handle transient case MS-Apps
#endif
	return rc;
}