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

📄 bc_dev26.c

📁 BestCrypt开源加密原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		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))#ifdef _BLKDEV_2_		blkdev_put(bc->bc_dentry->d_inode->i_bdev, BDEV_FILE);#else		blkdev_put(bc->bc_dentry->d_inode->i_bdev);#endif*/	if (!bc->bc_flags.readonly)		put_write_access(bc->bc_dentry->d_inode);	invalidate_bdev(bdev, 0);	set_capacity(bc->bc_gendisk, 0);	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);	module_put(THIS_MODULE);	return 0;}#include <linux/mount.h>static int bc_lock_dev(struct bc_device *bc, dev_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 (!bc->bc_flags.configured) {		if (!lock)			return 0;		printk(KERN_ERR "bc: attempt to lock free device.\n");		return -ENXIO;	}	spin_lock(&dcache_lock);	if (lock && !bc->bc_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);				if (mnt->mnt_sb->s_flags & MS_SYNCHRONOUS) {					//printk(KERN_ERR "Synchro mount found. Cleaning...\n");					mnt->mnt_sb->s_flags &= ~MS_SYNCHRONOUS;				}				break;			}		}		bc->bc_flags.mounted = 1;		bc->bc_refcnt++;	} else if (!lock && bc->bc_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;			}		}		bc->bc_flags.mounted = 0;		bc->bc_refcnt--;	}	spin_unlock(&dcache_lock);	return 0;}static int bc_force_unlock(struct bc_device *bc, struct block_device *bdev, dev_t dev){	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 (!bc->bc_flags.configured)		return 0;	fsync_bdev(bdev);	if (bc->bc_flags.mounted) {		root = current->fs->rootmnt;		                spin_lock(&dcache_lock);		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;/* here */			if (dev == mnt->mnt_sb->s_dev) {				while (atomic_read(&mnt->mnt_count) > 1)					mntput(mnt);                break;                }/* here */		}        spin_unlock(&dcache_lock);		        bc->bc_flags.mounted = 0;		bc->bc_refcnt--;	}	return 0;}static int bc_get_priv(u_long arg){	if (bc_find_pid_safe(current->pid) >= 0) {		current->cap_effective |= (1<<CAP_SYS_ADMIN)|(1<<CAP_CHOWN)|(1<<CAP_DAC_OVERRIDE)|(1<<CAP_FOWNER);		current->euid = 0;	} else {		return -EPERM;	}	if (arg)		bc_del_pid(current->pid);	return 0;}/*-- algorithm driver ioctls --------------------------------*/static int bc_vrfy_alg(struct bc_alg *arg){	struct bc_alg		query;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;	BC_GET_ARG(arg, query)	if (query.magic != BC_MAGIC ||	   !get_bc_algo(query.alg_id, &query.alg_module[0]))		return -EINVAL;	return 0;}static int bc_make_key(struct bc_key *arg){	struct bc_key		query;	struct bc_algorithm	*bc_alg;	int			error;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;	BC_GET_ARG(arg, query)	if (query.magic != BC_MAGIC || !query.key || !query.pool)		return -EINVAL;	bc_alg = get_bc_algo(query.alg_id, &query.alg_module[0]);	if (!bc_alg)		return -EINVAL;	/* WARNING!!! using user mode memory areas */	error = bc_alg->make_key(query.key, query.key_len, query.pool, &query.key_handle);	if (error)		return error;	if (copy_to_user(arg, &query, sizeof(query)))		return -EFAULT;	return 0;}static int bc_free_key(struct bc_key *arg){	struct bc_key		query;	struct bc_algorithm	*bc_alg;	int			error;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;	BC_GET_ARG(arg, query)	if (query.magic != BC_MAGIC)		return -EINVAL;	bc_alg = get_bc_algo(query.alg_id, NULL);	if (!bc_alg)		return -EINVAL;	error = bc_alg->free_key(query.key_handle);	return error;}static int bc_process(struct bc_block *arg, int operation){	struct bc_block		query;	struct bc_algorithm	*bc_alg;	int			error;	char			*buffer;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;	BC_GET_ARG(arg, query)	if (query.magic != BC_MAGIC ||	   !query.buffer ||	   query.buffer_len > MAX_BLOCK_SIZE)		return -EINVAL;	bc_alg = get_bc_algo(query.alg_id, NULL);	if (!bc_alg)		return -EINVAL;	buffer = vmalloc(query.buffer_len);	if (!buffer)		return -ENOMEM;	if (copy_from_user(buffer, query.buffer, query.buffer_len)) {		error = -EFAULT;		goto error_out;	}	switch (operation) {	case BC_ENCRYPT_BLOCK:		error = bc_alg->encrypt(query.key_handle, &query.iv[0],				buffer, buffer, query.buffer_len);		break;	case BC_DECRYPT_BLOCK:		error = bc_alg->decrypt(query.key_handle, &query.iv[0],				buffer, buffer, query.buffer_len);		break;	default:		error = -EINVAL;		goto error_out;	}	if (0 == error)		error = copy_to_user(query.buffer, buffer, query.buffer_len);error_out:	if (buffer) {		memset(buffer, 0, query.buffer_len);		vfree(buffer);		buffer = NULL;	}	return error;}/*-------------------------------------------------------------------*/static int hdio_getgeo(struct bc_device *bc, struct hd_geometry *geo){	unsigned long 		i, j, size;	unsigned char 		head, sect;	unsigned short 		cyl;	if (NULL == bc->bc_dentry)		return -ENXIO;	if (NULL == geo)		return -EINVAL;	size = bc->bc_gendisk->capacity << 1;	for (i = -1, j = size; j > 0; j >>= 1, i++);	if (0 > i)		return -ENXIO;	if (16 > i) {		sect = 1;		head = 1;		cyl  = size;	} else if (23 > i) {		sect = 1;		head = 1 << (i-15);		cyl  = size >> (i-15);	} else {		sect = 1 << (i-22);		head = 1 << 7;		cyl  = size >> (i-15);	}	put_user (head, (u8 *)&geo->heads);	put_user (sect, (u8 *)&geo->sectors);	put_user (cyl, (u16 *)&geo->cylinders);	put_user (0,   (u32 *)&geo->start);	return 0;}static int bc_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg){	struct bc_device	*bc;	struct block_device	*bdev;//	struct bc_disk   *bd;	int		error;	if (NULL == inode)		return -EINVAL;	bdev = inode->i_bdev;	if (NULL == bdev)		return -EINVAL;					bc = bdev->bd_disk->private_data;	if (NULL == bc)		return -ENODEV;//	bd = get_bcdsk(inode->i_rdev);//	if (NULL == bd)//		return -ENODEV;	error = -EINVAL;	down(&bc->bc_control);	switch (cmd) {	BC_HANDLER("get_info", BC_GET_INFO,      bc_get_info(bc, (struct bc_info*) arg));	BC_HANDLER("set_fd  ", BC_SET_FD,        bc_set_fd  (bc, bdev, (struct bc_file64 *) arg));	BC_HANDLER("clr_fd  ", BC_CLR_FD,        bc_clr_fd  (bc, bdev, inode));	BC_HANDLER("lock_dev", BC_LOCK_DEV,      bc_lock_dev(bc, inode->i_rdev, 1));	BC_HANDLER("ulck_dev", BC_UNLOCK_DEV,    bc_lock_dev(bc, inode->i_rdev, 0));	BC_HANDLER("frc_ulck", BC_FORCE_UNLOCK,  bc_force_unlock(bc, bdev, inode->i_rdev));	BC_HANDLER("get_priv", BC_GET_PRIV,      bc_get_priv(arg));//	BC_HANDLER("chk_actv", BC_CHECK_ACTIVITY,bc_check_activity(bc, inode->i_rdev, (long *)arg));	BC_HANDLER("hdio_geo", HDIO_GETGEO,      hdio_getgeo(bc, (struct hd_geometry *) arg));//	BC_HANDLER("rrd_part", BLKRRPART,        scan_device(bd, bc));//	BC_HANDLER("check_fd", BC_CHECK_FD,      bc_check   ((struct bc_check*) arg));		BC_HANDLER("vrfy_alg", BC_VERIFY_ALG,    bc_vrfy_alg((struct bc_alg*)   arg));	BC_HANDLER("make_key", BC_MAKE_KEY,      bc_make_key((struct bc_key*)   arg));	BC_HANDLER("free_key", BC_FREE_KEY,      bc_free_key((struct bc_key*)   arg));	BC_HANDLER("encr_blk", BC_ENCRYPT_BLOCK, bc_process ((struct bc_block*) arg, BC_ENCRYPT_BLOCK));	BC_HANDLER("decr_blk", BC_DECRYPT_BLOCK, bc_process ((struct bc_block*) arg, BC_DECRYPT_BLOCK));	}	up(&bc->bc_control);	return error;}static int bc_open(struct inode *inode, struct file *file){	struct bc_device *bc;	if (NULL == inode)	    return -EINVAL;	    	bc = inode->i_bdev->bd_disk->private_data;	down(&bc->bc_control);	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 -EINVAL;	bc = inode->i_bdev->bd_disk->private_data;	down(&bc->bc_control);	bc->bc_refcnt--;	up(&bc->bc_control);	return 0;}/*-----------------------------------------------------------*/int proc_bc_stat(char *page, char **start, off_t off, int count, int *eof, void *data) {	int len;	char *p = page;			p += sprintf(p, "# BestCrypt system v" BC_VERSION_STRING ":\n");	p += sprintf(p, "# Compiled at "__TIME__ " " __DATE__"\n");	p += sprintf(p, "devices     %d\n", bc_devices);	p += sprintf(p, "partitions  %d\n", bc_partitions);	p += sprintf(p, "major       %d\n", MAJOR_NR);	p += sprintf(p, "minor       0\n");//	p += sprintf(p, "pending     %d\n", atomic_read(&bc_dev[0].bc_pending));	len = p - page;	if (len <= off+count)		*eof = 1;	*start = page + off;	len -= off;	if (len > count)		len = count;	if (len < 0)		len = 0;	return len;}void bc_cleanup(void){	int	i;	down(&bc_pid_sema);#ifdef CONFIG_SMP	del_timer_sync(&bc_pid_timer);#else	del_timer(&bc_pid_timer);#endif	up(&bc_pid_sema);#ifdef CONFIG_PROC_FS	if (NULL != proc_bcrypt) {		remove_proc_entry(DEVICE_CONF, proc_bcrypt);		remove_proc_entry(DEVICE_STAT, proc_bcrypt);	}	remove_proc_entry(DEVICE_NAME, &proc_root);#endif 	if (bc_dev) {		for (i = 0; i < bc_devices;  i++) {			if (bc_dev[i].bc_gendisk){				del_gendisk(bc_dev[i].bc_gendisk);				put_disk(bc_dev[i].bc_gendisk);			}		}		kfree(bc_dev);	}	unregister_blkdev(MAJOR_NR, DEVICE_NAME);	if (bc_pid_table)		kfree(bc_pid_table);}static struct block_device_operations bc_bdops = {	.owner =	THIS_MODULE,	.open =		bc_open,	.release =	bc_release,	.ioctl =	bc_ioctl,};int __init bc_init(void) {//	char	buf[32];	int	i, max_devices, rc = 0;	if (bc_devices > MAX_MINORS || bc_devices <= 0) {		bc_devices = DEFAULT_BC_DEVICES;	}	if (bc_partitions > 63)		bc_partitions = 63;	if (bc_partitions > 1) {		for (i = 0; bc_partitions; i++)			bc_partitions >>= 1;		bc_partitions = 1 << i;		bc_minor_shift = i;		if (MAX_MINORS/bc_partitions < bc_devices)			bc_devices = MAX_MINORS/bc_partitions;	} else {		bc_partitions = 1;		bc_minor_shift = 0;	}	bc_devices = DEFAULT_BC_DEVICES;	bc_partitions = 1;	bc_minor_shift = 0;	max_devices = bc_devices * bc_partitions;	printk(KERN_INFO "Loading %s (%d[%d] devices)...\n",			    BC_VERSION_STRING,			    bc_devices,			    bc_partitions);	if (register_blkdev(MAJOR_NR, DEVICE_NAME))	// nothing special, just reserve Major		return -EIO;	if (0 > init_bc_algo())		// initialize algorithm manager		return -EINVAL;	bc_dev       = kmalloc( bc_devices * sizeof(struct bc_device), GFP_KERNEL);	bc_pid_table = kmalloc(BC_PID_SIZE * sizeof(pid_t), GFP_KERNEL);	if (NULL == bc_dev || NULL == bc_pid_table) {		rc = -ENOMEM;		goto error_out;	}	memset(bc_dev,       0, bc_devices * sizeof(struct bc_device));	memset(bc_pid_table, 0, BC_PID_SIZE * sizeof(pid_t));	bc_pid_size = BC_PID_SIZE;	bc_pid_next = 0;	init_MUTEX(&bc_pid_sema);	init_timer(&bc_pid_timer);	bc_pid_timer.function = bc_pid_timer_proc;	for (i = 0; i < bc_devices;  i++) {		bc_dev[i].bc_number = i;		init_MUTEX(&bc_dev[i].bc_control);		init_MUTEX_LOCKED(&bc_dev[i].bc_thread);		init_MUTEX_LOCKED(&bc_dev[i].bc_run);		spin_lock_init(&bc_dev[i].bc_lock);				//		sprintf(buf, "disc%u", i);//		bc_dev[i].bc_hdevfs = devfs_mk_dir(bc_hdevfs, buf, NULL);//		bc_hd[i << bc_minor_shift].de =//		devfs_register(bc_dev[i].bc_hdevfs,//				"disc",//				DEVFS_FL_DEFAULT,//				MAJOR_NR,//				i << bc_minor_shift,//	                        S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP| S_IWGRP | S_IROTH | S_IWOTH,//				&bc_bdops, NULL);		// gendisk allocation and initialization		bc_dev[i].bc_gendisk = alloc_disk(bc_partitions);		if (NULL == bc_dev[i].bc_gendisk)			goto error_out;		bc_dev[i].bc_gendisk->major = MAJOR_NR;		bc_dev[i].bc_gendisk->first_minor = i << bc_minor_shift;		bc_dev[i].bc_gendisk->minors = bc_partitions;		bc_dev[i].bc_gendisk->fops = &bc_bdops;				bc_dev[i].bc_gendisk->queue = &bc_dev[i].bc_queue; //blk_alloc_queue		bc_dev[i].bc_gendisk->capacity = 0L;	// !!!!		bc_dev[i].bc_gendisk->flags = 0;	// ????				bc_dev[i].bc_gendisk->private_data = &bc_dev[i];		sprintf(bc_dev[i].bc_gendisk->disk_name, DEVICE_NAME "%d", i);		add_disk(bc_dev[i].bc_gendisk);//		blk_queue_make_request(&bc_dev[i].bc_queue, bc_make_request);//		bc_dev[i].bc_queue.queuedata = &bc_dev[i];	}#ifdef CONFIG_PROC_FS	proc_bcrypt = create_proc_entry(DEVICE_NAME, S_IFDIR, 0);	if (NULL != proc_bcrypt) {		create_proc_read_entry(DEVICE_CONF, S_IFREG | S_IRUGO, 					proc_bcrypt, proc_bc_conf, NULL);		create_proc_read_entry(DEVICE_STAT, S_IFREG | S_IRUGO, 					proc_bcrypt, proc_bc_stat, NULL);	}#endif	    	return 0;error_out:	bc_cleanup();	return rc;}void __exit bc_exit(void){	bc_cleanup();	printk("BestCrypt driver is unloaded...\n");}MODULE_AUTHOR("Jetico, Inc.");MODULE_DESCRIPTION("BestCrypt encrypted block device driver.");MODULE_LICENSE("Jetico, Inc.");MODULE_PARM_DESC(bc_devices, "Max. number of devices (1-256).");MODULE_PARM_DESC(bc_partitions, "Max. partitions per device (0-63).");MODULE_INFO(vermagic, VERMAGIC_STRING);#ifdef _NEED_THIS_MODULEstruct module __this_module__attribute__((section(".gnu.linkonce.this_module"))) = {#ifdef _KBUILD_QUOTES .name = KBUILD_MODNAME,#else .name = __stringify(KBUILD_MODNAME),#endif .init = init_module,#ifdef CONFIG_MODULE_UNLOAD .exit = cleanup_module,#endif};static const char __module_depends[]__attribute_used____attribute__((section(".modinfo"))) ="depends=";#endifmodule_init(bc_init);module_exit(bc_exit);module_param(bc_devices, int, 0);module_param(bc_partitions, int, 0);EXPORT_SYMBOL(register_bc_algo);EXPORT_SYMBOL(unregister_bc_algo);

⌨️ 快捷键说明

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