📄 sys_sparc32.c
字号:
err2 |= __put_user (s.sem_nsems, &usp->sem_nsems); if (err2) err = -EFAULT; } }out: return err;}static int do_sys32_msgsnd (int first, int second, int third, void *uptr){ struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); struct msgbuf32 *up = (struct msgbuf32 *)uptr; mm_segment_t old_fs; int err; if (!p) return -ENOMEM; err = get_user (p->mtype, &up->mtype); err |= __copy_from_user (p->mtext, &up->mtext, second); if (err) goto out; old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_msgsnd (first, p, second, third); set_fs (old_fs);out: kfree (p); return err;}static int do_sys32_msgrcv (int first, int second, int msgtyp, int third, int version, void *uptr){ struct msgbuf32 *up; struct msgbuf *p; mm_segment_t old_fs; int err; if (!version) { struct ipc_kludge *uipck = (struct ipc_kludge *)uptr; struct ipc_kludge ipck; err = -EINVAL; if (!uptr) goto out; err = -EFAULT; if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge))) goto out; uptr = (void *)A(ipck.msgp); msgtyp = ipck.msgtyp; } err = -ENOMEM; p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); if (!p) goto out; old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_msgrcv (first, p, second + 4, msgtyp, third); set_fs (old_fs); if (err < 0) goto free_then_out; up = (struct msgbuf32 *)uptr; if (put_user (p->mtype, &up->mtype) || __copy_to_user (&up->mtext, p->mtext, err)) err = -EFAULT;free_then_out: kfree (p);out: return err;}static int do_sys32_msgctl (int first, int second, void *uptr){ int err; if (IPCOP_MASK (second) & (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) | IPCOP_MASK (IPC_RMID))) { err = sys_msgctl (first, second, (struct msqid_ds *)uptr); } else if (second & IPC_64) { struct msqid64_ds m; struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr; mm_segment_t old_fs; if (second == (IPC_SET|IPC_64)) { err = get_user (m.msg_perm.uid, &up->msg_perm.uid); err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid); err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode); err |= __get_user (m.msg_qbytes, &up->msg_qbytes); if (err) goto out; } old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_msgctl (first, second, (struct msqid_ds *)&m); set_fs (old_fs); if (IPCOP_MASK (second) & (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) { int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t)); err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes); err2 |= __put_user (m.msg_qnum, &up->msg_qnum); err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes); err2 |= __put_user (m.msg_lspid, &up->msg_lspid); err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid); if (err2) err = -EFAULT; } } else { struct msqid_ds m; struct msqid_ds32 *up = (struct msqid_ds32 *)uptr; mm_segment_t old_fs; if (second == IPC_SET) { err = get_user (m.msg_perm.uid, &up->msg_perm.uid); err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid); err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode); err |= __get_user (m.msg_qbytes, &up->msg_qbytes); if (err) goto out; } old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_msgctl (first, second, &m); set_fs (old_fs); if (IPCOP_MASK (second) & (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) { int err2 = put_user (m.msg_perm.key, &up->msg_perm.key); err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid); err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid); err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid); err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid); err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode); err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq); err2 |= __put_user (m.msg_stime, &up->msg_stime); err2 |= __put_user (m.msg_rtime, &up->msg_rtime); err2 |= __put_user (m.msg_ctime, &up->msg_ctime); err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes); err2 |= __put_user (m.msg_qnum, &up->msg_qnum); err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes); err2 |= __put_user (m.msg_lspid, &up->msg_lspid); err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid); if (err2) err = -EFAULT; } }out: return err;}static int do_sys32_shmat (int first, int second, int third, int version, void *uptr){ unsigned long raddr; u32 *uaddr = (u32 *)A((u32)third); int err = -EINVAL; if (version == 1) goto out; err = sys_shmat (first, uptr, second, &raddr); if (err) goto out; err = put_user (raddr, uaddr);out: return err;}static int do_sys32_shmctl (int first, int second, void *uptr){ int err; if (IPCOP_MASK (second) & (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) | IPCOP_MASK (IPC_RMID))) { if (second == (IPC_INFO|IPC_64)) second = IPC_INFO; /* So that we don't have to translate it */ err = sys_shmctl (first, second, (struct shmid_ds *)uptr); } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) { struct shmid64_ds s; struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr; mm_segment_t old_fs; if (second == (IPC_SET|IPC_64)) { err = get_user (s.shm_perm.uid, &up->shm_perm.uid); err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid); err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode); if (err) goto out; } old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_shmctl (first, second, (struct shmid_ds *)&s); set_fs (old_fs); if (err < 0) goto out; /* Mask it even in this case so it becomes a CSE. */ if (IPCOP_MASK (second) & (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) { int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t)); err2 |= __put_user (s.shm_segsz, &up->shm_segsz); err2 |= __put_user (s.shm_nattch, &up->shm_nattch); err2 |= __put_user (s.shm_cpid, &up->shm_cpid); err2 |= __put_user (s.shm_lpid, &up->shm_lpid); if (err2) err = -EFAULT; } } else { struct shmid_ds s; struct shmid_ds32 *up = (struct shmid_ds32 *)uptr; mm_segment_t old_fs; second &= ~IPC_64; if (second == IPC_SET) { err = get_user (s.shm_perm.uid, &up->shm_perm.uid); err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid); err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode); if (err) goto out; } old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_shmctl (first, second, &s); set_fs (old_fs); if (err < 0) goto out; /* Mask it even in this case so it becomes a CSE. */ if (second == SHM_INFO) { struct shm_info32 { int used_ids; u32 shm_tot, shm_rss, shm_swp; u32 swap_attempts, swap_successes; } *uip = (struct shm_info32 *)uptr; struct shm_info *kp = (struct shm_info *)&s; int err2 = put_user (kp->used_ids, &uip->used_ids); err2 |= __put_user (kp->shm_tot, &uip->shm_tot); err2 |= __put_user (kp->shm_rss, &uip->shm_rss); err2 |= __put_user (kp->shm_swp, &uip->shm_swp); err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts); err2 |= __put_user (kp->swap_successes, &uip->swap_successes); if (err2) err = -EFAULT; } else if (IPCOP_MASK (second) & (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) { int err2 = put_user (s.shm_perm.key, &up->shm_perm.key); err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid); err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid); err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid); err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid); err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode); err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq); err2 |= __put_user (s.shm_atime, &up->shm_atime); err2 |= __put_user (s.shm_dtime, &up->shm_dtime); err2 |= __put_user (s.shm_ctime, &up->shm_ctime); err2 |= __put_user (s.shm_segsz, &up->shm_segsz); err2 |= __put_user (s.shm_nattch, &up->shm_nattch); err2 |= __put_user (s.shm_cpid, &up->shm_cpid); err2 |= __put_user (s.shm_lpid, &up->shm_lpid); if (err2) err = -EFAULT; } }out: return err;}asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth){ int version, err; version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; if (call <= SEMCTL) switch (call) { case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ err = sys_semop (first, (struct sembuf *)AA(ptr), second); goto out; case SEMGET: err = sys_semget (first, second, third); goto out; case SEMCTL: err = do_sys32_semctl (first, second, third, (void *)AA(ptr)); goto out; default: err = -EINVAL; goto out; }; if (call <= MSGCTL) switch (call) { case MSGSND: err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr)); goto out; case MSGRCV: err = do_sys32_msgrcv (first, second, fifth, third, version, (void *)AA(ptr)); goto out; case MSGGET: err = sys_msgget ((key_t) first, second); goto out; case MSGCTL: err = do_sys32_msgctl (first, second, (void *)AA(ptr)); goto out; default: err = -EINVAL; goto out; } if (call <= SHMCTL) switch (call) { case SHMAT: err = do_sys32_shmat (first, second, third, version, (void *)AA(ptr)); goto out; case SHMDT: err = sys_shmdt ((char *)AA(ptr)); goto out; case SHMGET: err = sys_shmget (first, second, third); goto out; case SHMCTL: err = do_sys32_shmctl (first, second, (void *)AA(ptr)); goto out; default: err = -EINVAL; goto out; } err = -EINVAL;out: return err;}static inline int get_flock(struct flock *kfl, struct flock32 *ufl){ int err; err = get_user(kfl->l_type, &ufl->l_type); err |= __get_user(kfl->l_whence, &ufl->l_whence); err |= __get_user(kfl->l_start, &ufl->l_start); err |= __get_user(kfl->l_len, &ufl->l_len); err |= __get_user(kfl->l_pid, &ufl->l_pid); return err;}static inline int put_flock(struct flock *kfl, struct flock32 *ufl){ int err; err = __put_user(kfl->l_type, &ufl->l_type); err |= __put_user(kfl->l_whence, &ufl->l_whence); err |= __put_user(kfl->l_start, &ufl->l_start); err |= __put_user(kfl->l_len, &ufl->l_len); err |= __put_user(kfl->l_pid, &ufl->l_pid); return err;}extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg){ switch (cmd) { case F_GETLK: case F_SETLK: case F_SETLKW: { struct flock f; mm_segment_t old_fs; long ret; if (get_flock(&f, (struct flock32 *)arg)) return -EFAULT; old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_fcntl(fd, cmd, (unsigned long)&f); set_fs (old_fs); if (ret) return ret; if (put_flock(&f, (struct flock32 *)arg)) return -EFAULT; return 0; } default: return sys_fcntl(fd, cmd, (unsigned long)arg); }}asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg){ if (cmd >= F_GETLK64 && cmd <= F_SETLKW64) return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg); return sys32_fcntl(fd, cmd, arg);}struct dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; __u32 dqb_curblocks; __u32 dqb_ihardlimit; __u32 dqb_isoftlimit; __u32 dqb_curinodes; __kernel_time_t32 dqb_btime; __kernel_time_t32 dqb_itime;}; extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr){ int cmds = cmd >> SUBCMDSHIFT; int err; struct dqblk d; mm_segment_t old_fs; char *spec; switch (cmds) { case Q_GETQUOTA: break; case Q_SETQUOTA: case Q_SETUSE: case Q_SETQLIM: if (copy_from_user (&d, (struct dqblk32 *)addr, sizeof (struct dqblk32))) return -EFAULT; d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; break; default: return sys_quotactl(cmd, special, id, (caddr_t)addr); } spec = getname (special); err = PTR_ERR(spec); if (IS_ERR(spec)) return err; old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d); set_fs (old_fs); putname (spec); if (cmds == Q_GETQUOTA) { __kernel_time_t b = d.dqb_btime, i = d.dqb_itime; ((struct dqblk32 *)&d)->dqb_itime = i; ((struct dqblk32 *)&d)->dqb_btime = b; if (copy_to_user ((struct dqblk32 *)addr, &d, sizeof (struct dqblk32))) return -EFAULT; } 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 int sys32_statfs(const char * path, struct statfs32 *buf){ int ret; struct statfs s; mm_segment_t old_fs = get_fs(); char *pth; pth = getname (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; } return ret;}extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf){ int ret; struct statfs s; mm_segment_t old_fs = get_fs();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -