Esempio n. 1
0
arg_t _ioctl(void)
{
	inoptr ino;
	uint16_t dev;

	if ((ino = getinode(fd)) == NULLINODE)
		return -1;

	if (!(isdevice(ino))) {
		udata.u_error = ENOTTY;
		return -1;
	}

	if ((request & IOCTL_SUPER) && esuper())
	        return -1;

	if (!(getperm(ino) & OTH_WR)) {
		udata.u_error = EPERM;
		return -1;
	}

	dev = ino->c_node.i_addr[0];

	/* top bit of request is reserved for kernel originated magic */
	return d_ioctl(dev, request & 0x7FFF, data);
}
Esempio n. 2
0
File: vt.c Progetto: Rappalot/FUZIX
int vt_ioctl(uint8_t minor, uarg_t request, char *data)
{
	/* FIXME: need to address the multiple vt switching case
	   here.. probably need to switch vt */
	if (minor <= MAX_VT) {
		switch(request) {
#ifdef KEY_ROWS
			case KBMAPSIZE:
				return KEY_ROWS << 8 | KEY_COLS;
			case KBMAPGET:
				return uput(keymap, data, sizeof(keymap));
			case KBSETTRANS:
				if (esuper())
					return -1;
				if (uget(keyboard, data, sizeof(keyboard)) == -1)
					return -1;
				return uget(shiftkeyboard,
					data + sizeof(keyboard),
					sizeof(shiftkeyboard));
#endif					
			case VTSIZE:
				return VT_HEIGHT << 8 | VT_WIDTH;
			case VTATTRS:
				return vtattr_cap;
		}
	}
	return tty_ioctl(minor, request, data);
}
Esempio n. 3
0
arg_t _setrlimit(void)
{
	staticfast struct rlimit r;
	struct rlimit *o;

	if (res < 0 || res >= NRLIMIT)
		goto bad;

	if (uget(rlim, &r, sizeof(struct rlimit)))
		return -1;

	o = udata.u_rlimit + res;
	if (r.rlim_cur > r.rlim_max)
		goto bad;

	/* Securit check */
	if ((r.rlim_cur > o->rlim_max || r.rlim_max > o->rlim_max) && esuper())
		return -1;
	o->rlim_cur = r.rlim_cur;
	o->rlim_max = r.rlim_max;
	return 0;
bad:	
	udata.u_error = EINVAL;
	return -1;
}
Esempio n. 4
0
arg_t _acct(void)
{
#ifdef CONFIG_ACCT
        inoptr inode;
        if (esuper())
                return -1;
        if (acct_fh != -1)
                oft_deref(acct_fh);
        if (fd != -1) {
                if ((inode = getinode(fd)) == NULLINODE)
                        return -1;
                if (getmode(inode) != F_REG) {
                        udata.u_error = EINVAL;
                        return -1;
                }
		if (inode->c_flags & CRDONLY) {
			udata.u_error = EROFS;
			return -1;
		}
        	acct_fh = udata.u_files[fd];
        	++of_tab[acct_fh].o_refs;
        }
	return 0;
#else
        udata.u_error = EINVAL;
        return -1;
#endif        
}
Esempio n. 5
0
arg_t make_socket(struct sockinfo *s, struct socket **np)
{
	struct socket *n;
	int8_t uindex;
	int8_t oftindex;
	inoptr ino;

	/* RAW sockets are superuser */
	if (s->priv && esuper())
		return -1;

	if (np)
		n = *np;
	else {
		n = alloc_socket();
		if (n == NULL)
			return -1;
	}
	n->s_type = s - socktypes;	/* Pointer or uint8_t best ? */
	n->s_state = SS_INIT;

	if (net_init(n) == -1)
		goto nosock;

	/* Start by getting the file and inode table entries */
	if ((uindex = uf_alloc()) == -1)
		goto nosock;
	if ((oftindex = oft_alloc()) == -1)
		goto nooft;

	/* We need an inode : FIXME - do we want a pipedev aka Unix ? */
	if (!(ino = i_open(root_dev, 0)))
		goto noalloc;
	/* All good - now set it up */
	/* The nlink cheat needs to be taught to fsck! */
	ino->c_node.i_mode = F_SOCK | 0777;
	ino->c_node.i_nlink = n->s_num;	/* Cheat !! */
	ino->c_readers = 1;
	ino->c_writers = 1;

	of_tab[oftindex].o_inode = ino;
	of_tab[oftindex].o_access = O_RDWR;

	udata.u_files[uindex] = oftindex;

	sock_wait_leave(n, 0, SS_INIT);
	if (np)
		*np = n;
	return uindex;

noalloc:
	oft_deref(oftindex);	/* Will call i_deref! */
nooft:
	udata.u_files[uindex] = NO_FILE;
nosock:
	n->s_state = SS_UNUSED;
	return -1;
}
Esempio n. 6
0
arg_t _chroot(void)
{
	inoptr newroot;

	if (esuper())
		return (-1);
	if (!(newroot = n_open(dir, NULLINOPTR)))
		return (-1);
	return chdiroot_op(newroot, &udata.u_root);
}
Esempio n. 7
0
arg_t _link(void)
{
	inoptr ino;
	inoptr ino2;
	inoptr parent2;
	char fname[FILENAME_LEN + 1];

	if (!(ino = n_open(name1, NULLINOPTR)))
		return (-1);

	if (getmode(ino) == F_DIR && esuper())
		goto nogood;

	if (ino->c_node.i_nlink == 0xFFFF) {
		udata.u_error = EMLINK;
		goto nogood;
	}

	/* Make sure file2 doesn't exist, and get its parent */
	if ((ino2 = n_open(name2, &parent2)) != NULL) {
		i_deref(ino2);
		i_deref(parent2);
		udata.u_error = EEXIST;
		goto nogood;
	}

	if (!parent2)
		goto nogood;

	if (ino->c_dev != parent2->c_dev) {
		i_deref(parent2);
		udata.u_error = EXDEV;
		goto nogood;
	}

	filename(name2, fname);

	if (!ch_link(parent2, "", fname, ino)) {
		i_deref(parent2);
		goto nogood;
	}

	/* Update the link count. */
	++ino->c_node.i_nlink;
	wr_inode(ino);
	setftime(ino, C_TIME);

	i_deref(parent2);
	i_deref(ino);
	return 0;

      nogood:
	i_deref(ino);
	return -1;
}
Esempio n. 8
0
static int chown_op(inoptr ino)
{
	if (ino->c_node.i_uid != udata.u_euid && esuper()) {
		i_deref(ino);
		return (-1);
	}
	ino->c_node.i_uid = owner;
	ino->c_node.i_gid = group;
	setftime(ino, C_TIME);
	return 0;
}
Esempio n. 9
0
arg_t _stime(void)
{
	time_t t;
	if (type != 0) {
		udata.u_error = EINVAL;
		return -1;
	}
	if (uget(&t, tvec, sizeof(t)) || esuper())
		return -1;
	wrtime(&t);
	return (-1);
}
Esempio n. 10
0
static int16_t chmod_op(inoptr ino)
{
	if (ino->c_node.i_uid != udata.u_euid && esuper()) {
		i_deref(ino);
		return (-1);
	}

	ino->c_node.i_mode =
	    (mode & MODE_MASK) | (ino->c_node.i_mode & F_MASK);
	setftime(ino, C_TIME);
	return 0;
}
Esempio n. 11
0
arg_t _setgroups(void)
{
	if (esuper())
		return -1;
	if (ngroup < 0 || ngroup > NGROUP) {
		udata.u_error = EINVAL;
		return -1;
	}
	if (ngroup && uget(groups, udata.u_groups, ngroup * sizeof(uint16_t)))
		return -1;
	udata.u_ngroup = ngroup;
	return 0;
}
Esempio n. 12
0
static int chown_op(inoptr ino)
{
	if (ino->c_node.i_uid != udata.u_euid && esuper())
		return (-1);
	if (ino->c_flags & CRDONLY) {
		udata.u_error = EROFS;
		return -1;
	}
	ino->c_node.i_uid = owner;
	ino->c_node.i_gid = group;
	setftime(ino, C_TIME);
	return 0;
}
Esempio n. 13
0
arg_t make_socket(struct sockinfo *s, int8_t *np)
{
	int8_t n;
	int8_t uindex;
	int8_t oftindex;
	inoptr ino;

	/* RAW sockets are superuser */
	if (s->priv && esuper())
		return -1;

	/* Start by getting the file and inode table entries */
	if ((uindex = uf_alloc()) == -1)
		return -1;
	if ((oftindex = oft_alloc()) == -1)
		goto nooft;

	if (np)
		n = *np;
	else {
		n = alloc_socket();
		if (n == -1)
			goto noalloc;
	}
	/* We need an inode : FIXME - do we want a pipedev aka Unix ? */
	if (!(ino = i_open(root_dev, 0)))
		goto noalloc;
	/* All good - now set it up */
	/* The nlink cheat needs to be taught to fsck! */
	ino->c_node.i_mode = F_SOCK | 0777;
	ino->c_node.i_nlink = n;	/* Cheat !! */

	of_tab[oftindex].o_inode = ino;
	of_tab[oftindex].o_access = O_RDWR;

	udata.u_files[uindex] = oftindex;

	sockets[n].s_inode = ino;
	sockets[n].s_type = s - socktypes;	/* Pointer or uint8_t best ? */
	sockets[n].s_state = SS_UNCONNECTED;

	if (np)
		*np = n;
	return uindex;

noalloc:
	oft_deref(oftindex);	/* Will call i_deref! */
nooft:
	udata.u_files[uindex] = NO_FILE;
	return -1;
}
Esempio n. 14
0
static arg_t chmod_op(inoptr ino)
{
	if (ino->c_node.i_uid != udata.u_euid && esuper())
		return (-1);
	if (ino->c_flags & CRDONLY) {
		udata.u_error = EROFS;
		return -1;
	}

	ino->c_node.i_mode =
	    (mode & MODE_MASK) | (ino->c_node.i_mode & F_MASK);
	setftime(ino, C_TIME);
	return 0;
}
Esempio n. 15
0
int16_t _utime(void)
{
	inoptr ino;
	time_t t[2];

	if (!valaddr(buf, 2 * sizeof(time_t)))
		return (-1);
	if (!(ino = n_open(file, NULLINOPTR)))
		return (-1);
	if (ino->c_node.i_uid != udata.u_euid && esuper()) {
		i_deref(ino);
		return (-1);
	}
	uget(buf, t, 2 * sizeof(time_t));
	/* FIXME: needs updating once we pack top bits
	   elsewhere in the inode */
	ino->c_node.i_atime = t[0];
	ino->c_node.i_mtime = t[1];
	setftime(ino, C_TIME);
	i_deref(ino);
	return (0);
}
Esempio n. 16
0
arg_t _utime(void)
{
	inoptr ino;
	time_t t[2];

	if (!(ino = n_open(file, NULLINOPTR)))
		return (-1);
	if (ino->c_flags & CRDONLY) {
		udata.u_error = EROFS;
		goto out2;
	}
	/* Special case in the Unix API - NULL means now */
	if (buf) {
	        if (ino->c_node.i_uid != udata.u_euid && esuper())
			goto out;
		if (!valaddr(buf, 2 * sizeof(time_t)))
			goto out2;
		uget(buf, t, 2 * sizeof(time_t));
	} else {
	        if (!(getperm(ino) & OTH_WR))
			goto out;
	        rdtime(&t[0]);
	        memcpy(&t[1], &t[0], sizeof(t[1]));
        }
	/* FIXME: needs updating once we pack top bits
	   elsewhere in the inode */
	ino->c_node.i_atime = t[0].low;
	ino->c_node.i_mtime = t[1].low;
	setftime(ino, C_TIME);
	i_deref(ino);
	return (0);
out:
	udata.u_error = EPERM;
out2:
	i_deref(ino);
	return -1;
}