Esempio n. 1
0
asmlinkage int
sunos_mount(char *type, char *dir, int flags, void *data)
{
	int linux_flags = MS_MGC_MSK; /* new semantics */
	int error;
	char *dev_fname = 0;

	/* We don't handle the integer fs type */
	if ((flags & SMNT_NEWTYPE) == 0)
		return -EINVAL;

	/* Do not allow for those flags we don't support */
	if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5))
		return -EINVAL;

	if(flags & SMNT_REMOUNT)
		linux_flags |= MS_REMOUNT;
	if(flags & SMNT_RDONLY)
		linux_flags |= MS_RDONLY;
	if(flags & SMNT_NOSUID)
		linux_flags |= MS_NOSUID;
	error = verify_area(VERIFY_READ, type, 16);
	if(error)
		return error;
	if(strcmp(type, "ext2") == 0) {
		dev_fname = (char *) data;
	} else if(strcmp(type, "iso9660") == 0) {
		dev_fname = (char *) data;
	} else if(strcmp(type, "minix") == 0) {
		dev_fname = (char *) data;
	} else if(strcmp(type, "ext") == 0) {
		dev_fname = (char *) data;
	} else if(strcmp(type, "xiafs") == 0) {
		dev_fname = (char *) data;
	} else if(strcmp(type, "nfs") == 0) {
		error = sunos_nfs_mount (dir, flags, data);
		return error;
        } else if(strcmp(type, "ufs") == 0) {
		printk("Warning: UFS filesystem mounts unsupported.\n");
		return -ENODEV;
	} else if(strcmp(type, "proc")) {
		return -ENODEV;
	}
	if(error)
		return error;
	error = sys_mount(dev_fname, dir, type, linux_flags, NULL);
	return error;
}
Esempio n. 2
0
/* a basic put() operation. Note the avoidance of odd word boundaries
   and transfers sizes beyond what the hardware can deal with */
static inline int aplib_put(struct aplib_putget *put)
{
	int error;
	struct aplib_struct *aplib = current->aplib;

	error = verify_area(VERIFY_WRITE,put,sizeof(*put));
	if (error) return error;

	if (put->cid >= aplib->numcells) 
		return -EINVAL;

	do {
		int n;

		if (put->size && (((unsigned)put->src_addr) & 4)) {
			n = 1;
		} else if (put->size > MAX_PUT_SIZE) {
			n = MAX_PUT_SIZE;
		} else {
			n = put->size;
		}

		put->size -= n;

		page_in((char *)put->src_addr,n<<2);

		_putget(MSC_PUT_QUEUE,
			aplib->rel_cid[put->cid],
			put->src_addr,
			n,
			put->dest_addr,
			put->size?0:put->dest_flag,
			put->size?0:put->src_flag);

		put->dest_addr += n;
		put->src_addr += n;
	} while (put->size);

	if (put->ack) {
		aplib->ack_request++;
		_putget(MSC_GET_QUEUE,
			aplib->rel_cid[put->cid], 
			0, 0, 0,
			&aplib->ack_flag, 0);
	}

	return 0;
}
Esempio n. 3
0
/*
 * bind a name to a socket. this is where much of the work is done. we
 * allocate a fresh page for the buffer, grab the appropriate inode and
 * set things up.
 *
 * XXX what should we do if an address is already bound? here we return
 * EINVAL, but it may be necessary to re-bind. i think thats what bsd does
 * in the case of datagram sockets
 */
static int
unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
		int sockaddr_len)
{
	struct unix_proto_data *upd = UN_DATA(sock);
	char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
	int i;
	unsigned long old_fs;

	PRINTK("unix_proto_bind: socket 0x%x, len=%d\n", sock,
	       sockaddr_len);
	if (sockaddr_len <= UN_PATH_OFFSET ||
	    sockaddr_len >= sizeof(struct sockaddr_un)) {
		PRINTK("unix_proto_bind: bad length %d\n", sockaddr_len);
		return -EINVAL;
	}
	if (upd->sockaddr_len || upd->inode) {
		printk("unix_proto_bind: already bound!\n");
		return -EINVAL;
	}
	verify_area(umyaddr, sockaddr_len);
	memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
	if (upd->sockaddr_un.sun_family != AF_UNIX) {
		PRINTK("unix_proto_bind: family is %d, not AF_UNIX (%d)\n",
		       upd->sockaddr_un.sun_family, AF_UNIX);
		return -EINVAL;
	}

	memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
	fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
	old_fs = get_fs();
	set_fs(get_ds());
	i = do_mknod(fname, S_IFSOCK | 0777, 0);
	if (i == 0)
		i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
	set_fs(old_fs);
	if (i < 0) {
		printk("unix_proto_bind: can't open socket %s\n", fname);
		return i;
	}

	upd->sockaddr_len = sockaddr_len;	/* now its legal */
	PRINTK("unix_proto_bind: bound socket address: ");
#ifdef SOCK_DEBUG
	sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
#endif
	return 0;
}
Esempio n. 4
0
// 获取系统名称等信息。其中utsname结构包含5个字段,分别是:当前运行系统的名称,
// 网络节点名称(主机名)、当前操作系统发行级别、操作系统版本号以及系统运行的
// 硬件类型名称,该结构在include/sys/utsname.h中定义。
int sys_uname(struct utsname * name)
{
	static struct utsname thisname = {      // 这里给出了结构中的信息,这种编码肯定会改变。
		"linux .0","nodename","release ","version ","machine "
	};
	int i;

    // 首先判断参数的有效性。如果存放信息的缓冲区指针为空,则出错返回。在验证缓
    // 冲区大小是否超限(若超出内核自动扩展)。然后将utsname中的信息逐字节复制到
    // 用户缓冲区中。
	if (!name) return -ERROR;
	verify_area(name,sizeof *name);
	for(i=0;i<sizeof *name;i++)
		put_fs_byte(((char *) &thisname)[i],i+(char *) name);
	return 0;
}
Esempio n. 5
0
/*
 * Due to some executables calling the wrong select we sometimes
 * get wrong args.  This determines how the args are being passed
 * (a single ptr to them all args passed) then calls
 * sys_select() with the appropriate args. -- Cort
 */
int
ppc_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
{
	if ( (unsigned long)n >= 4096 )
	{
		unsigned long *buffer = (unsigned long *)n;
		if (verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long))
		    || __get_user(n, buffer)
		    || __get_user(inp, ((fd_set **)(buffer+1)))
		    || __get_user(outp, ((fd_set **)(buffer+2)))
		    || __get_user(exp, ((fd_set **)(buffer+3)))
		    || __get_user(tvp, ((struct timeval **)(buffer+4))))
			return -EFAULT;
	}
	return sys_select(n, inp, outp, exp, tvp);
}
Esempio n. 6
0
int sigreturn_common(struct pt_regs *regs,int framesize)
{
	sigframe *frame = (sigframe *)regs->gprs[15];
	sigset_t set;

	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
		return -1;
	if (restore_sigcontext(&frame->sc,regs,&frame->sregs,&set))
	        return -1;
	sigdelsetmask(&set, ~_BLOCKABLE);
	spin_lock_irq(&current->sigmask_lock);
	current->blocked = set;
	recalc_sigpending(current);
	spin_unlock_irq(&current->sigmask_lock);
	return 0;
}
Esempio n. 7
0
static ssize_t read_nvram(struct file *file, char *buf,
			  size_t count, loff_t *ppos)
{
	unsigned int i;
	char *p = buf;

	if (verify_area(VERIFY_WRITE, buf, count))
		return -EFAULT;
	if (*ppos >= NVRAM_SIZE)
		return 0;
	for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count)
		if (__put_user(nvram_read_byte(i), p))
			return -EFAULT;
	*ppos = i;
	return p - buf;
}
Esempio n. 8
0
asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
{
    struct rt_sigframe __user *frame;
    sigset_t set;

    /* Always make any pending restarted system calls return -EINTR */
    current_thread_info()->restart_block.fn = do_no_restart_syscall;

    /*
     * Since we stacked the signal on a 64-bit boundary,
     * then 'sp' should be word aligned here.  If it's
     * not, then the user is trying to mess with us.
     */
    if (regs->ARM_sp & 7)
        goto badframe;

    frame = (struct rt_sigframe __user *)regs->ARM_sp;

    if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
        goto badframe;
    if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
        goto badframe;

    sigdelsetmask(&set, ~_BLOCKABLE);
    spin_lock_irq(&current->sighand->siglock);
    current->blocked = set;
    recalc_sigpending();
    spin_unlock_irq(&current->sighand->siglock);

    if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
        goto badframe;

    if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
        goto badframe;

    /* Send SIGTRAP if we're single-stepping */
    if (current->ptrace & PT_SINGLESTEP) {
        ptrace_cancel_bpt(current);
        send_sig(SIGTRAP, current, 1);
    }

    return regs->ARM_r0;

badframe:
    force_sig(SIGSEGV, current);
    return 0;
}
Esempio n. 9
0
asmlinkage long osf_proplist_syscall (enum pl_code code, union pl_args *args)
{
	long error;
	int *min_buf_size_ptr;

	switch (code) {
	      case PL_SET:
		error = verify_area(VERIFY_READ, &args->set.nbytes,
				    sizeof(args->set.nbytes));
		if (error)
		  return error;
		return args->set.nbytes;

	      case PL_FSET:
		error = verify_area(VERIFY_READ, &args->fset.nbytes,
				    sizeof(args->fset.nbytes));
		if (error)
		  return error;
		return args->fset.nbytes;

	      case PL_GET:
		error = verify_area(VERIFY_READ, &args->get.min_buf_size,
				    sizeof(args->get.min_buf_size));
		if (error)
		  return error;
		min_buf_size_ptr = get_user(&args->get.min_buf_size);
		error = verify_area(VERIFY_WRITE, min_buf_size_ptr,
				    sizeof(*min_buf_size_ptr));
		if (error)
		  return error;
		put_user(0, min_buf_size_ptr);
		return 0;

	      case PL_FGET:
		error = verify_area(VERIFY_READ, &args->fget.min_buf_size,
				    sizeof(args->fget.min_buf_size));
		if (error)
		  return error;
		min_buf_size_ptr = get_user(&args->fget.min_buf_size);
		error = verify_area(VERIFY_WRITE, min_buf_size_ptr,
				    sizeof(*min_buf_size_ptr));
		if (error)
		  return error;
		put_user(0, min_buf_size_ptr);
		return 0;

	      case PL_DEL:
	      case PL_FDEL:
		return 0;

	      default:
		return -EOPNOTSUPP;
	}
}
Esempio n. 10
0
/* This will check if all events are logged, if they are then, we
 * know that we can safely clear the events in NVRAM.
 * Next we'll sit and wait for something else to log.
 */
static ssize_t rtas_log_read(struct file * file, char * buf,
			 size_t count, loff_t *ppos)
{
	int error;
	char *tmp;
	unsigned long s;
	unsigned long offset;

	if (!buf || count < rtas_error_log_buffer_max)
		return -EINVAL;

	count = rtas_error_log_buffer_max;

	error = verify_area(VERIFY_WRITE, buf, count);
	if (error)
		return -EFAULT;

	tmp = kmalloc(count, GFP_KERNEL);
	if (!tmp)
		return -ENOMEM;


	spin_lock_irqsave(&log_lock, s);
	/* if it's 0, then we know we got the last one (the one in NVRAM) */
	if (rtas_log_size == 0 && !no_more_logging)
		nvram_clear_error_log();
	spin_unlock_irqrestore(&log_lock, s);


	error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
	if (error)
		goto out;

	spin_lock_irqsave(&log_lock, s);
	offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK);
	memcpy(tmp, &rtas_log_buf[offset], count);

	rtas_log_start += 1;
	rtas_log_size -= 1;
	spin_unlock_irqrestore(&log_lock, s);

	error = copy_to_user(buf, tmp, count) ? -EFAULT : count;
out:
	kfree(tmp);
	return error;
}
Esempio n. 11
0
void do_signal(long signr,
	/* system_call()提供 */
	long eax, long ebx, long ecx, long edx,
	long fs, long es, long ds,
	/* 中断自动进栈 */
	long eip, long cs, long eflags,
	unsigned long * esp, long ss)
{
	unsigned long sa_handler;
	long old_eip=eip;
	struct sigaction * sa = current->sigaction + signr - 1;
	int longs;
	unsigned long * tmp_esp;

	sa_handler = (unsigned long) sa->sa_handler; // 信号回调函数
	if (sa_handler==1) // 忽略此信号
		return;

	// 默认处理
	if (!sa_handler) {
		if (signr==SIGCHLD)
			return;
		else
			do_exit(1<<(signr-1));
	}

	// 如果只处理一次(signal)
	if (sa->sa_flags & SA_ONESHOT)
		sa->sa_handler = NULL;
	*(&eip) = sa_handler; // 修改堆栈中的eip
	longs = (sa->sa_flags & SA_NOMASK)?7:8;
	*(&esp) -= longs;
	verify_area(esp,longs*4);
	// 修改用户堆栈的数据
	tmp_esp=esp;
	put_fs_long((long) sa->sa_restorer,tmp_esp++);
	put_fs_long(signr,tmp_esp++);
	if (!(sa->sa_flags & SA_NOMASK))
		put_fs_long(current->blocked,tmp_esp++);
	put_fs_long(eax,tmp_esp++);
	put_fs_long(ecx,tmp_esp++);
	put_fs_long(edx,tmp_esp++);
	put_fs_long(eflags,tmp_esp++);
	put_fs_long(old_eip,tmp_esp++);  // 这个是用户程序的中断点
	current->blocked |= sa->sa_mask;
}
Esempio n. 12
0
int sys_readlink(const char * path, char * buf, int bufsiz)
{
	struct inode * inode;
	int error;

	if (bufsiz <= 0)
		return -EINVAL;
	verify_area(buf,bufsiz);
	error = lnamei(path,&inode);
	if (error)
		return error;
	if (!inode->i_op || !inode->i_op->readlink) {
		iput(inode);
		return -EINVAL;
	}
	return inode->i_op->readlink(inode,buf,bufsiz);
}
Esempio n. 13
0
static int get_termio(struct tty_struct * tty, struct termio * termio)
{
	int i;
	struct termio tmp_termio;

	verify_area(termio, sizeof (*termio));
	tmp_termio.c_iflag = tty->termios->c_iflag;
	tmp_termio.c_oflag = tty->termios->c_oflag;
	tmp_termio.c_cflag = tty->termios->c_cflag;
	tmp_termio.c_lflag = tty->termios->c_lflag;
	tmp_termio.c_line = tty->termios->c_line;
	for(i=0 ; i < NCC ; i++)
		tmp_termio.c_cc[i] = tty->termios->c_cc[i];
	for (i=0 ; i< (sizeof (*termio)) ; i++)
		put_fs_byte( ((char *)&tmp_termio)[i] , i+(char *)termio );
	return 0;
}
Esempio n. 14
0
/* 读取目录文件的一个目录 
 */
asmlinkage int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
{
	int error;
	struct file * file;
	struct inode * inode;

	if (fd >= NR_OPEN || !(file = current->filp[fd]) ||
	    !(inode = file->f_inode))
		return -EBADF;
	error = -ENOTDIR;
	if (file->f_op && file->f_op->readdir) {
		error = verify_area(VERIFY_WRITE, dirent, sizeof (*dirent));
		if (!error)
			error = file->f_op->readdir(inode,file,dirent,count);
	}
	return error;
}
Esempio n. 15
0
static int ioctl_probe(struct Scsi_Host * host, void *buffer)
{
	int temp;
	unsigned int len,slen;
	const char * string;
	
	if ((temp = host->hostt->present) && buffer) {
		len = get_fs_long ((unsigned long *) buffer);
		string = host->hostt->info();
		slen = strlen(string);
		if (len > slen)
			len = slen + 1;
		verify_area(VERIFY_WRITE, buffer, len);
		memcpy_tofs (buffer, string, len);
	}
	return temp;
}
Esempio n. 16
0
static int
sock_socketpair(int family, int type, int protocol, unsigned long usockvec[2])
{
  int fd1, fd2, i;
  struct socket *sock1, *sock2;
  int er;

  DPRINTF((net_debug,
	"NET: sock_socketpair: family = %d, type = %d, protocol = %d\n",
							family, type, protocol));

  /*
   * Obtain the first socket and check if the underlying protocol
   * supports the socketpair call.
   */
  if ((fd1 = sock_socket(family, type, protocol)) < 0) return(fd1);
  sock1 = sockfd_lookup(fd1, NULL);
  if (!sock1->ops->socketpair) {
	sys_close(fd1);
	return(-EINVAL);
  }

  /* Now grab another socket and try to connect the two together. */
  if ((fd2 = sock_socket(family, type, protocol)) < 0) {
	sys_close(fd1);
	return(-EINVAL);
  }
  sock2 = sockfd_lookup(fd2, NULL);
  if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
	sys_close(fd1);
	sys_close(fd2);
	return(i);
  }
  sock1->conn = sock2;
  sock2->conn = sock1;
  sock1->state = SS_CONNECTED;
  sock2->state = SS_CONNECTED;

  er=verify_area(VERIFY_WRITE, usockvec, 2 * sizeof(int));
  if(er)
  	return er;
  put_fs_long(fd1, &usockvec[0]);
  put_fs_long(fd2, &usockvec[1]);

  return(0);
}
Esempio n. 17
0
static ssize_t read_port(struct file * file, char * buf,
			 size_t count, loff_t *ppos)
{
	unsigned long i = *ppos;
	char *tmp = buf;

	if (verify_area(VERIFY_WRITE,buf,count))
		return -EFAULT; 
	while (count-- > 0 && i < 65536) {
		if (__put_user(inb(i),tmp) < 0) 
			return -EFAULT;  
		i++;
		tmp++;
	}
	*ppos = i;
	return tmp-buf;
}
Esempio n. 18
0
static int ioctl_probe(int dev, void *buffer)
{
	int temp;
	unsigned int len,slen;
	const char * string;
	
	if ((temp = scsi_hosts[dev].present) && buffer) {
		len = get_fs_long ((int *) buffer);
		string = scsi_hosts[dev].info();
		slen = strlen(string);
		if (len > slen)
			len = slen + 1;
		verify_area(VERIFY_WRITE, buffer, len);
		memcpy_tofs (buffer, string, len);
	}
	return temp;
}
Esempio n. 19
0
/* Read */
static ssize_t tun_chr_read(struct file * file, char * buf, 
			    size_t count, loff_t *pos)
{
	struct tun_struct *tun = (struct tun_struct *)file->private_data;
	DECLARE_WAITQUEUE(wait, current);
	struct sk_buff *skb;
	ssize_t ret = 0;

	DBG(KERN_INFO "%s: tun_chr_read\n", tun->name);

	add_wait_queue(&tun->read_wait, &wait);
	while (count) {
		current->state = TASK_INTERRUPTIBLE;

		/* Read frames from device queue */
		if (!(skb=skb_dequeue(&tun->txq))) {
			if (file->f_flags & O_NONBLOCK) {
				ret = -EAGAIN;
				break;
			}
			if (signal_pending(current)) {
				ret = -ERESTARTSYS;
				break;
			}

			/* Nothing to read, let's sleep */
			schedule();
			continue;
		}
		netif_start_queue(&tun->dev);

		if (!verify_area(VERIFY_WRITE, buf, count))
			ret = tun_put_user(tun, skb, buf, count);
		else
			ret = -EFAULT;

		kfree_skb(skb);
		break;
	}

	current->state = TASK_RUNNING;
	remove_wait_queue(&tun->read_wait, &wait);

	return ret;
}
Esempio n. 20
0
static int
sock_socketpair(int family, int type, int protocol, int usockvec[2])
{
	int fd1, fd2, i;
	struct socket *sock1, *sock2;

	PRINTK("sys_socketpair: family = %d, type = %d, protocol = %d\n",
	       family, type, protocol);

	/*
	 * obtain the first socket and check if the underlying protocol
	 * supports the socketpair call
	 */
	if ((fd1 = sock_socket(family, type, protocol)) < 0)
		return fd1;
	sock1 = sockfd_lookup(fd1, NULL);
	if (!sock1->ops->socketpair) {
		sys_close(fd1);
		return -EINVAL;
	}

	/*
	 * now grab another socket and try to connect the two together
	 */
	if ((fd2 = sock_socket(family, type, protocol)) < 0) {
		sys_close(fd1);
		return -EINVAL;
	}
	sock2 = sockfd_lookup(fd2, NULL);
	if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
		sys_close(fd1);
		sys_close(fd2);
		return i;
	}
	sock1->conn = sock2;
	sock2->conn = sock1;
	sock1->state = SS_CONNECTED;
	sock2->state = SS_CONNECTED;

	verify_area(usockvec, 2 * sizeof(int));
	put_fs_long(fd1, &usockvec[0]);
	put_fs_long(fd2, &usockvec[1]);

	return 0;
}
Esempio n. 21
0
/*
	the scsi_ioctl() function differs from most ioctls in that it does
	not take a major/minor number as the dev filed.  Rather, it takes
	a pointer to a scsi_devices[] element, a structure. 
*/
int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
{
        char scsi_cmd[10];

	if ((cmd != 0 && dev->index > NR_SCSI_DEVICES))
		return -ENODEV;
	if ((cmd == 0 && dev->host_no > max_scsi_hosts))
		return -ENODEV;
	
	switch (cmd) {
	        case SCSI_IOCTL_GET_IDLUN:
	                verify_area(VERIFY_WRITE, (void *) arg, sizeof(int));
			put_fs_long(dev->id + (dev->lun << 8) + 
				    (dev->host_no << 16), (long *) arg);
			return 0;
		case SCSI_IOCTL_PROBE_HOST:
			return ioctl_probe(dev->host_no, arg);
		case SCSI_IOCTL_SEND_COMMAND:
			return ioctl_command((Scsi_Device *) dev, arg);
		case SCSI_IOCTL_DOORLOCK:
			if (!dev->removable || !dev->lockable) return 0;
		        scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
			scsi_cmd[1] = dev->lun << 5;
			scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
			scsi_cmd[4] = SCSI_REMOVAL_PREVENT;
			return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
			break;
		case SCSI_IOCTL_DOORUNLOCK:
			if (!dev->removable || !dev->lockable) return 0;
		        scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
			scsi_cmd[1] = dev->lun << 5;
			scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
			scsi_cmd[4] = SCSI_REMOVAL_ALLOW;
			return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
		case SCSI_IOCTL_TEST_UNIT_READY:
		        scsi_cmd[0] = TEST_UNIT_READY;
			scsi_cmd[1] = dev->lun << 5;
			scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
			scsi_cmd[4] = 0;
			return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
			break;
		default :			
			return -EINVAL;
	}
}
Esempio n. 22
0
asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
{
	int error;
	struct file * file;
	struct inode * inode;
	int written;
	
	if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
		return -EBADF;
	if (!(file->f_mode & 2))
		return -EBADF;
	if (!file->f_op || !file->f_op->write)
		return -EINVAL;
	if (!count)
		return 0;
	error = locks_verify_area(FLOCK_VERIFY_WRITE,inode,file,file->f_pos,count);
	if (error)
		return error;
	error = verify_area(VERIFY_READ,buf,count);
	if (error)
		return error;
	/*
	 * If data has been written to the file, remove the setuid and
	 * the setgid bits. We do it anyway otherwise there is an
	 * extremely exploitable race - does your OS get it right |->
	 *
	 * Set ATTR_FORCE so it will always be changed.
	 */
	if (!suser() && (inode->i_mode & (S_ISUID | S_ISGID))) {
		struct iattr newattrs;
		/*
		 * Don't turn off setgid if no group execute. This special
		 * case marks candidates for mandatory locking.
		 */
		newattrs.ia_mode = inode->i_mode &
			~(S_ISUID | ((inode->i_mode & S_IXGRP) ? S_ISGID : 0));
		newattrs.ia_valid = ATTR_CTIME | ATTR_MODE | ATTR_FORCE;
		notify_change(inode, &newattrs);
	}

	down(&inode->i_sem);
	written = file->f_op->write(inode,file,buf,count);
	up(&inode->i_sem);
	return written;
}
Esempio n. 23
0
int abi_utsname(unsigned long addr)
{
	int error;
	struct svr4_utsname *it = (struct svr4_utsname *)addr;

	down_read(&uts_sem);
	error = verify_area(VERIFY_WRITE, it, sizeof (struct svr4_utsname));
	if (!error) {
		set_utsfield(it->sysname, system_utsname.sysname, 0);
		set_utsfield(it->nodename, system_utsname.nodename, 0);
		set_utsfield(it->release, system_utsname.release, 0);
		set_utsfield(it->version, system_utsname.version, 0);
		set_utsfield(it->machine, system_utsname.machine, 0);
	}
	up_read(&uts_sem);

	return error;
}
Esempio n. 24
0
/*
 * Clear the bytes in the last page of data.
 */
static int
coff_clear_memory(u_long addr, u_long size)
{
	int			err = 0;

	if ((size = (PAGE_SIZE - (addr & ~PAGE_MASK)) & ~PAGE_MASK) == 0)
		goto out;
	if ((err = verify_area(VERIFY_WRITE, (void *)addr, size)) < 0)
		goto out;

	while (size-- != 0) {
		__put_user(0, (char *)addr);
		addr++;
	}

out:
	return (err);
}
Esempio n. 25
0
asmlinkage int old_select(unsigned long *buffer)
{
	int n;
	fd_set *inp;
	fd_set *outp;
	fd_set *exp;
	struct timeval *tvp;

	n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
	if (n)
		return n;
	n = get_user(buffer);
	inp = (fd_set *) get_user(buffer+1);
	outp = (fd_set *) get_user(buffer+2);
	exp = (fd_set *) get_user(buffer+3);
	tvp = (struct timeval *) get_user(buffer+4);
	return sys_select(n, inp, outp, exp, tvp);
}
Esempio n. 26
0
asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
{
    int	i;

    if (!suser())
        return -EPERM;
    if (gidsetsize > NGROUPS)
        return -EINVAL;
    i = verify_area(VERIFY_READ, grouplist, sizeof(gid_t) * gidsetsize);
    if (i)
        return i;
    for (i = 0; i < gidsetsize; i++, grouplist++) {
        current->groups[i] = get_user(grouplist);
    }
    if (i < NGROUPS)
        current->groups[i] = NOGROUP;
    return 0;
}
Esempio n. 27
0
static int osf_procfs_mount(char * dirname, struct procfs_args * args, int flags)
{
	kdev_t dev;
	int retval;
	struct procfs_args tmp;

	retval = verify_area(VERIFY_READ, args, sizeof(*args));
	if (retval)
		return retval;
	memcpy_fromfs(&tmp, args, sizeof(tmp));
	dev = get_unnamed_dev();
	if (!dev)
		return -ENODEV;
	retval = do_mount(dev, "", dirname, "proc", flags, NULL);
	if (retval)
		put_unnamed_dev(dev);
	return retval;
}
Esempio n. 28
0
int wyse_getdomainname(char *name, int len)
{
	int error;
	char *p;

	down_read(&uts_sem);
	error = verify_area(VERIFY_WRITE, name, len);
	if (!error) {
		--len;
		for (p = system_utsname.domainname; *p && len; p++,len--) {
			__put_user(*p, name);
			name++;
		}
		__put_user('\0', name);
	}
	up_read(&uts_sem);
	return error;
}
Esempio n. 29
0
static int get_termio(struct tty_struct * tty, struct termio * termio)
{
	int i;
	struct termio tmp_termio;

	i = verify_area(VERIFY_WRITE, termio, sizeof (struct termio));
	if (i)
		return i;
	tmp_termio.c_iflag = tty->termios->c_iflag;
	tmp_termio.c_oflag = tty->termios->c_oflag;
	tmp_termio.c_cflag = tty->termios->c_cflag;
	tmp_termio.c_lflag = tty->termios->c_lflag;
	tmp_termio.c_line = tty->termios->c_line;
	for(i=0 ; i < NCC ; i++)
		tmp_termio.c_cc[i] = tty->termios->c_cc[i];
	memcpy_tofs(termio, &tmp_termio, sizeof (struct termio));
	return 0;
}
Esempio n. 30
0
static ssize_t proc_mpc_write(struct file *file, const char *buff,
                              size_t nbytes, loff_t *ppos)
{
        int incoming, error, retval;
        char *page, c;
        const char *tmp;

        if (nbytes < 0) return -EINVAL;
        if (nbytes == 0) return 0;
        if (nbytes > PAGE_SIZE) nbytes = PAGE_SIZE-1;

        error = verify_area(VERIFY_READ, buff, nbytes);
        if (error) return error;

        page = (char *)__get_free_page(GFP_KERNEL);
        if (page == NULL) return -ENOMEM;

        incoming = 0;
        tmp = buff;
        while(incoming < nbytes){
                if (get_user(c, tmp++)) return -EFAULT;
                incoming++;
                if (c == '\0' || c == '\n')
                        break;
        }

        retval = copy_from_user(page, buff, incoming);
        if (retval != 0) {
                printk("mpoa: proc_mpc_write: copy_from_user() failed\n");
                return -EFAULT;
        }

        *ppos += incoming;

        page[incoming] = '\0';
	retval = parse_qos(page, incoming);
        if (retval == 0)
                printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);

        free_page((unsigned long)page);
        
        return nbytes;
}