Commit d3c48151 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David S. Miller
Browse files

net: remove sockptr_advance



sockptr_advance never properly worked.  Replace it with _offset variants
of copy_from_sockptr and copy_to_sockptr.

Fixes: ba423fda ("net: add a new sockptr_t type")
Reported-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Reported-by: default avatarIdo Schimmel <idosch@idosch.org>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Tested-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 035bfd05
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -525,9 +525,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
		/* Obtain version and type from previous copy */
		crypto_info[0] = tmp_crypto_info;
		/* Now copy the following data */
		sockptr_advance(optval, sizeof(*crypto_info));
		rc = copy_from_sockptr((char *)crypto_info + sizeof(*crypto_info),
				optval,
		rc = copy_from_sockptr_offset((char *)crypto_info +
				sizeof(*crypto_info),
				optval, sizeof(*crypto_info),
				sizeof(struct tls12_crypto_info_aes_gcm_128)
				- sizeof(*crypto_info));

@@ -542,9 +542,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
	}
	case TLS_CIPHER_AES_GCM_256: {
		crypto_info[0] = tmp_crypto_info;
		sockptr_advance(optval, sizeof(*crypto_info));
		rc = copy_from_sockptr((char *)crypto_info + sizeof(*crypto_info),
				    optval,
		rc = copy_from_sockptr_offset((char *)crypto_info +
				sizeof(*crypto_info),
				optval, sizeof(*crypto_info),
				sizeof(struct tls12_crypto_info_aes_gcm_256)
				- sizeof(*crypto_info));

+13 −14
Original line number Diff line number Diff line
@@ -69,19 +69,26 @@ static inline bool sockptr_is_null(sockptr_t sockptr)
	return !sockptr.user;
}

static inline int copy_from_sockptr(void *dst, sockptr_t src, size_t size)
static inline int copy_from_sockptr_offset(void *dst, sockptr_t src,
		size_t offset, size_t size)
{
	if (!sockptr_is_kernel(src))
		return copy_from_user(dst, src.user, size);
	memcpy(dst, src.kernel, size);
		return copy_from_user(dst, src.user + offset, size);
	memcpy(dst, src.kernel + offset, size);
	return 0;
}

static inline int copy_to_sockptr(sockptr_t dst, const void *src, size_t size)
static inline int copy_from_sockptr(void *dst, sockptr_t src, size_t size)
{
	return copy_from_sockptr_offset(dst, src, 0, size);
}

static inline int copy_to_sockptr_offset(sockptr_t dst, size_t offset,
		const void *src, size_t size)
{
	if (!sockptr_is_kernel(dst))
		return copy_to_user(dst.user, src, size);
	memcpy(dst.kernel, src, size);
		return copy_to_user(dst.user + offset, src, size);
	memcpy(dst.kernel + offset, src, size);
	return 0;
}

@@ -112,14 +119,6 @@ static inline void *memdup_sockptr_nul(sockptr_t src, size_t len)
	return p;
}

static inline void sockptr_advance(sockptr_t sockptr, size_t len)
{
	if (sockptr_is_kernel(sockptr))
		sockptr.kernel += len;
	else
		sockptr.user += len;
}

static inline long strncpy_from_sockptr(char *dst, sockptr_t src, size_t count)
{
	if (sockptr_is_kernel(src)) {
+2 −3
Original line number Diff line number Diff line
@@ -426,9 +426,8 @@ static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
			return -ENOMEM;

		sl->dccpsl_nr = optlen / sizeof(u32) - 1;
		sockptr_advance(optval, sizeof(service));
		if (copy_from_sockptr(sl->dccpsl_list, optval,
				      optlen - sizeof(service)) ||
		if (copy_from_sockptr_offset(sl->dccpsl_list, optval,
				sizeof(service), optlen - sizeof(service)) ||
		    dccp_list_has_service(sl, DCCP_SERVICE_INVALID_VALUE)) {
			kfree(sl);
			return -EFAULT;
+4 −4
Original line number Diff line number Diff line
@@ -971,8 +971,8 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
		return -ENOMEM;

	loc_cpu_entry = newinfo->entries;
	sockptr_advance(arg, sizeof(tmp));
	if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
	if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
			tmp.size) != 0) {
		ret = -EFAULT;
		goto free_newinfo;
	}
@@ -1267,8 +1267,8 @@ static int compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
		return -ENOMEM;

	loc_cpu_entry = newinfo->entries;
	sockptr_advance(arg, sizeof(tmp));
	if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
	if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
			tmp.size) != 0) {
		ret = -EFAULT;
		goto free_newinfo;
	}
+4 −4
Original line number Diff line number Diff line
@@ -1126,8 +1126,8 @@ do_replace(struct net *net, sockptr_t arg, unsigned int len)
		return -ENOMEM;

	loc_cpu_entry = newinfo->entries;
	sockptr_advance(arg, sizeof(tmp));
	if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
	if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
			tmp.size) != 0) {
		ret = -EFAULT;
		goto free_newinfo;
	}
@@ -1508,8 +1508,8 @@ compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
		return -ENOMEM;

	loc_cpu_entry = newinfo->entries;
	sockptr_advance(arg, sizeof(tmp));
	if (copy_from_sockptr(loc_cpu_entry, arg, tmp.size) != 0) {
	if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp),
			tmp.size) != 0) {
		ret = -EFAULT;
		goto free_newinfo;
	}
Loading