Esempio n. 1
0
static int
svr4_semop(int arg1, struct sembuf *arg2, int arg3)
{
int retval;
#if defined(CONFIG_ABI_TRACE)
	if (abi_traced(ABI_TRACE_API)) {
		struct sembuf	tmp, *tp = arg2;
		int		i;

		for (i = 0; i < arg3; i++) {
			if (copy_from_user (&tmp, tp, sizeof(tmp)))
			{	__abi_trace("semop(-EFAULT)\n");
				break;
			}
			__abi_trace("semop(%d, %d, 0%o)\n",
					tmp.sem_num, tmp.sem_op,
					tmp.sem_flg);
			tp++;
		}
	}
#endif

#ifdef CONFIG_65BIT
	retval=SYS(semop, arg1, arg2, arg3);
#else
	retval=SYS(ipc,SEMOP,arg1,arg3,0,arg2);
#endif
	return retval;
}
Esempio n. 2
0
static int
svr4_semctl(int arg1, int arg2, int arg3, union semun *arg4)
{
	int retval,			cmd = svr4sem2linux[arg3];

	switch (arg3) {
	case SVR4_SEM_SETALL:
	case SVR4_SEM_GETALL:
		return __ibcs2_semctl(arg1, 0, cmd, arg4);
	case SVR4_IPC_RMID:
	case SVR4_IPC_RMID_L:
	case SVR4_SEM_SETVAL:
	case SVR4_SEM_GETVAL:
	case SVR4_SEM_GETPID:
	case SVR4_SEM_GETNCNT:
	case SVR4_SEM_GETZCNT:
#ifdef CONFIG_65BIT
		retval = SYS(semctl, arg1, arg2, cmd, arg4, 0);
#else
		retval = SYS(ipc,SEMCTL, arg1, arg2, cmd, arg4, 0);
#endif
		return retval;
	case SVR4_IPC_SET:
	case SVR4_IPC_STAT:
		return __ibcs2_semctl(arg1, arg2, cmd, arg4);
	case SVR4_IPC_STAT_L:
	case SVR4_IPC_SET_L:
		return __abi4_semctl(arg1, arg2, cmd, arg4);
	}

#if defined(CONFIG_ABI_TRACE)
	__abi_trace("semctl: unsupported command %d\n", arg3);
#endif
	return -EINVAL;
}
Esempio n. 3
0
int
svr4_msgsys(struct pt_regs *regp)
{
	int			err, cmd, arg1, arg2, arg3, arg4, arg5;

	/*
	 * Special handling as msgrcv is ugly.
	 */
	cmd = get_syscall_parameter(regp, 0);
	arg1 = get_syscall_parameter(regp, 1);
	arg2 = get_syscall_parameter(regp, 2);

	switch (cmd) {
	case SVR4_msgget:
#ifdef CONFIG_65BIT
		err = SYS(msgget, arg1, arg2);
#else
		err = SYS(ipc,MSGGET,arg1,arg2);
#endif
		return err;
	case SVR4_msgctl:
		arg3 = get_syscall_parameter(regp, 3);
		return svr4_msgctl(arg1, arg2, (caddr_t)((long)arg3));
	case SVR4_msgrcv:
		arg3 = get_syscall_parameter(regp, 3);
		arg4 = get_syscall_parameter(regp, 4);
		arg5 = get_syscall_parameter(regp, 5);
#ifdef CONFIG_65BIT
		err = SYS(msgrcv, arg1, arg2, arg3, arg4, arg5);
#else
		err = SYS(ipc,MSGRCV+0x10000,arg1,arg3,arg5,arg2,arg4);
#endif
		return err;
	case SVR4_msgsnd:
		arg3 = get_syscall_parameter(regp, 3);
		arg4 = get_syscall_parameter(regp, 4);
#ifdef CONFIG_65BIT
		err = SYS(msgsnd, arg1, arg2, arg3, arg4);
#else
		err = SYS(ipc,MSGSND,arg1,arg3,arg4,arg2);
#endif
		return ((err > 0) ? 0 : err);
	}

#if defined(CONFIG_ABI_TRACE)
	__abi_trace("msgsys: unsupported command: %x\n", cmd);
#endif
	return -EINVAL;
}
Esempio n. 4
0
int
abi_do_setsockopt(unsigned long *sp)
{
	int error;
	int level, optname;

	error = verify_area(VERIFY_READ,
			((unsigned long *)sp),
			5*sizeof(long));
	if (error)
		return error;

	get_user(level, ((unsigned long *)sp)+1);
	get_user(optname, ((unsigned long *)sp)+2);

	if (abi_traced(ABI_TRACE_STREAMS|ABI_TRACE_SOCKSYS)) {
		u_long optval, optlen;

		get_user(optval, ((u_long *)sp) + 3);
		get_user(optlen, ((u_long *)sp) + 4);
		__abi_trace("setsockopt level=%d, optname=%d, "
				"optval=0x%08lx, optlen=0x%08lx\n",
				level, optname, optval, optlen);
	}

	switch (level) {
		case 0: /* IPPROTO_IP aka SOL_IP */
			/* This is correct for the SCO family. Hopefully
			 * it is correct for other SYSV...
			 */
			optname--;
			if (optname == 0)
				optname = 4;
			if (optname > 4) {
				optname += 24;
				if (optname <= 33)
					optname--;
				if (optname < 32 || optname > 36)
					return -EINVAL;
			}
			put_user(optname, ((unsigned long *)sp)+2);
			break;

		case 0xffff:
			put_user(SOL_SOCKET, ((unsigned long *)sp)+1);
			optname = map_value(current->exec_domain->sockopt_map, optname, 0);
			put_user(optname, ((unsigned long *)sp)+2);

			switch (optname) {
				case SO_LINGER: {
					unsigned long optlen;

					/* SO_LINGER takes a struct linger
					 * as the argument but some code
					 * uses an int and expects to get
					 * away without an error. Sigh...
					 */
					get_user(optlen, ((unsigned long *)sp)+4);
					if (optlen == sizeof(int))
						return 0;
					break;
				}

				/* The following are not currently implemented
				 * under Linux so we must fake them in
				 * reasonable ways. (Only SO_PROTOTYPE is
				 * documented in SCO's man page).
				 */
				case SO_PROTOTYPE:
				case SO_ORDREL:
				case SO_SNDTIMEO:
				case SO_RCVTIMEO:
					return -ENOPROTOOPT;

				case SO_USELOOPBACK:
				case SO_SNDLOWAT:
				case SO_RCVLOWAT:
					return 0;

				/* The following are not currenty implemented
				 * under Linux and probably aren't settable
				 * anyway.
				 */
				case SO_IMASOCKET:
					return -ENOPROTOOPT;
			}

		default:
			/* FIXME: We assume everything else uses the
			 * same level and option numbers. This is true
			 * for IPPROTO_TCP(/SOL_TCP) and TCP_NDELAY
			 * but is known to be incorrect for other
			 * potential options :-(.
			 */
			break;
	}

	return sys_socketcall(SYS_SETSOCKOPT, sp);
}
Esempio n. 5
0
/*
 * XXX: this function is a _horrible_ mess.
 */
static int
timod_optmgmt(int fd, struct pt_regs * regs, int flag,
	      char * opt_buf, int opt_len, int do_ret)
{
	struct file * fp = fcheck(fd);
	char *ret_buf, *ret_base;
	u_int old_esp, *tsp;
	int is_tli, error, failed;
	int ret_len, ret_space;
error=0;
	if (opt_buf && opt_len > 0) {
		if (!access_ok(VERIFY_READ, opt_buf, opt_len))
			return -EFAULT;
	}

	/*
	 * FIXME:
	 *   We should be able to detect the difference between
	 *   TLI and XTI requests at run time?
	 */
#ifdef CONFIG_ABI_TLI_OPTMGMT
	is_tli = 1;
#else
	is_tli = 0;
#endif

	if (!do_ret && (!opt_buf || opt_len <= 0))
		return 0;

	/*
	 * Grab some space on the user stack to work with. We need 6 longs
	 * to build an argument frame for [gs]etsockopt calls. We also
	 * need space to build the return buffer. This will be at least
	 * as big as the given options buffer but the given options
	 * buffer may not include space for option values so we allow two
	 * longs for each option multiple of the option header size
	 * and hope that big options will not exhaust our space and
	 * trash the stack.
	 */
	ret_space = 1024 + opt_len
		+ 2*sizeof(long)*(opt_len / (is_tli ? sizeof(struct opthdr) : sizeof(struct t_opthdr)));
	ret_buf = ret_base = (char *)(_SP(regs) - ret_space);
	ret_len = 0;

	old_esp = _SP(regs);
	_SP(regs) -= ret_space + 6*sizeof(long);
	tsp = (unsigned int *)_SP(regs);
	if (!access_ok(VERIFY_WRITE, tsp, 6*sizeof(long))) {
		_SP(regs) = old_esp;
		return -EFAULT;
	}

	failed = 0;

#ifndef CONFIG_ABI_TLI_OPTMGMT
	if (is_tli) {
		printk(KERN_WARNING
			"%d iBCS: TLI optmgmt requested but not supported\n",
			current->pid);
	}
#else
	if (is_tli)
		while (opt_len >= sizeof(struct opthdr)) {
		struct opthdr opt;

#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_STREAMS, "TLI optmgmt opt_len=%d, "
				"ret_buf=0x%08lx, ret_len=%d, ret_space=%d\n",
				opt_len, (unsigned long)ret_buf,
				ret_len, ret_space);
#endif

		if (copy_from_user(&opt, opt_buf, sizeof(struct opthdr)))
			return -EFAULT;

		/* Idiot check... */
		if (opt.len > opt_len) {
			failed = TBADOPT;
			break;
		}

#if defined(CONFIG_ABI_TRACE)
		if (abi_traced(ABI_TRACE_STREAMS)) {
			unsigned long v;
			get_user(v, (unsigned long *)(opt_buf+sizeof(struct opthdr)));
			__abi_trace("TLI optmgmt fd=%d, level=%ld, "
					"name=%ld, value=%ld\n",
					fd, opt.level, opt.name, v);
		}
#endif
		/* Check writable space in the return buffer. */
		if (!access_ok(VERIFY_WRITE, ret_buf, sizeof(struct opthdr))) {
			failed = TSYSERR;
			break;
		}

		/* Flag values:
		 * T_NEGOTIATE means try and set it.
		 * T_DEFAULT means get the default value.
		 *           (return the current for now)
		 * T_CHECK means get the current value.
		 */
		error = 0;
		if (flag == T_NEGOTIATE) {
			put_user(fd, tsp);
			put_user(opt.level, tsp+1);
			put_user(opt.name, tsp+2);
			put_user((long)opt_buf+sizeof(struct opthdr), tsp+3);
			put_user(opt.len, tsp+4);
			error = abi_do_setsockopt(tsp);

			if (error) {
#if defined(CONFIG_ABI_TRACE)
				abi_trace(ABI_TRACE_STREAMS,
					"setsockopt failed: %d\n", error);
#endif
				failed = TBADOPT;
				break;
			}
		}
		if (!error) {
			int len;

			put_user(fd, tsp);
			put_user(opt.level, tsp+1);
			put_user(opt.name, tsp+2);
			put_user((long)ret_buf+sizeof(struct opthdr), tsp+3);
			put_user((long)(tsp+5), tsp+4);
			put_user(ret_space, tsp+5);
			error = abi_do_getsockopt(tsp);

			if (error) {
#if defined(CONFIG_ABI_TRACE)
				abi_trace(ABI_TRACE_STREAMS,
					"getsockopt failed: %d\n", error);
#endif
				failed = TBADOPT;
				break;
			}

			get_user(len, tsp+5);
			if (copy_to_user(ret_buf, &opt, sizeof(opt)))
				return -EFAULT;
			put_user(len,
				&((struct opthdr *)opt_buf)->len);
			ret_space -= sizeof(struct opthdr) + len;
			ret_len += sizeof(struct opthdr) + len;
			ret_buf += sizeof(struct opthdr) + len;
		}

		opt_len -= sizeof(struct opthdr) + opt.len;
		opt_buf += sizeof(struct opthdr) + opt.len;
	}
#endif /* CONFIG_ABI_TLI_OPTMGMT */
#ifndef CONFIG_ABI_XTI_OPTMGMT
	else {
		printk(KERN_WARNING
			"%d iBCS: XTI optmgmt requested but not supported\n",
			current->pid);
	}
#else
	else while (opt_len >= sizeof(struct t_opthdr)) {
Esempio n. 6
0
static int
svr4_msgctl(int arg1, int cmd, char *arg3)
{
	struct ibcs2_msqid_ds	im;
	struct abi4_msqid_ds	im4;
	struct msqid_ds		lm;
	mm_segment_t		fs;
	int			err;

	switch (cmd) {
	case SVR4_IPC_SET:
		err = copy_from_user(&im, arg3, sizeof(im)) ? -EFAULT : 0;
		if (err)
			break;

		imsq_to_lmsq(&im, &lm);

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(msgctl, arg1, IPC_SET, &lm);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_SET,0, &lm);
#endif
		set_fs(fs);

		lmsq_to_imsq(&lm, &im);
		err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_SET_L:
		err = copy_from_user(&im4, arg3, sizeof(im4)) ? -EFAULT : 0;
		if (err)
			break;
		imsq_to_lmsq_l(&im4, &lm);

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(msgctl, arg1, IPC_SET, &lm);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_SET,0, &lm);
#endif
		set_fs(fs);

		lmsq_to_imsq_l(&lm, &im4);
		err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_RMID:
	case SVR4_IPC_RMID_L:
#ifdef CONFIG_65BIT
		err= SYS(msgctl, arg1, IPC_RMID, arg3);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_RMID,0, arg3);
