long compat_sys_msgctl(int first, int second, void __user *uptr) { int err, err2; struct msqid64_ds m64; int version = compat_ipc_parse_version(&second); void __user *p; memset(&m64, 0, sizeof(m64)); switch (second & (~IPC_64)) { case IPC_INFO: case IPC_RMID: case MSG_INFO: err = sys_msgctl(first, second, uptr); break; case IPC_SET: if (version == IPC_64) { err = get_compat_msqid64(&m64, uptr); } else { err = get_compat_msqid(&m64, uptr); } if (err) break; p = compat_alloc_user_space(sizeof(m64)); if (copy_to_user(p, &m64, sizeof(m64))) err = -EFAULT; else err = sys_msgctl(first, second, p); break; case IPC_STAT: case MSG_STAT: p = compat_alloc_user_space(sizeof(m64)); err = sys_msgctl(first, second, p); if (err < 0) break; if (copy_from_user(&m64, p, sizeof(m64))) err2 = -EFAULT; else if (version == IPC_64) err2 = put_compat_msqid64_ds(&m64, uptr); else err2 = put_compat_msqid_ds(&m64, uptr); if (err2) err = -EFAULT; break; default: err = -EINVAL; break; } return err; }
static long do_compat_semctl(int first, int second, int third, u32 pad) { unsigned long fourth; int err, err2; struct semid64_ds s64; struct semid64_ds __user *up64; int version = compat_ipc_parse_version(&third); memset(&s64, 0, sizeof(s64)); if ((third & (~IPC_64)) == SETVAL) #ifdef __BIG_ENDIAN fourth = (unsigned long)pad << 32; #else fourth = pad; #endif else
long compat_sys_shmctl(int first, int second, void __user *uptr) { void __user *p; struct shmid64_ds s64; struct shminfo64 smi; int err, err2; int version = compat_ipc_parse_version(&second); memset(&s64, 0, sizeof(s64)); switch (second & (~IPC_64)) { case IPC_RMID: case SHM_LOCK: case SHM_UNLOCK: err = sys_shmctl(first, second, uptr); break; case IPC_INFO: p = compat_alloc_user_space(sizeof(smi)); err = sys_shmctl(first, second, p); if (err < 0) break; if (copy_from_user(&smi, p, sizeof(smi))) err2 = -EFAULT; else if (version == IPC_64) err2 = put_compat_shminfo64(&smi, uptr); else err2 = put_compat_shminfo(&smi, uptr); if (err2) err = -EFAULT; break; case IPC_SET: if (version == IPC_64) { err = get_compat_shmid64_ds(&s64, uptr); } else { err = get_compat_shmid_ds(&s64, uptr); } if (err) break; p = compat_alloc_user_space(sizeof(s64)); if (copy_to_user(p, &s64, sizeof(s64))) err = -EFAULT; else err = sys_shmctl(first, second, p); break; case IPC_STAT: case SHM_STAT: p = compat_alloc_user_space(sizeof(s64)); err = sys_shmctl(first, second, p); if (err < 0) break; if (copy_from_user(&s64, p, sizeof(s64))) err2 = -EFAULT; else if (version == IPC_64) err2 = put_compat_shmid64_ds(&s64, uptr); else err2 = put_compat_shmid_ds(&s64, uptr); if (err2) err = -EFAULT; break; case SHM_INFO: p = compat_alloc_user_space(sizeof(struct shm_info)); err = sys_shmctl(first, second, p); if (err < 0) break; err2 = put_compat_shm_info(p, uptr); if (err2) err = -EFAULT; break; default: err = -EINVAL; break; } return err; }
static long do_compat_semctl(int first, int second, int third, u32 pad) { union semun fourth; int err, err2; struct semid64_ds s64; struct semid64_ds __user *up64; int version = compat_ipc_parse_version(&third); memset(&s64, 0, sizeof(s64)); if ((third & (~IPC_64)) == SETVAL) fourth.val = (int) pad; else fourth.__pad = compat_ptr(pad); switch (third & (~IPC_64)) { case IPC_INFO: case IPC_RMID: case SEM_INFO: case GETVAL: case GETPID: case GETNCNT: case GETZCNT: case GETALL: case SETVAL: case SETALL: err = sys_semctl(first, second, third, fourth); break; case IPC_STAT: case SEM_STAT: up64 = compat_alloc_user_space(sizeof(s64)); fourth.__pad = up64; err = sys_semctl(first, second, third, fourth); if (err < 0) break; if (copy_from_user(&s64, up64, sizeof(s64))) err2 = -EFAULT; else if (version == IPC_64) err2 = put_compat_semid64_ds(&s64, compat_ptr(pad)); else err2 = put_compat_semid_ds(&s64, compat_ptr(pad)); if (err2) err = -EFAULT; break; case IPC_SET: if (version == IPC_64) { err = get_compat_semid64_ds(&s64, compat_ptr(pad)); } else { err = get_compat_semid_ds(&s64, compat_ptr(pad)); } up64 = compat_alloc_user_space(sizeof(s64)); if (copy_to_user(up64, &s64, sizeof(s64))) err = -EFAULT; if (err) break; fourth.__pad = up64; err = sys_semctl(first, second, third, fourth); break; default: err = -EINVAL; break; } return err; }