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

📄 sys_parisc32.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
asmlinkage long sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim){	struct rlimit32 rlim32;	struct rlimit new_rlim, *old_rlim;	if (resource >= RLIM_NLIMITS)		return -EINVAL;	if (copy_from_user(&rlim32, rlim, sizeof(rlim)))		return -EFAULT;	if (rlim32.rlim_cur == RLIM32_INFINITY) {		new_rlim.rlim_cur = RLIM_INFINITY;	} else {		new_rlim.rlim_cur = rlim32.rlim_cur;	}	if (rlim32.rlim_max == RLIM32_INFINITY) {		new_rlim.rlim_max = RLIM_INFINITY;	} else {		new_rlim.rlim_max = rlim32.rlim_max;	}	old_rlim = current->rlim + resource;	if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||	     (new_rlim.rlim_max > old_rlim->rlim_max)) &&	    !capable(CAP_SYS_RESOURCE))		return -EPERM;	if (resource == RLIMIT_NOFILE) {		if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)			return -EPERM;	}	if (resource == RLIMIT_STACK) {		if (new_rlim.rlim_max > 1024 * 1024 * 1024) {			new_rlim.rlim_max = 1024 * 1024 * 1024;		}		new_rlim.rlim_max = PAGE_ALIGN(new_rlim.rlim_max);	}		*old_rlim = new_rlim;	return 0;}static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel){	int i;	unsigned long page;	struct vm_area_struct *vma;	*kernel = 0;	if(!user)		return 0;	vma = find_vma(current->mm, (unsigned long)user);	if(!vma || (unsigned long)user < vma->vm_start)		return -EFAULT;	if(!(vma->vm_flags & VM_READ))		return -EFAULT;	i = vma->vm_end - (unsigned long) user;	if(PAGE_SIZE <= (unsigned long) i)		i = PAGE_SIZE - 1;	if(!(page = __get_free_page(GFP_KERNEL)))		return -ENOMEM;	if(copy_from_user((void *) page, user, i)) {		free_page(page);		return -EFAULT;	}	*kernel = page;	return 0;}#define SMBFS_NAME	"smbfs"#define NCPFS_NAME	"ncpfs"asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data){	unsigned long type_page = 0;	unsigned long data_page = 0;	unsigned long dev_page = 0;	unsigned long dir_page = 0;	int err, is_smb, is_ncp;	is_smb = is_ncp = 0;	err = copy_mount_stuff_to_kernel((const void *)type, &type_page);	if (err)		goto out;	if (!type_page) {		err = -EINVAL;		goto out;	}	is_smb = !strcmp((char *)type_page, SMBFS_NAME);	is_ncp = !strcmp((char *)type_page, NCPFS_NAME);	err = copy_mount_stuff_to_kernel((const void *)(unsigned long)data, &data_page);	if (err)		goto type_out;	err = copy_mount_stuff_to_kernel(dev_name, &dev_page);	if (err)		goto data_out;	err = copy_mount_stuff_to_kernel(dir_name, &dir_page);	if (err)		goto dev_out;	if (!is_smb && !is_ncp) {		lock_kernel();		err = do_mount((char*)dev_page, (char*)dir_page,				(char*)type_page, new_flags, (char*)data_page);		unlock_kernel();	} else {		if (is_ncp)			panic("NCP mounts not yet supported 32/64 parisc");			/* do_ncp_super_data_conv((void *)data_page); */		else {			panic("SMB mounts not yet supported 32/64 parisc");			/* do_smb_super_data_conv((void *)data_page); */		}		lock_kernel();		err = do_mount((char*)dev_page, (char*)dir_page,				(char*)type_page, new_flags, (char*)data_page);		unlock_kernel();	}	free_page(dir_page);dev_out:	free_page(dev_page);data_out:	free_page(data_page);type_out:	free_page(type_page);out:	return err;}#ifdef CONFIG_MODULESstruct module_info32 {	u32 addr;	u32 size;	u32 flags;	s32 usecount;};/* Query various bits about modules.  */static inline longget_mod_name(const char *user_name, char **buf){	unsigned long page;	long retval;	if ((unsigned long)user_name >= TASK_SIZE	    && !segment_eq(get_fs (), KERNEL_DS))		return -EFAULT;	page = __get_free_page(GFP_KERNEL);	if (!page)		return -ENOMEM;	retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);	if (retval > 0) {		if (retval < PAGE_SIZE) {			*buf = (char *)page;			return retval;		}		retval = -ENAMETOOLONG;	} else if (!retval)		retval = -EINVAL;	free_page(page);	return retval;}static inline voidput_mod_name(char *buf){	free_page((unsigned long)buf);}static __inline__ struct module *find_module(const char *name){	struct module *mod;	for (mod = module_list; mod ; mod = mod->next) {		if (mod->flags & MOD_DELETED)			continue;		if (!strcmp(mod->name, name))			break;	}	return mod;}static intqm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret){	struct module *mod;	size_t nmod, space, len;	nmod = space = 0;	for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {		len = strlen(mod->name)+1;		if (len > bufsize)			goto calc_space_needed;		if (copy_to_user(buf, mod->name, len))			return -EFAULT;		buf += len;		bufsize -= len;		space += len;	}	if (put_user(nmod, ret))		return -EFAULT;	else		return 0;calc_space_needed:	space += len;	while ((mod = mod->next)->next != NULL)		space += strlen(mod->name)+1;	if (put_user(space, ret))		return -EFAULT;	else		return -ENOSPC;}static intqm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret){	size_t i, space, len;	if (mod->next == NULL)		return -EINVAL;	if (!MOD_CAN_QUERY(mod))		return put_user(0, ret);	space = 0;	for (i = 0; i < mod->ndeps; ++i) {		const char *dep_name = mod->deps[i].dep->name;		len = strlen(dep_name)+1;		if (len > bufsize)			goto calc_space_needed;		if (copy_to_user(buf, dep_name, len))			return -EFAULT;		buf += len;		bufsize -= len;		space += len;	}	return put_user(i, ret);calc_space_needed:	space += len;	while (++i < mod->ndeps)		space += strlen(mod->deps[i].dep->name)+1;	if (put_user(space, ret))		return -EFAULT;	else		return -ENOSPC;}static intqm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret){	size_t nrefs, space, len;	struct module_ref *ref;	if (mod->next == NULL)		return -EINVAL;	if (!MOD_CAN_QUERY(mod))		if (put_user(0, ret))			return -EFAULT;		else			return 0;	space = 0;	for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {		const char *ref_name = ref->ref->name;		len = strlen(ref_name)+1;		if (len > bufsize)			goto calc_space_needed;		if (copy_to_user(buf, ref_name, len))			return -EFAULT;		buf += len;		bufsize -= len;		space += len;	}	if (put_user(nrefs, ret))		return -EFAULT;	else		return 0;calc_space_needed:	space += len;	while ((ref = ref->next_ref) != NULL)		space += strlen(ref->ref->name)+1;	if (put_user(space, ret))		return -EFAULT;	else		return -ENOSPC;}static inline intqm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret){	size_t i, space, len;	struct module_symbol *s;	char *strings;	unsigned *vals;	if (!MOD_CAN_QUERY(mod))		if (put_user(0, ret))			return -EFAULT;		else			return 0;	space = mod->nsyms * 2*sizeof(u32);	i = len = 0;	s = mod->syms;	if (space > bufsize)		goto calc_space_needed;	if (!access_ok(VERIFY_WRITE, buf, space))		return -EFAULT;	bufsize -= space;	vals = (unsigned *)buf;	strings = buf+space;	for (; i < mod->nsyms ; ++i, ++s, vals += 2) {		len = strlen(s->name)+1;		if (len > bufsize)			goto calc_space_needed;		if (copy_to_user(strings, s->name, len)		    || __put_user(s->value, vals+0)		    || __put_user(space, vals+1))			return -EFAULT;		strings += len;		bufsize -= len;		space += len;	}	if (put_user(i, ret))		return -EFAULT;	else		return 0;calc_space_needed:	for (; i < mod->nsyms; ++i, ++s)		space += strlen(s->name)+1;	if (put_user(space, ret))		return -EFAULT;	else		return -ENOSPC;}static inline intqm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret){	int error = 0;	if (mod->next == NULL)		return -EINVAL;	if (sizeof(struct module_info32) <= bufsize) {		struct module_info32 info;		info.addr = (unsigned long)mod;		info.size = mod->size;		info.flags = mod->flags;		info.usecount =			((mod_member_present(mod, can_unload)			  && mod->can_unload)			 ? -1 : atomic_read(&mod->uc.usecount));		if (copy_to_user(buf, &info, sizeof(struct module_info32)))			return -EFAULT;	} else		error = -ENOSPC;	if (put_user(sizeof(struct module_info32), ret))		return -EFAULT;	return error;}asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, __kernel_size_t32 *ret){	struct module *mod;	int err;	lock_kernel();	if (name_user == 0) {		/* This finds "kernel_module" which is not exported. */		for(mod = module_list; mod->next != NULL; mod = mod->next)			;	} else {		long namelen;		char *name;		if ((namelen = get_mod_name(name_user, &name)) < 0) {			err = namelen;			goto out;		}		err = -ENOENT;		if (namelen == 0) {			/* This finds "kernel_module" which is not exported. */			for(mod = module_list; mod->next != NULL; mod = mod->next)				;		} else if ((mod = find_module(name)) == NULL) {			put_mod_name(name);			goto out;		}		put_mod_name(name);	}	switch (which)	{	case 0:		err = 0;		break;	case QM_MODULES:		err = qm_modules(buf, bufsize, ret);		break;	case QM_DEPS:		err = qm_deps(mod, buf, bufsize, ret);		break;	case QM_REFS:		err = qm_refs(mod, buf, bufsize, ret);		break;	case QM_SYMBOLS:		err = qm_symbols(mod, buf, bufsize, ret);		break;	case QM_INFO:		err = qm_info(mod, buf, bufsize, ret);		break;	default:		err = -EINVAL;		break;	}out:	unlock_kernel();	return err;}struct kernel_sym32 {	u32 value;	char name[60];};		 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table){	int len, i;	struct kernel_sym *tbl;	mm_segment_t old_fs;		len = sys_get_kernel_syms(NULL);	if (!table) return len;	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);	if (!tbl) return -ENOMEM;	old_fs = get_fs();	set_fs (KERNEL_DS);	sys_get_kernel_syms(tbl);	set_fs (old_fs);	for (i = 0; i < len; i++, table++) {		if (put_user (tbl[i].value, &table->value) ||		    copy_to_user (table->name, tbl[i].name, 60))			break;	}	kfree (tbl);	return i;}#else /* CONFIG_MODULES */asmlinkage intsys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,		 size_t *ret){	/* Let the program know about the new interface.  Not that	   it'll do them much good.  */	if (which == 0)		return 0;	return -ENOSYS;}asmlinkage intsys32_get_kernel_syms(struct kernel_sym *table){	return -ENOSYS;}#endif  /* CONFIG_MODULES *//* readv/writev stolen from mips64 */struct iovec32 { unsigned int iov_base; int iov_len; };typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);static longdo_readv_writev32(int type, struct file *file, const struct iovec32 *vector,		  u32 count){	unsigned long tot_len;	struct iovec iovstack[UIO_FASTIOV];	struct iovec *iov=iovstack, *ivp;	struct inode *inode;	long retval, i;	IO_fn_t fn;	/* First get the "struct iovec" from user memory and	 * verify all the pointers	 */	if (!count)		return 0;	if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))		return -EFAULT;	if (count > UIO_MAXIOV)		return -EINVAL;	if (count > UIO_FASTIOV) {		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);		if (!iov)			return -ENOMEM;	}	tot_len = 0;	i = count;	ivp = iov;	while (i > 0) {		u32 len;		u32 buf;		__get_user(len, &vector->iov_len);		__get_user(buf, &vector->iov_base);		tot_len += len;		ivp->iov_base = (void *)A(buf);		ivp->iov_len = (__kernel_size_t) len;

⌨️ 快捷键说明

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