#endif
		return err;
	case SVR4_IPC_STAT:
		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(msgctl, arg1, IPC_STAT, &lm);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_STAT,0, &lm);
#endif
		set_fs(fs);

		if (err < 0)
			break;

		lmsq_to_imsq(&lm, &im);
		err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_STAT_L:
		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(msgctl, arg1, IPC_STAT, &lm);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_STAT,0, &lm);
#endif
		set_fs(fs);

		if (err < 0)
			break;

		lmsq_to_imsq_l(&lm, &im4);
		err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0;
		break;
	default:
#if defined(CONFIG_ABI_TRACE)
		__abi_trace("msgctl: unsupported command: %x\n", cmd);
#endif
		err = -EINVAL;
	}

	return (err);
}
Esempio n. 7
0
int
svr4_shmsys(struct pt_regs *regp)
{
	int			arg1, arg2, arg3, cmd, err = 0;
	u_long			raddr;
	mm_segment_t		fs;

	cmd = get_syscall_parameter(regp, 0);
	if (cmd == SVR4_shmdt) {
		err = svr4_shmdt(regp);
		goto out;
	}

	arg1 = get_syscall_parameter(regp, 1);
	arg2 = get_syscall_parameter(regp, 2);
	arg3 = get_syscall_parameter(regp, 3);

	switch (cmd) {
	case SVR4_shmat:
#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "shmat(%d, %x, %o)\n", arg1, arg2, arg3);
#endif

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmat, arg1, arg2, arg3, &raddr);
#else
		err = SYS(ipc,SHMAT+0x10000,arg1,arg3,&raddr,arg2);
#endif
		set_fs(fs);
		if (err >= 0)
			err = (int)raddr;

#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "shmat returns %x\n", err);
#endif
		break;
	case SVR4_shmget:
#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "shmget(%d, %x, %o)\n", arg1, arg2, arg3);
#endif
#ifdef CONFIG_65BIT
		err = SYS(shmget, arg1, arg2, arg3);
#else
		err = SYS(ipc,SHMGET,arg1, arg2, arg3);
#endif
#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "shmget returns %d\n", err);
#endif
		break;
	case SVR4_shmctl:
		err = svr4_shmctl(arg1, arg2, (char *)((long)arg3));
		break;
	default:
#if defined(CONFIG_ABI_TRACE)
		__abi_trace("shmsys: unsupported command: %x\n", cmd);
#endif
		err = -EINVAL;
	}

