Commit 13ad98ea authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull fbdev fixes from Helge Deller:
 "Four small patches for fbdev, of which two are important: One fixes
  the bitmap font generation and the other prevents a possible
  use-after-free in udlfb:

   - Fix rotating fonts by 180 degrees (Thomas Zimmermann)

   - Drop duplicate include of linux/module.h in fb_defio (Chen Ni)

   - Add vm_ops in udlfb to prevent use-after-free (Rajat Gupta)

   - ipu-v3: clean up kernel-doc warnings (Randy Dunlap)"

* tag 'fbdev-for-7.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev:
  fbdev: udlfb: add vm_ops to dlfb_ops_mmap to prevent use-after-free
  lib/fonts: Fix bit position when rotating by 180 degrees
  fbdev: defio: Remove duplicate include of linux/module.h
  fbdev: ipu-v3: clean up kernel-doc warnings
parents 9207d47f 8de779dc
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@
#include <linux/export.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+30 −1
Original line number Diff line number Diff line
@@ -321,12 +321,32 @@ static int dlfb_set_video_mode(struct dlfb_data *dlfb,
	return retval;
}

static void dlfb_vm_open(struct vm_area_struct *vma)
{
	struct dlfb_data *dlfb = vma->vm_private_data;

	atomic_inc(&dlfb->mmap_count);
}

static void dlfb_vm_close(struct vm_area_struct *vma)
{
	struct dlfb_data *dlfb = vma->vm_private_data;

	atomic_dec(&dlfb->mmap_count);
}

static const struct vm_operations_struct dlfb_vm_ops = {
	.open  = dlfb_vm_open,
	.close = dlfb_vm_close,
};

static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
	unsigned long start = vma->vm_start;
	unsigned long size = vma->vm_end - vma->vm_start;
	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
	unsigned long page, pos;
	struct dlfb_data *dlfb = info->par;

	if (info->fbdefio)
		return fb_deferred_io_mmap(info, vma);
@@ -358,6 +378,9 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
			size = 0;
	}

	vma->vm_ops = &dlfb_vm_ops;
	vma->vm_private_data = dlfb;
	atomic_inc(&dlfb->mmap_count);
	return 0;
}

@@ -1176,7 +1199,6 @@ static void dlfb_deferred_vfree(struct dlfb_data *dlfb, void *mem)

/*
 * Assumes &info->lock held by caller
 * Assumes no active clients have framebuffer open
 */
static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info, u32 new_len)
{
@@ -1188,6 +1210,13 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info
	new_len = PAGE_ALIGN(new_len);

	if (new_len > old_len) {
		if (atomic_read(&dlfb->mmap_count) > 0) {
			dev_warn(info->dev,
				"refusing realloc: %d active mmaps\n",
				atomic_read(&dlfb->mmap_count));
			return -EBUSY;
		}

		/*
		 * Alloc system memory for virtual framebuffer
		 */
+11 −5
Original line number Diff line number Diff line
@@ -27,12 +27,13 @@ struct ipu_image_convert_run {

	int status;

	/* private: */
	/* internal to image converter, callers don't touch */
	struct list_head list;
};

/**
 * ipu_image_convert_cb_t - conversion callback function prototype
 * typedef ipu_image_convert_cb_t - conversion callback function prototype
 *
 * @run:	the completed conversion run pointer
 * @ctx:	a private context pointer for the callback
@@ -60,7 +61,7 @@ void ipu_image_convert_adjust(struct ipu_image *in, struct ipu_image *out,
 * @out:	output image format
 * @rot_mode:	rotation mode
 *
 * Returns 0 if the formats and rotation mode meet IPU restrictions,
 * Returns: 0 if the formats and rotation mode meet IPU restrictions,
 * -EINVAL otherwise.
 */
int ipu_image_convert_verify(struct ipu_image *in, struct ipu_image *out,
@@ -77,11 +78,11 @@ int ipu_image_convert_verify(struct ipu_image *in, struct ipu_image *out,
 * @complete:	run completion callback
 * @complete_context:	a context pointer for the completion callback
 *
 * Returns an opaque conversion context pointer on success, error pointer
 * In V4L2, drivers should call ipu_image_convert_prepare() at streamon.
 *
 * Returns: an opaque conversion context pointer on success, error pointer
 * on failure. The input/output formats and rotation mode must already meet
 * IPU retrictions.
 *
 * In V4L2, drivers should call ipu_image_convert_prepare() at streamon.
 */
struct ipu_image_convert_ctx *
ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task,
@@ -122,6 +123,8 @@ void ipu_image_convert_unprepare(struct ipu_image_convert_ctx *ctx);
 * In V4L2, drivers should call ipu_image_convert_queue() while
 * streaming to queue the conversion of a received input buffer.
 * For example mem2mem devices this would be called in .device_run.
 *
 * Returns: 0 on success or -errno on error.
 */
int ipu_image_convert_queue(struct ipu_image_convert_run *run);

@@ -155,6 +158,9 @@ void ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx);
 * On successful return the caller can queue more run requests if needed, using
 * the prepared context in run->ctx. The caller is responsible for unpreparing
 * the context when no more conversion requests are needed.
 *
 * Returns: pointer to the created &struct ipu_image_convert_run that has
 * been queued on success; an ERR_PTR(errno) on error.
 */
struct ipu_image_convert_run *
ipu_image_convert(struct ipu_soc *ipu, enum ipu_ic_task ic_task,
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ struct dlfb_data {
	spinlock_t damage_lock;
	struct work_struct damage_work;
	struct fb_ops ops;
	atomic_t mmap_count;
	/* blit-only rendering path metrics, exposed through sysfs */
	atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */
	atomic_t bytes_identical; /* saved effort with backbuffer comparison */
+1 −1
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ static void __font_glyph_rotate_180(const unsigned char *glyph,
	for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
			if (font_glyph_test_bit(glyph, x, y, bit_pitch)) {
				font_glyph_set_bit(out, width - (1 + x + shift), height - (1 + y),
				font_glyph_set_bit(out, bit_pitch - 1 - x - shift, height - 1 - y,
						   bit_pitch);
			}
		}