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

Commit 67b7626a authored by David Howells's avatar David Howells Committed by Steve French
Browse files

CIFS: Make cifs_convert_address() take a const src pointer and a length



Make cifs_convert_address() take a const src pointer and a length so that all
the strlen() calls in their can be cut out and to make it unnecessary to modify
the src string.

Also return the data length from dns_resolve_server_name_to_ip() so that a
strlen() can be cut out of cifs_compose_mount_options() too.

Acked-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent f579903e
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
	}

	rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
	if (rc != 0) {
	if (rc < 0) {
		cERROR(1, "%s: Failed to resolve server part of %s to IP: %d",
			  __func__, *devname, rc);
		goto compose_mount_options_err;
@@ -150,8 +150,7 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
	 * assuming that we have 'unc=' and 'ip=' in
	 * the original sb_mountdata
	 */
	md_len = strlen(sb_mountdata) + strlen(srvIP) +
		strlen(ref->node_name) + 12;
	md_len = strlen(sb_mountdata) + rc + strlen(ref->node_name) + 12;
	mountdata = kzalloc(md_len+1, GFP_KERNEL);
	if (mountdata == NULL) {
		rc = -ENOMEM;
+2 −2
Original line number Diff line number Diff line
@@ -86,8 +86,8 @@ extern unsigned int smbCalcSize(struct smb_hdr *ptr);
extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
extern int decode_negTokenInit(unsigned char *security_blob, int length,
			struct TCP_Server_Info *server);
extern int cifs_convert_address(struct sockaddr *dst, char *src);
extern int cifs_fill_sockaddr(struct sockaddr *dst, char *src,
extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
				unsigned short int port);
extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
extern void header_assemble(struct smb_hdr *, char /* command */ ,
+1 −0
Original line number Diff line number Diff line
@@ -1543,6 +1543,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
	if (volume_info->UNCip && volume_info->UNC) {
		rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
					volume_info->UNCip,
					strlen(volume_info->UNCip),
					volume_info->port);
		if (!rc) {
			/* we failed translating address */
+9 −11
Original line number Diff line number Diff line
@@ -40,11 +40,11 @@ static const struct cred *dns_resolver_cache;
 * 		0 - name is not IP
 */
static int
is_ip(char *name)
is_ip(const char *name, int len)
{
	struct sockaddr_storage ss;

	return cifs_convert_address((struct sockaddr *)&ss, name);
	return cifs_convert_address((struct sockaddr *)&ss, name, len);
}

static int
@@ -54,6 +54,10 @@ dns_resolver_instantiate(struct key *key, const void *data,
	int rc = 0;
	char *ip;

	/* make sure this looks like an address */
	if (!is_ip(data, datalen))
		return -EINVAL;

	ip = kmalloc(datalen + 1, GFP_KERNEL);
	if (!ip)
		return -ENOMEM;
@@ -61,12 +65,6 @@ dns_resolver_instantiate(struct key *key, const void *data,
	memcpy(ip, data, datalen);
	ip[datalen] = '\0';

	/* make sure this looks like an address */
	if (!is_ip(ip)) {
		kfree(ip);
		return -EINVAL;
	}

	key->type_data.x[0] = datalen;
	key->payload.data = ip;

@@ -93,7 +91,7 @@ struct key_type key_type_dns_resolver = {
 * 	unc - server UNC
 * output:
 * 	*ip_addr - pointer to server ip, caller responcible for freeing it.
 * return 0 on success
 * return the length of the returned string on success
 */
int
dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
@@ -131,7 +129,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
	memcpy(name, unc+2, len);
	name[len] = 0;

	if (is_ip(name)) {
	if (is_ip(name, len)) {
		cFYI(1, "%s: it is IP, skipping dns upcall: %s",
					__func__, name);
		data = name;
@@ -164,7 +162,7 @@ skip_upcall:
							name,
							*ip_addr
					);
			rc = 0;
			rc = len;
		} else {
			rc = -ENOMEM;
		}
+24 −21
Original line number Diff line number Diff line
@@ -140,17 +140,18 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
 * Returns 0 on failure.
 */
static int
cifs_inet_pton(const int address_family, const char *cp, void *dst)
cifs_inet_pton(const int address_family, const char *cp, int len, void *dst)
{
	int ret = 0;

	/* calculate length by finding first slash or NULL */
	if (address_family == AF_INET)
		ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL);
		ret = in4_pton(cp, len, dst, '\\', NULL);
	else if (address_family == AF_INET6)
		ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
		ret = in6_pton(cp, len, dst , '\\', NULL);

	cFYI(DBG2, "address conversion returned %d for %s", ret, cp);
	cFYI(DBG2, "address conversion returned %d for %*.*s",
	     ret, len, len, cp);
	if (ret > 0)
		ret = 1;
	return ret;
@@ -165,37 +166,39 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst)
 * Returns 0 on failure.
 */
int
cifs_convert_address(struct sockaddr *dst, char *src)
cifs_convert_address(struct sockaddr *dst, const char *src, int len)
{
	int rc;
	char *pct, *endp;
	int rc, alen, slen;
	const char *pct;
	char *endp, scope_id[13];
	struct sockaddr_in *s4 = (struct sockaddr_in *) dst;
	struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) dst;

	/* IPv4 address */
	if (cifs_inet_pton(AF_INET, src, &s4->sin_addr.s_addr)) {
	if (cifs_inet_pton(AF_INET, src, len, &s4->sin_addr.s_addr)) {
		s4->sin_family = AF_INET;
		return 1;
	}

	/* temporarily terminate string */
	pct = strchr(src, '%');
	if (pct)
		*pct = '\0';

	rc = cifs_inet_pton(AF_INET6, src, &s6->sin6_addr.s6_addr);

	/* repair temp termination (if any) and make pct point to scopeid */
	if (pct)
		*pct++ = '%';
	/* attempt to exclude the scope ID from the address part */
	pct = memchr(src, '%', len);
	alen = pct ? pct - src : len;

	rc = cifs_inet_pton(AF_INET6, src, alen, &s6->sin6_addr.s6_addr);
	if (!rc)
		return rc;

	s6->sin6_family = AF_INET6;
	if (pct) {
		/* grab the scope ID */
		slen = len - (alen + 1);
		if (slen <= 0 || slen > 12)
			return 0;
		memcpy(scope_id, pct + 1, slen);
		scope_id[slen] = '\0';

		s6->sin6_scope_id = (u32) simple_strtoul(pct, &endp, 0);
		if (!*pct || *endp)
		if (endp != scope_id + slen)
			return 0;
	}

@@ -203,10 +206,10 @@ cifs_convert_address(struct sockaddr *dst, char *src)
}

int
cifs_fill_sockaddr(struct sockaddr *dst, char *src,
cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
		   const unsigned short int port)
{
	if (!cifs_convert_address(dst, src))
	if (!cifs_convert_address(dst, src, len))
		return 0;

	switch (dst->sa_family) {