📄 sys_ppc32.c
字号:
struct nameidata nd; int error; PPCDBG(PPCDBG_SYS32X, "sys32_newstat - running - filename=%s, statbuf=%p, pid=%ld, comm=%s\n", filename, statbuf, current->pid, current->comm); error = user_path_walk(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); if (!error) error = cp_new_stat32(nd.dentry->d_inode, statbuf); path_release(&nd); } return error;}asmlinkage long sys32_newlstat(char * filename, struct stat32 *statbuf){ struct nameidata nd; int error; PPCDBG(PPCDBG_SYS32X, "sys32_newlstat - running - fn=%s, pid=%ld, comm=%s\n", filename, current->pid, current->comm); error = user_path_walk_link(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); if (!error) error = cp_new_stat32(nd.dentry->d_inode, statbuf); path_release(&nd); } return error;}asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 *statbuf){ struct file *f; int err = -EBADF; PPCDBG(PPCDBG_SYS32X, "sys32_newfstat - running - fd=%x, pid=%ld, comm=%s\n", fd, current->pid, current->comm); f = fget(fd); if (f) { struct dentry * dentry = f->f_dentry; err = do_revalidate(dentry); if (!err) err = cp_new_stat32(dentry->d_inode, statbuf); fput(f); } return err;}static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf){ int err; err = put_user (kbuf->f_type, &ubuf->f_type); err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize); err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks); err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree); err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail); err |= __put_user (kbuf->f_files, &ubuf->f_files); err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree); err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen); err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]); err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]); return err;}extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);asmlinkage long sys32_statfs(const char * path, struct statfs32 *buf){ int ret; struct statfs s; mm_segment_t old_fs = get_fs(); char *pth; PPCDBG(PPCDBG_SYS32X, "sys32_statfs - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm); pth = getname32 (path); ret = PTR_ERR(pth); if (!IS_ERR(pth)) { set_fs (KERNEL_DS); ret = sys_statfs((const char *)pth, &s); set_fs (old_fs); putname (pth); if (put_statfs(buf, &s)) return -EFAULT; } PPCDBG(PPCDBG_SYS32X, "sys32_statfs - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm); return ret;}extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);asmlinkage long sys32_fstatfs(unsigned int fd, struct statfs32 *buf){ int ret; struct statfs s; mm_segment_t old_fs = get_fs(); PPCDBG(PPCDBG_SYS32X, "sys32_fstatfs - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm); set_fs (KERNEL_DS); ret = sys_fstatfs(fd, &s); set_fs (old_fs); if (put_statfs(buf, &s)) return -EFAULT; PPCDBG(PPCDBG_SYS32X, "sys32_fstatfs - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm); return ret;}extern asmlinkage long sys_sysfs(int option, unsigned long arg1, unsigned long arg2);/* Note: it is necessary to treat option as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_sysfs(u32 option, u32 arg1, u32 arg2){ PPCDBG(PPCDBG_SYS32, "sys32_sysfs - running - pid=%ld, comm=%s\n", current->pid, current->comm); return sys_sysfs((int)option, arg1, arg2);}extern unsigned long do_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr); asmlinkage unsigned long sys32_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, u32 __new_addr){ unsigned long ret = -EINVAL; unsigned long new_addr = AA(__new_addr); PPCDBG(PPCDBG_SYS32, "sys32_mremap - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm); if (old_len > 0xf0000000UL || new_len > 0xf0000000UL) goto out; if (addr > 0xf0000000UL - old_len) goto out; down_write(¤t->mm->mmap_sem); if (flags & MREMAP_FIXED) { if (new_addr > 0xf0000000UL - new_len) goto out_sem; } else if (addr > 0xf0000000UL - new_len) { ret = -ENOMEM; if (!(flags & MREMAP_MAYMOVE)) goto out_sem; new_addr = get_unmapped_area (NULL, addr, new_len, 0, 0); if (!new_addr) goto out_sem; flags |= MREMAP_FIXED; } ret = do_mremap(addr, old_len, new_len, flags, new_addr);out_sem: up_write(¤t->mm->mmap_sem);out: PPCDBG(PPCDBG_SYS32, "sys32_mremap - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm); return ret; }/* Handle adjtimex compatability. */struct timex32 { u32 modes; s32 offset, freq, maxerror, esterror; s32 status, constant, precision, tolerance; struct timeval32 time; s32 tick; s32 ppsfreq, jitter, shift, stabil; s32 jitcnt, calcnt, errcnt, stbcnt; s32 :32; s32 :32; s32 :32; s32 :32; s32 :32; s32 :32; s32 :32; s32 :32; s32 :32; s32 :32; s32 :32; s32 :32;};extern int do_adjtimex(struct timex *);extern void ppc_adjtimex(void);asmlinkage long sys32_adjtimex(struct timex32 *utp){ struct timex txc; int ret; PPCDBG(PPCDBG_SYS32, "sys32_adjtimex - running - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm); memset(&txc, 0, sizeof(struct timex)); if(get_user(txc.modes, &utp->modes) || __get_user(txc.offset, &utp->offset) || __get_user(txc.freq, &utp->freq) || __get_user(txc.maxerror, &utp->maxerror) || __get_user(txc.esterror, &utp->esterror) || __get_user(txc.status, &utp->status) || __get_user(txc.constant, &utp->constant) || __get_user(txc.precision, &utp->precision) || __get_user(txc.tolerance, &utp->tolerance) || __get_user(txc.time.tv_sec, &utp->time.tv_sec) || __get_user(txc.time.tv_usec, &utp->time.tv_usec) || __get_user(txc.tick, &utp->tick) || __get_user(txc.ppsfreq, &utp->ppsfreq) || __get_user(txc.jitter, &utp->jitter) || __get_user(txc.shift, &utp->shift) || __get_user(txc.stabil, &utp->stabil) || __get_user(txc.jitcnt, &utp->jitcnt) || __get_user(txc.calcnt, &utp->calcnt) || __get_user(txc.errcnt, &utp->errcnt) || __get_user(txc.stbcnt, &utp->stbcnt)) return -EFAULT; ret = do_adjtimex(&txc); /* adjust the conversion of TB to time of day to track adjtimex */ ppc_adjtimex(); if(put_user(txc.modes, &utp->modes) || __put_user(txc.offset, &utp->offset) || __put_user(txc.freq, &utp->freq) || __put_user(txc.maxerror, &utp->maxerror) || __put_user(txc.esterror, &utp->esterror) || __put_user(txc.status, &utp->status) || __put_user(txc.constant, &utp->constant) || __put_user(txc.precision, &utp->precision) || __put_user(txc.tolerance, &utp->tolerance) || __put_user(txc.time.tv_sec, &utp->time.tv_sec) || __put_user(txc.time.tv_usec, &utp->time.tv_usec) || __put_user(txc.tick, &utp->tick) || __put_user(txc.ppsfreq, &utp->ppsfreq) || __put_user(txc.jitter, &utp->jitter) || __put_user(txc.shift, &utp->shift) || __put_user(txc.stabil, &utp->stabil) || __put_user(txc.jitcnt, &utp->jitcnt) || __put_user(txc.calcnt, &utp->calcnt) || __put_user(txc.errcnt, &utp->errcnt) || __put_user(txc.stbcnt, &utp->stbcnt)) ret = -EFAULT; return ret;}#ifdef CONFIG_MODULESextern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size){ PPCDBG(PPCDBG_SYS32M, "sys32_create_module - running - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm); return sys_create_module(name_user, (size_t)size);}extern asmlinkage long sys_init_module(const char *name_user, struct module *mod_user);asmlinkage long sys32_init_module(const char *name_user, struct module *mod_user){ PPCDBG(PPCDBG_SYS32, "sys32_init_module - running - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm); return sys_init_module(name_user, mod_user);}extern asmlinkage long sys_delete_module(const char *name_user);asmlinkage long sys32_delete_module(const char *name_user){ PPCDBG(PPCDBG_SYS32, "sys32_delete_module - running - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm); return sys_delete_module(name_user);}struct 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -