static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) { struct dentry *lower_dentry; struct dentry *lower_dir_dentry; int rc; #ifdef CONFIG_SDP if(IS_CHAMBER_DENTRY(dentry)) { printk("You're removing chamber directory. I/O error\n"); return -EIO; } #endif lower_dentry = ecryptfs_dentry_to_lower(dentry); dget(dentry); lower_dir_dentry = lock_parent(lower_dentry); dget(lower_dentry); rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); dput(lower_dentry); if (!rc && dentry->d_inode) clear_nlink(dentry->d_inode); fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); set_nlink(dir, lower_dir_dentry->d_inode->i_nlink); unlock_dir(lower_dir_dentry); if (!rc) d_drop(dentry); dput(dentry); return rc; }
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_SDP if(IS_CHAMBER_DENTRY(old_dentry)) { printk("You're renaming chamber directory. I/O error\n"); return -EIO; } #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); 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); return rc; }
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; }