void *xt_copy_counters(sockptr_t arg, unsigned int len,
		       struct xt_counters_info *info)
{
	size_t offset;
	void *mem;
	u64 size;

#ifdef CONFIG_COMPAT
	if (in_compat_syscall()) {
		/* structures only differ in size due to alignment */
		struct compat_xt_counters_info compat_tmp;

		if (len <= sizeof(compat_tmp))
			return ERR_PTR(-EINVAL);

		len -= sizeof(compat_tmp);
		if (copy_from_sockptr(&compat_tmp, arg, sizeof(compat_tmp)) != 0)
			return ERR_PTR(-EFAULT);

		memcpy(info->name, compat_tmp.name, sizeof(info->name) - 1);
		info->num_counters = compat_tmp.num_counters;
		offset = sizeof(compat_tmp);
	} else
#endif
	{
		if (len <= sizeof(*info))
			return ERR_PTR(-EINVAL);

		len -= sizeof(*info);
		if (copy_from_sockptr(info, arg, sizeof(*info)) != 0)
			return ERR_PTR(-EFAULT);

		offset = sizeof(*info);
	}
	info->name[sizeof(info->name) - 1] = '\0';

	size = sizeof(struct xt_counters);
	size *= info->num_counters;

	if (size != (u64)len)
		return ERR_PTR(-EINVAL);

	mem = vmalloc(len);
	if (!mem)
		return ERR_PTR(-ENOMEM);

	if (copy_from_sockptr_offset(mem, arg, offset, len) == 0)
		return mem;

	vfree(mem);
	return ERR_PTR(-EFAULT);
}
void *xt_copy_counters(sockptr_t arg, unsigned int len,
		       struct xt_counters_info *info)
{
	size_t offset;
	void *mem;
	u64 size;

#ifdef CONFIG_COMPAT
	if (in_compat_syscall()) {
		 
		struct compat_xt_counters_info compat_tmp;

		if (len <= sizeof(compat_tmp))
			return ERR_PTR(-EINVAL);

		len -= sizeof(compat_tmp);
		if (copy_from_sockptr(&compat_tmp, arg, sizeof(compat_tmp)) != 0)
			return ERR_PTR(-EFAULT);

		memcpy(info->name, compat_tmp.name, sizeof(info->name) - 1);
		info->num_counters = compat_tmp.num_counters;
		offset = sizeof(compat_tmp);
	} else
#endif
	{
		if (len <= sizeof(*info))
			return ERR_PTR(-EINVAL);

		len -= sizeof(*info);
		if (copy_from_sockptr(info, arg, sizeof(*info)) != 0)
			return ERR_PTR(-EFAULT);

		offset = sizeof(*info);
	}
	info->name[sizeof(info->name) - 1] = '\0';

	size = sizeof(struct xt_counters);
	size *= info->num_counters;

	if (size != (u64)len)
		return ERR_PTR(-EINVAL);

	mem = vmalloc(len);
	if (!mem)
		return ERR_PTR(-ENOMEM);

	if (copy_from_sockptr_offset(mem, arg, offset, len) == 0)
		return mem;

	vfree(mem);
	return ERR_PTR(-EFAULT);
}