Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3af07613 authored by Al Viro's avatar Al Viro
Browse files

cx25821: sanitize cx25821_openfile_audio() a bit...



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2ce8fce2
Loading
Loading
Loading
Loading
+28 −68
Original line number Diff line number Diff line
@@ -321,81 +321,41 @@ static void cx25821_audioups_handler(struct work_struct *work)
static int cx25821_openfile_audio(struct cx25821_dev *dev,
			   struct sram_channel *sram_ch)
{
	struct file *myfile;
	int i = 0, j = 0;
	int line_size = AUDIO_LINE_SIZE;
	ssize_t vfs_read_retval = 0;
	char mybuf[line_size];
	loff_t pos;
	loff_t offset = (unsigned long)0;
	mm_segment_t old_fs;

	myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);

	if (IS_ERR(myfile)) {
		const int open_errno = -PTR_ERR(myfile);
		pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
			__func__, dev->_audiofilename, open_errno);
		return PTR_ERR(myfile);
	} else {
		if (!(myfile->f_op)) {
			pr_err("%s(): File has no file operations registered!\n",
				__func__);
			filp_close(myfile, NULL);
			return -EIO;
		}
	char *p = (void *)dev->_audiodata_buf_virt_addr;
	struct file *file;
	loff_t offset;
	int i, j;

		if (!myfile->f_op->read) {
			pr_err("%s(): File has no READ operations registered!\n",
				__func__);
			filp_close(myfile, NULL);
			return -EIO;
	file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
	if (IS_ERR(file)) {
		pr_err("%s(): ERROR opening file(%s) with errno = %ld!\n",
			__func__, dev->_audiofilename, PTR_ERR(file));
		return PTR_ERR(file);
	}

		pos = myfile->f_pos;
		old_fs = get_fs();
		set_fs(KERNEL_DS);

		for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
	for (j = 0, offset = 0; j < NUM_AUDIO_FRAMES; j++) {
		for (i = 0; i < dev->_audio_lines_count; i++) {
				pos = offset;

				vfs_read_retval = vfs_read(myfile, mybuf,
						line_size, &pos);

				if (vfs_read_retval > 0 &&
				    vfs_read_retval == line_size &&
				    dev->_audiodata_buf_virt_addr != NULL) {
					memcpy((void *)(dev->
							_audiodata_buf_virt_addr
							+ offset / 4), mybuf,
					       vfs_read_retval);
				}
			char buf[AUDIO_LINE_SIZE];
			int n = kernel_read(file, offset, buf,
						AUDIO_LINE_SIZE);

				offset += vfs_read_retval;

				if (vfs_read_retval < line_size) {
			if (n < AUDIO_LINE_SIZE) {
				pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
					__func__);
					break;
				}
				dev->_audiofile_status = END_OF_FILE;
				fput(file);
				return 0;
			}

			if (i > 0)
				dev->_audioframe_count++;
			if (p)
				memcpy(p + offset, buf, n);

			if (vfs_read_retval < line_size)
				break;
			offset += n;
		}

		dev->_audiofile_status = (vfs_read_retval == line_size) ?
						IN_PROGRESS : END_OF_FILE;

		set_fs(old_fs);
		myfile->f_pos = 0;
		filp_close(myfile, NULL);
		dev->_audioframe_count++;
	}

	dev->_audiofile_status = IN_PROGRESS;
	fput(file);
	return 0;
}