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

Commit 5b1a43d7 authored by Al Viro's avatar Al Viro
Browse files

[PATCH] drivers/media/video __user annotations and fixes



* compat_alloc_user_space() returns __user pointer
* copying between two userland areas is copy_in_user(), not copy_from_user()
* dereferencing userland pointers is bad
* so's get_user() from local variables

... plus usual __user annotations

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent de125bf3
Loading
Loading
Loading
Loading
+41 −48
Original line number Diff line number Diff line
@@ -167,29 +167,32 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user
	if (kp->clipcount > 2048)
		return -EINVAL;
	if (kp->clipcount) {
		struct v4l2_clip32 *uclips = compat_ptr(up->clips);
		struct v4l2_clip *kclips;
		struct v4l2_clip32 __user *uclips;
		struct v4l2_clip __user *kclips;
		int n = kp->clipcount;
		compat_caddr_t p;

		if (get_user(p, &up->clips))
			return -EFAULT;
		uclips = compat_ptr(p);
		kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
		kp->clips = kclips;
		while (--n >= 0) {
			if (!access_ok(VERIFY_READ, &uclips->c, sizeof(uclips->c)) ||
				copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
			if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
				return -EFAULT;
			if (put_user(n ? kclips + 1 : NULL, &kclips->next))
				return -EFAULT;
			kclips->next = n ? kclips + 1 : 0;
			uclips += 1;
			kclips += 1;
		}
	} else
		kp->clips = 0;
		kp->clips = NULL;
	return 0;
}

static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
{
	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_window32)) ||
		copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
	if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
		put_user(kp->field, &up->field) ||
		put_user(kp->chromakey, &up->chromakey) ||
		put_user(kp->clipcount, &up->clipcount))
@@ -199,32 +202,28 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user

static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
{
	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_pix_format)) ||
		copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
	if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
		return -EFAULT;
	return 0;
}

static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
{
	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_pix_format)) ||
		copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
	if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
		return -EFAULT;
	return 0;
}

static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
{
	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_vbi_format)) ||
		copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
	if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
		return -EFAULT;
	return 0;
}

static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
{
	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_vbi_format)) ||
		copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
	if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
		return -EFAULT;
	return 0;
}
@@ -279,8 +278,7 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user

static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
{
	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard)) ||
		copy_from_user(kp, up, sizeof(struct v4l2_standard)))
	if (copy_from_user(kp, up, sizeof(struct v4l2_standard)))
		return -EFAULT;
	return 0;

@@ -288,8 +286,7 @@ static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standa

static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
{
	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard)) ||
		copy_to_user(up, kp, sizeof(struct v4l2_standard)))
	if (copy_to_user(up, kp, sizeof(struct v4l2_standard)))
		return -EFAULT;
	return 0;
}
@@ -328,8 +325,7 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32

static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
{
	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_tuner)) ||
		copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
	if (copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
		return -EFAULT;
	return 0;

@@ -337,8 +333,7 @@ static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user

static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
{
	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_tuner)) ||
		copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
	if (copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
		return -EFAULT;
	return 0;
}
@@ -380,11 +375,13 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
		break;
	case V4L2_MEMORY_USERPTR:
		{
		unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr);
		compat_long_t tmp;

		if (get_user(kp->length, &up->length) ||
			get_user(kp->m.userptr, &tmp))
		    get_user(tmp, &up->m.userptr))
			return -EFAULT;

		kp->m.userptr = (unsigned long)compat_ptr(tmp);
		}
		break;
	case V4L2_MEMORY_OVERLAY:
@@ -468,32 +465,28 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame

static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
{
	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input) - 4) ||
		copy_from_user(kp, up, sizeof(struct v4l2_input) - 4))
	if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4))
		return -EFAULT;
	return 0;
}

static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
{
	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input) - 4) ||
		copy_to_user(up, kp, sizeof(struct v4l2_input) - 4))
	if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4))
		return -EFAULT;
	return 0;
}

static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
{
	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input)) ||
		copy_from_user(kp, up, sizeof(struct v4l2_input)))
	if (copy_from_user(kp, up, sizeof(struct v4l2_input)))
		return -EFAULT;
	return 0;
}

static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
{
	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input)) ||
		copy_to_user(up, kp, sizeof(struct v4l2_input)))
	if (copy_to_user(up, kp, sizeof(struct v4l2_input)))
		return -EFAULT;
	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -549,7 +549,7 @@ struct v4l2_framebuffer
struct v4l2_clip
{
	struct v4l2_rect        c;
	struct v4l2_clip	*next;
	struct v4l2_clip	__user *next;
};

struct v4l2_window