📄 sys_sparc32.c
字号:
{ int err; err = put_user(stat->dev, &statbuf->st_dev); err |= put_user(stat->ino, &statbuf->st_ino); err |= put_user(stat->mode, &statbuf->st_mode); err |= put_user(stat->nlink, &statbuf->st_nlink); err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid); err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid); err |= put_user(stat->rdev, &statbuf->st_rdev); if (stat->size > MAX_NON_LFS) return -EOVERFLOW; err |= put_user(stat->size, &statbuf->st_size); err |= put_user(stat->atime, &statbuf->st_atime); err |= put_user(0, &statbuf->__unused1); err |= put_user(stat->mtime, &statbuf->st_mtime); err |= put_user(0, &statbuf->__unused2); err |= put_user(stat->ctime, &statbuf->st_ctime); err |= put_user(0, &statbuf->__unused3); err |= put_user(stat->blksize, &statbuf->st_blksize); err |= put_user(stat->blocks, &statbuf->st_blocks); err |= put_user(0, &statbuf->__unused4[0]); err |= put_user(0, &statbuf->__unused4[1]); return err;}asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf){ struct kstat stat; int error = vfs_stat(filename, &stat); if (!error) error = cp_new_stat32(&stat, statbuf); return error;}asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf){ struct kstat stat; int error = vfs_lstat(filename, &stat); if (!error) error = cp_new_stat32(&stat, statbuf); return error;}asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf){ struct kstat stat; int error = vfs_fstat(fd, &stat); if (!error) error = cp_new_stat32(&stat, statbuf); return error;}extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2){ return sys_sysfs(option, arg1, arg2);}struct ncp_mount_data32 { int version; unsigned int ncp_fd; __kernel_uid_t32 mounted_uid; __kernel_pid_t32 wdog_pid; unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; unsigned int time_out; unsigned int retry_count; unsigned int flags; __kernel_uid_t32 uid; __kernel_gid_t32 gid; __kernel_mode_t32 file_mode; __kernel_mode_t32 dir_mode;};static void *do_ncp_super_data_conv(void *raw_data){ struct ncp_mount_data news, *n = &news; struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data; n->dir_mode = n32->dir_mode; n->file_mode = n32->file_mode; n->gid = low2highgid(n32->gid); n->uid = low2highuid(n32->uid); memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int))); n->wdog_pid = n32->wdog_pid; n->mounted_uid = low2highuid(n32->mounted_uid); memcpy(raw_data, n, sizeof(struct ncp_mount_data)); return raw_data;}struct smb_mount_data32 { int version; __kernel_uid_t32 mounted_uid; __kernel_uid_t32 uid; __kernel_gid_t32 gid; __kernel_mode_t32 file_mode; __kernel_mode_t32 dir_mode;};static void *do_smb_super_data_conv(void *raw_data){ struct smb_mount_data news, *s = &news; struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data; s->version = s32->version; s->mounted_uid = low2highuid(s32->mounted_uid); s->uid = low2highuid(s32->uid); s->gid = low2highgid(s32->gid); s->file_mode = s32->file_mode; s->dir_mode = s32->dir_mode; memcpy(raw_data, s, sizeof(struct smb_mount_data)); return raw_data;}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 *)AA(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) do_ncp_super_data_conv((void *)data_page); else 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;}struct rusage32 { struct timeval32 ru_utime; struct timeval32 ru_stime; s32 ru_maxrss; s32 ru_ixrss; s32 ru_idrss; s32 ru_isrss; s32 ru_minflt; s32 ru_majflt; s32 ru_nswap; s32 ru_inblock; s32 ru_oublock; s32 ru_msgsnd; s32 ru_msgrcv; s32 ru_nsignals; s32 ru_nvcsw; s32 ru_nivcsw;};static int put_rusage (struct rusage32 *ru, struct rusage *r){ int err; err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec); err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec); err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec); err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec); err |= __put_user (r->ru_maxrss, &ru->ru_maxrss); err |= __put_user (r->ru_ixrss, &ru->ru_ixrss); err |= __put_user (r->ru_idrss, &ru->ru_idrss); err |= __put_user (r->ru_isrss, &ru->ru_isrss); err |= __put_user (r->ru_minflt, &ru->ru_minflt); err |= __put_user (r->ru_majflt, &ru->ru_majflt); err |= __put_user (r->ru_nswap, &ru->ru_nswap); err |= __put_user (r->ru_inblock, &ru->ru_inblock); err |= __put_user (r->ru_oublock, &ru->ru_oublock); err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd); err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv); err |= __put_user (r->ru_nsignals, &ru->ru_nsignals); err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw); err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw); return err;}asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru){ if (!ru) return sys_wait4(pid, stat_addr, options, NULL); else { struct rusage r; int ret; unsigned int status; mm_segment_t old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r); set_fs (old_fs); if (put_rusage (ru, &r)) return -EFAULT; if (stat_addr && put_user (status, stat_addr)) return -EFAULT; return ret; }}struct sysinfo32 { s32 uptime; u32 loads[3]; u32 totalram; u32 freeram; u32 sharedram; u32 bufferram; u32 totalswap; u32 freeswap; unsigned short procs; char _f[22];};extern asmlinkage int sys_sysinfo(struct sysinfo *info);asmlinkage int sys32_sysinfo(struct sysinfo32 *info){ struct sysinfo s; int ret, err; mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); ret = sys_sysinfo(&s); set_fs (old_fs); err = put_user (s.uptime, &info->uptime); err |= __put_user (s.loads[0], &info->loads[0]); err |= __put_user (s.loads[1], &info->loads[1]); err |= __put_user (s.loads[2], &info->loads[2]); err |= __put_user (s.totalram, &info->totalram); err |= __put_user (s.freeram, &info->freeram); err |= __put_user (s.sharedram, &info->sharedram); err |= __put_user (s.bufferram, &info->bufferram); err |= __put_user (s.totalswap, &info->totalswap); err |= __put_user (s.freeswap, &info->freeswap); err |= __put_user (s.procs, &info->procs); if (err) return -EFAULT; return ret;}struct timespec32 { s32 tv_sec; s32 tv_nsec;}; extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval){ struct timespec t; int ret; mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); ret = sys_sched_rr_get_interval(pid, &t); set_fs (old_fs); if (put_user (t.tv_sec, &interval->tv_sec) || __put_user (t.tv_nsec, &interval->tv_nsec)) return -EFAULT; return ret;}extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp){ struct timespec t; int ret; mm_segment_t old_fs = get_fs (); if (get_user (t.tv_sec, &rqtp->tv_sec) || __get_user (t.tv_nsec, &rqtp->tv_nsec)) return -EFAULT; set_fs (KERNEL_DS); ret = sys_nanosleep(&t, rmtp ? &t : NULL); set_fs (old_fs); if (rmtp && ret == -EINTR) { if (__put_user (t.tv_sec, &rmtp->tv_sec) || __put_user (t.tv_nsec, &rmtp->tv_nsec)) return -EFAULT; } return ret;}extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset){ old_sigset_t s; int ret; mm_segment_t old_fs = get_fs(); if (set && get_user (s, set)) return -EFAULT; set_fs (KERNEL_DS); ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); set_fs (old_fs); if (ret) return ret; if (oset && put_user (s, oset)) return -EFAULT; return 0;}extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize){ sigset_t s; sigset_t32 s32; int ret; mm_segment_t old_fs = get_fs(); if (set) { if (copy_from_user (&s32, set, sizeof(sigset_t32))) return -EFAULT; switch (_NSIG_WORDS) { case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); } } set_fs (KERNEL_DS); ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize); set_fs (old_fs); if (ret) return ret; if (oset) { switch (_NSIG_WORDS) { case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; } if (copy_to_user (oset, &s32, sizeof(sigset_t32))) return -EFAULT; } return 0;}extern asmlinkage int sys_sigpending(old_sigset_t *set);asmlinkage int sys32_sigpending(old_sigset_t32 *set){ old_sigset_t s; int ret; mm_segment_t old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_sigpending(&s); set_fs (old_fs); if (put_user (s, set)) return -EFAULT; return ret;}extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize){ sigset_t s; sigset_t32 s32; int ret; mm_segment_t old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_rt_sigpending(&s, sigsetsize); set_fs (old_fs); if (!ret) { switch (_NSIG_WORDS) { case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; } if (copy_to_user (set, &s32, sizeof(sigset_t32))) return -EFAULT; } return ret;}asmlinkage intsys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo, struct timespec32 *uts, __kernel_size_t32 sigsetsize){ int ret, sig; sigset_t these; sigset_t32 these32; struct timespec ts; siginfo_t info; long timeout = 0; /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(sigset_t)) return -EINVAL; if (copy_from_user (&these32, uthese, sizeof(sigset_t32))) return -EFAULT; switch (_NSIG_WORDS) { case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32); case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32); case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32); case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32); } /* * Invert the set of allowed signals to get those we * want to block. */ sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP)); signotset(&these); if (uts) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -