/* This is a simplified version of a real bug found in the kernel
   using cqual. */

static inline unsigned long
copy_from_user(void * to, const void   * from, unsigned long n);

void * kmalloc(int, int);


struct msg {
 	short len;
 	char *buf;
};

struct ioctl_data
{
	struct msg *msgs;
	int nmsgs;
};

int dev_ioctl (long arg)
{
	struct ioctl_data karg;
	struct msg * msgs;
	int i;

	copy_from_user(&karg, (struct ioctl_data *)arg, sizeof(karg));
	/* At this point, karg.msgs is a user pointer */

	msgs = kmalloc(karg.nmsgs * sizeof(*msgs), 0);
	copy_from_user(msgs, karg.msgs, karg.nmsgs * sizeof(*msgs));

	for (i = 0; i < karg.nmsgs; i++) {
		msgs[i].buf = kmalloc(msgs[i].len, 0);
		
		/* ERROR! loading the value "karg.msgs[i].buf" from
		   memory requires dereferencing a user pointer. */
		copy_from_user(msgs[i].buf, karg.msgs[i].buf, msgs[i].len);
	}

}