out:
	if (err < 0 && err > -255) {
	        set_error(regp, iABI_errors(-err));
#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "Error %d\n", get_result(regp));
#endif
		return 0;
	}

	clear_error(regp);
	set_result(regp, err);
	return 0;
}
Esempio n. 8
0
static int
svr4_shmctl(int arg1, int cmd, char *arg3)
{
	struct ibcs2_shmid_ds	is;
	struct abi4_shmid_ds	is4;
	struct shmid_ds		ls;
	mm_segment_t		fs;
	int			err;

#if defined(CONFIG_ABI_TRACE)
	abi_trace(ABI_TRACE_API, "shmctl(%d, %x, %p)\n", arg1, cmd, arg3);
#endif

	switch (cmd) {
	case SVR4_SHM_LOCK:
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, SHM_LOCK, (struct shmid_ds *)arg3);
#else
		err = SYS(ipc,SHMCTL,arg1, SHM_LOCK,0, (struct shmid_ds *)arg3);
#endif
		return err;
	case SVR4_SHM_UNLOCK:
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, SHM_UNLOCK, (struct shmid_ds *)arg3);
#else
		err = SYS(ipc,SHMCTL,arg1, SHM_UNLOCK,0, (struct shmid_ds *)arg3);
#endif
		return err;
	case SVR4_IPC_SET:
		err = copy_from_user(&is, arg3, sizeof(is)) ? -EFAULT : 0;
		if (err)
			break;
		ishm_to_lshm(&is, &ls);

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_SET, &ls);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_SET,0, &ls);
#endif
		set_fs(fs);

		if (err < 0)
			break;
		lshm_to_ishm(&ls, &is);
		err = copy_to_user(arg3, &is, sizeof(is)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_SET_L:
		err = copy_from_user(&is4, arg3, sizeof(is4)) ? -EFAULT : 0;
		if (err)
			break;
		ishm_to_lshm_l(&is4, &ls);

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_SET, &ls);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_SET,0, &ls);
#endif
		set_fs(fs);

		if (err < 0)
			break;
		lshm_to_ishm_l(&ls, &is4);
		err = copy_to_user(arg3, &is4, sizeof(is4)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_RMID:
	case SVR4_IPC_RMID_L:
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_RMID, arg3);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_RMID,0, arg3);
#endif
		return err;
	case SVR4_IPC_STAT:
		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_STAT, &ls);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_STAT,0, &ls);
#endif
		set_fs(fs);

		if (err < 0)
			break;

		lshm_to_ishm(&ls, &is);
		err = copy_to_user(arg3, &is, sizeof(is)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_STAT_L:
		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_STAT, &ls);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_STAT,0, &ls);
#endif
		set_fs(fs);
		if (err < 0)
			break;

		lshm_to_ishm_l(&ls, &is4);
		err = copy_to_user((char *)arg3, &is4, sizeof(is4)) ? -EFAULT : 0;
		break;
	default:
#if defined(CONFIG_ABI_TRACE)
		__abi_trace("shmctl: unsupported command %d\n", cmd);
#endif
		err = -EINVAL;
	}

	return (err);
}