⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bc_dev24.c

📁 加密解密,安全工具!很有意思的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			MAJOR(inode->i_rdev),			MINOR(inode->i_rdev));		MOD_DEC_USE_COUNT;		return -ENODEV;	}	while (1) {		down(&bc->bc_control);		if (!bc->bc_flags.busy)			break;		up(&bc->bc_control);		sleep_on(&wait_open);	}	bc->bc_refcnt++;	up(&bc->bc_control);	if (capable(CAP_SYS_ADMIN)) {		bc_add_pid(current->pid);		}	return 0;}static int bc_release(struct inode *inode, struct file *file){	struct bc_device *bc;	if (NULL == inode)		return 0;	bc = get_bcdev(inode->i_rdev);	if (NULL == bc)		return 0;/*	fsync() is not required here. It should	be called before by upper level. Moreover,	fsync() here leads to ReiserFS hangup on 	umount. 			error = fsync_dev(inode->i_rdev);*/	down(&bc->bc_control);	if (0 >= bc->bc_refcnt)		printk(KERN_WARNING "bc_release: refcount (%d) <= 0\n", bc->bc_refcnt);	else  {		bc->bc_refcnt--;		MOD_DEC_USE_COUNT;	}	up(&bc->bc_control);	return 0;}static ssize_t bc_read (struct file *file, char *buf, size_t count, loff_t *ppos){	struct bc_disk		*bd;	struct bc_device	*bc;	struct inode		*inode;	if (NULL == file)		return -EINVAL;	inode = file->f_dentry->d_inode;	if (NULL == inode)		return -EIO;			bd = get_bcdsk(inode->i_rdev);	if (NULL == bd)		return -ENODEV;	bc = get_bcdev(inode->i_rdev);	if (NULL == bc)		return -ENODEV;	if (!bd->bd_flags.configured || bd->bd_flags.mounted)		return -EIO;	if (bc->bc_save_fops && bc->bc_save_fops->read)		return bc->bc_save_fops->read(file, buf, count, ppos);	else		return -EPERM;}static ssize_t bc_write(struct file *file, const char *buf, size_t count, loff_t *ppos){	struct bc_disk		*bd;	struct bc_device	*bc;	struct inode		*inode;	if (NULL == file)		return -EINVAL;	inode = file->f_dentry->d_inode;	if (NULL == inode)		return -EIO;			bd = get_bcdsk(inode->i_rdev);	if (NULL == bd)		return -ENODEV;	bc = get_bcdev(inode->i_rdev);	if (NULL == bc)		return -ENODEV;	if (!bd->bd_flags.configured || bd->bd_flags.mounted)		return -EIO;	if (bc->bc_save_fops && bc->bc_save_fops->write)		return bc->bc_save_fops->write(file, buf, count, ppos);	else		return -EPERM;}/*-- end of fops functions ----------------------------------*/static int bc_get_info(struct bc_disk *bd, struct bc_device *bc, struct bc_info *arg){	struct bc_info	query;	long		busy;	BC_GET_ARG(arg, query)	put_user(BC_VERSION_MAJOR, (long *)&arg->ver_major);	put_user(BC_VERSION_MINOR, (long *)&arg->ver_minor);	busy = bd->bd_flags.configured || bc->bc_refcnt > 1 ? 1 : 0;	put_user(busy, (long *)&arg->busy);	return 0;}static int bc_check(struct bc_check *arg){	struct bc_check	 query;	struct file	 *file;	int              i, max_devices;	BC_GET_ARG(arg, query)	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;			if (!(file = fget(query.fd)))		return -EBADF;	max_devices = bc_devices * bc_partitions;	for (i = 0; i < max_devices; i++) {		if (!bc_dsk[i].bd_flags.configured)			continue;		if (file == bc_dev[i>>bc_minor_shift].bc_file)			break;	}	if (max_devices == i)		i = BC_CONTAINER_UNUSED;	else if (bc_dsk[i].bd_flags.mounted)		i = BC_CONTAINER_MOUNTED;	else		i = BC_CONTAINER_USED;	put_user(i, (long *)&arg->busy);	return 0;}#define MAX_DISK_SIZE 1024*1024*1024static int scan_device(struct bc_disk *bd, struct bc_device *bc){	int			i, part, size;	kdev_t			dev;	struct super_block	*sb = NULL;	if (!is_parent(bd))		return -EPERM;	if (NULL == bc->bc_dentry)		return -ENXIO;			if (bc->bc_refcnt > 1)		return -EBUSY;	bc->bc_flags.busy = 1;	if (S_ISREG(bc->bc_dentry->d_inode->i_mode)) {		size = (bc->bc_dentry->d_inode->i_size - bc->bc_offset) >> BLOCK_SIZE_BITS;	} else {		size = MAX_DISK_SIZE;		dev = bc->bc_dev;		if (blk_size[MAJOR(dev)]) {			size =  blk_size[MAJOR(dev)][MINOR(dev)];			size -= (bc->bc_offset >> BLOCK_SIZE_BITS);		}	}	bc_sizes[bd->bd_number] = size;	bd->bd_offset = bc->bc_offset; 	if (!bc->bc_flags.multpart || !bc_minor_shift) { /* skip partitions */		bd->bd_flags.configured = 1;		bc->bc_flags.busy = 0;		wake_up(&wait_open);		return 0;	}		for (i = bc_gendisk.max_p - 1; i >= 0; i--) {		part = bd->bd_number + i;		dev = MKDEV(MAJOR_NR, part);		sb = get_super(dev);		sync_dev(dev);		if (sb)			invalidate_inodes(sb);		invalidate_buffers(dev);				bc_gendisk.part[part].start_sect = 0;		bc_gendisk.part[part].nr_sects = 0;		bc_dsk[part].bd_flags.configured = 0;		bc_dsk[part].bd_offset = bc->bc_offset; 	};	bc_gendisk.part[bd->bd_number].nr_sects = size << 1;		grok_partitions(&bc_gendisk, bc->bc_number, bc_gendisk.max_p, size << 1);	for (i = bc_gendisk.max_p - 1; i >= 0; i--) {		part = bd->bd_number + i;		if (0 < bc_gendisk.part[part].nr_sects) {			bc_dsk[part].bd_flags.configured = 1;			bc_dsk[part].bd_offset = bc->bc_offset + 		        (((loff_t)bc_gendisk.part[part].start_sect) << 9);		} 	}	bc->bc_flags.busy = 0;	wake_up(&wait_open);	return 0;}static int bc_set_fd(struct bc_disk *bd, struct bc_device *bc, kdev_t dev, struct inode *dev_inode, struct bc_file64 *arg)/* key must be ready */{	struct file		*file = NULL;	struct inode		*inode = NULL;	struct bc_algorithm	*bc_alg = NULL;	struct bc_file64	query;	int 			error;/*	struct list_head	*ptr;	struct file		*other;*/	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;	MOD_INC_USE_COUNT;	BC_GET_ARG(arg, query)	if (!is_parent(bd)) {		error = -EPERM;		goto error_out;	}	if (bc->bc_dentry) {		error = -EBUSY;		goto error_out;	}	bc_alg = get_bc_algo(query.alg_id, NULL);	if (NULL == bc_alg || bc_alg->test_key(query.key_handle) != 0) {		error = -EINVAL;		goto error_out;	}	if (!(file = fget(query.fd))) {		error = -EBADF;		goto error_out;	}	inode = file->f_dentry->d_inode;/*	list_for_each(ptr, &file->f_list) {		other = list_entry(ptr, struct file, f_list);		if (other && other->f_dentry)			if (inode == other->f_dentry->d_inode)				printk("file busy pid=%d\n", other->f_owner.pid);	}*/		error = -EINVAL;	if (!inode) {		printk(KERN_ERR "bc_set_fd: NULL inode.\n");		goto error_out;	}	if (!file->f_op) {		printk(KERN_ERR "bc_set_fd: NULL file_operations.\n");		goto error_out;	}	if (!file->f_op->read) {		printk(KERN_ERR "bc_set_fd: Can't perform reads.\n");		goto error_out;	}		reset_dev(bc);	if (S_ISBLK(inode->i_mode)) {		error = blkdev_open(inode, file);		if (error)			goto error_out;		bc->bc_dev   = inode->i_rdev;	} else if (S_ISREG(inode->i_mode)) {		bc->bc_dev   = inode->i_dev;	} else		goto error_out;	bc->bc_flags.iv_64bit = query.flags & BC_FLAGS_IV_64BIT || 0;	bc->bc_flags.multpart = query.flags & BC_FLAGS_MULTPART || 0;	bc->bc_flags.readonly = IS_RDONLY(inode) || 				is_read_only(bc->bc_dev) || 				(NULL == file->f_op->write) || 				query.flags & BC_FLAGS_READONLY;	if (!bc->bc_flags.readonly) {		error = get_write_access(inode);		if (error) {			printk (KERN_ERR "bc_set_fd: Can't get write access.\n"); 		        goto error_out;		}		invalidate_inode_pages (inode);	}	set_device_ro(dev, bc->bc_flags.readonly);	if (NULL != dev_inode->i_fop) {		bc->bc_save_fops = dev_inode->i_fop;		memcpy(&(bc->bc_fops), dev_inode->i_fop, sizeof(bc->bc_fops));		bc->bc_fops.read  = bc_read;		bc->bc_fops.write = bc_write;		dev_inode->i_fop  = &(bc->bc_fops);	}	bc->bc_buffer   = vmalloc(BC_BUFFER_SIZE);	if (NULL == bc->bc_buffer)		goto error_out;			bc->bc_key	= query.key_handle;	bc->bc_alg	= bc_alg;	bc->bc_file	= file;	bc->bc_dentry	= dget(file->f_dentry);	bc->bc_offset   = (loff_t)query.offset;	bc->bc_start_sector   = (loff_t)query.start_sector;	bc->bc_num_sectors    = (loff_t)query.num_sectors;	bc_alg->lock_key(query.key_handle, 1);	bc->bc_gfpmask = bc->bc_dentry->d_inode->i_mapping->gfp_mask;	bc->bc_dentry->d_inode->i_mapping->gfp_mask = GFP_NOIO;	kernel_thread(bc_thread, bc, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);	down(&bc->bc_thread);	scan_device(bd, bc);	return 0;error_out:	if (file)		fput(file);	MOD_DEC_USE_COUNT;	return error;}static int errno;static int bc_clr_fd(struct bc_disk *bd, struct bc_device *bc, kdev_t dev, struct inode *dev_inode){	int		i, n, minor;	devfs_handle_t	hdevfs;	size_t		   ret;	loff_t		   pos;	unsigned char      magic;	mm_segment_t	   fs;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;		if (!is_parent(bd))		return -EPERM;	if (NULL == bc->bc_dentry)		return -ENXIO;	if (NULL == bc->bc_file)		return -ENXIO;	if (bc->bc_refcnt > 1)		return -EBUSY;	spin_lock_irq(&bc->bc_lock);		if (atomic_dec_and_test(&bc->bc_pending))		up(&bc->bc_run);	bc->bc_flags.active = 0;	spin_unlock_irq(&bc->bc_lock);		down(&bc->bc_thread);	waitpid(-1, NULL, __WCLONE|WNOHANG);	bc->bc_dentry->d_inode->i_mapping->gfp_mask = bc->bc_gfpmask;	n = 1 << bc_minor_shift;	for (i = 0; i < n; i++) {		minor = bc->bc_number*n+i;		sync_dev(MKDEV(MAJOR_NR, minor));		invalidate_buffers(MKDEV(MAJOR_NR, minor));		while (i) {			hdevfs = devfs_find_handle(bc->bc_hdevfs, NULL, 						MAJOR_NR, minor,						DEVFS_SPECIAL_BLK, 0);			if (NULL == hdevfs) {				bc_hd[minor].de = 0;				break;			}			if (hdevfs != bc->bc_hdevfs)				devfs_unregister(hdevfs);		}		bc_sizes[minor] = 0;	}	if (bc->bc_save_fops) {		dev_inode->i_fop = bc->bc_save_fops;	}	if (!bc->bc_flags.readonly && bc->bc_offset) {		pos = 0;		magic = 0xEB;		fs = get_fs();		set_fs(KERNEL_DS);		ret = bc->bc_file->f_op->write(bc->bc_file, &magic, 1, &pos);		set_fs(fs);		if (ret != 1)			printk(KERN_ERR "bc: error %ld writing magic\n", 			(unsigned long)ret);	}	if (S_ISBLK(bc->bc_dentry->d_inode->i_mode))		blkdev_put(bc->bc_dentry->d_inode->i_bdev, BDEV_FILE);	if (!bc->bc_flags.readonly)		put_write_access(bc->bc_dentry->d_inode);			dput(bc->bc_dentry);	fput(bc->bc_file);	//	bc->bc_alg->lock_key(bc->bc_key, 0);			bc->bc_alg->free_key(bc->bc_key);			reset_dev(bc);			MOD_DEC_USE_COUNT;    	return 0;}static int bc_lock_dev(struct bc_disk *bd, struct bc_device *bc, kdev_t dev, int lock){	struct vfsmount    *mnt, *root;	struct list_head   *ptr;		if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;//	if (!capable(CAP_SYS_ADMIN))//		return -EPERM;	if (!bd->bd_flags.configured) {		if (!lock)			return 0;		printk(KERN_ERR "bc: attempt to lock free device.\n");		return -ENXIO;	}	spin_lock(&dcache_lock);	if (lock && !bd->bd_flags.mounted) {		root = current->fs->rootmnt;				list_for_each(ptr, &root->mnt_list) {			mnt = list_entry(ptr, struct vfsmount, mnt_list);			if (NULL == mnt ||			    NULL == mnt->mnt_sb ||			    NULL == mnt->mnt_root ||			    NULL == mnt->mnt_devname)				continue;			if (dev == mnt->mnt_sb->s_dev) {				mntget(mnt);				break;				}		}		bd->bd_flags.mounted = 1;		bc->bc_refcnt++;	} else if (!lock && bd->bd_flags.mounted) {		root = current->fs->rootmnt;				list_for_each(ptr, &root->mnt_list) {			mnt = list_entry(ptr, struct vfsmount, mnt_list);			if (NULL == mnt ||			    NULL == mnt->mnt_sb ||			    NULL == mnt->mnt_root ||			    NULL == mnt->mnt_devname)				continue;			if (dev == mnt->mnt_sb->s_dev) {				mntput(mnt);				break;			}		}		bd->bd_flags.mounted = 0;		bc->bc_refcnt--;	}	spin_unlock(&dcache_lock);	return 0;}static int bc_force_unlock(struct bc_disk *bd, struct bc_device *bc, kdev_t dev){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -