Esempio n. 1
0
int sys_readdir(unsigned int fd, char *dirent, unsigned int count
		/* ignored and unused, noted in Linux man page */ )
{
    int error;
    struct file *file;
    register struct file *filp;
    register struct file_operations *fop;
    struct readdir_callback buf;

    if ((error = fd_check(fd, dirent, sizeof(struct linux_dirent),
			  FMODE_READ, &file))
	>= 0) {
	error = -ENOTDIR;
	filp = file;
	fop = filp->f_op;
	if (fop && fop->readdir) {
	    buf.count = 0;
	    buf.dirent = (struct linux_dirent *) dirent;
	    if ((error = fop->readdir(filp->f_inode, filp,
				      &buf, fillonedir))
		>= 0)
		return buf.count;
	}
    }

    return error;
}
Esempio n. 2
0
int sys_read(unsigned int fd, char *buf, size_t count)
{
    register struct file_operations *fop;
    struct file *file;
    int retval;

    if (((retval = fd_check(fd, buf, count, FMODE_READ, &file)) == 0)
	&& count) {
	retval = -EINVAL;
	fop = file->f_op;
	if (fop->read) {
	    retval = (int) fop->read(file->f_inode, file, buf, count);
	    schedule();
	}
    }
    return retval;
}
Esempio n. 3
0
int sys_write(unsigned int fd, char *buf, size_t count)
{
    register struct file_operations *fop;
    struct file *file;
    register struct inode *inode;
    int written;

    if (((written = fd_check(fd, buf, count, FMODE_WRITE, &file)) == 0)
	&& (count != 0)) {
	written = -EINVAL;
	fop = file->f_op;
	if (fop->write) {
	    inode = file->f_inode;

	    /*
	     * 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))) {

#ifdef USE_NOTIFY_CHANGE
		struct iattr newattrs;
		newattrs.ia_mode = inode->i_mode & ~(S_ISUID | S_ISGID);
		newattrs.ia_valid = ATTR_CTIME | ATTR_MODE | ATTR_FORCE;
		notify_change(inode, &newattrs);
#else
		inode->i_mode = inode->i_mode & ~(S_ISUID | S_ISGID);
#endif

	    }
	    written = (int) fop->write(inode, file, buf, count);
	    schedule();
	}
    }
    return written;
}