Skip to content

Commit e7a0444

Browse files
westonandrosadamsonJ. Bruce Fields
authored andcommitted
nfsd: add IPv6 addr escaping to fs_location hosts
The fs_location->hosts list is split on colons, but this doesn't work when IPv6 addresses are used (they contain colons). This patch adds the function nfsd4_encode_components_esc() to allow the caller to specify escape characters when splitting on 'sep'. In order to fix referrals, this patch must be used with the mountd patch that similarly fixes IPv6 [] escaping. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
1 parent 45eaa1c commit e7a0444

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

fs/nfsd/nfs4xdr.c

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,24 +1744,40 @@ static void encode_seqid_op_tail(struct nfsd4_compoundres *resp, __be32 *save, _
17441744
}
17451745

17461746
/* Encode as an array of strings the string given with components
1747-
* separated @sep.
1747+
* separated @sep, escaped with esc_enter and esc_exit.
17481748
*/
1749-
static __be32 nfsd4_encode_components(char sep, char *components,
1750-
__be32 **pp, int *buflen)
1749+
static __be32 nfsd4_encode_components_esc(char sep, char *components,
1750+
__be32 **pp, int *buflen,
1751+
char esc_enter, char esc_exit)
17511752
{
17521753
__be32 *p = *pp;
17531754
__be32 *countp = p;
17541755
int strlen, count=0;
1755-
char *str, *end;
1756+
char *str, *end, *next;
17561757

17571758
dprintk("nfsd4_encode_components(%s)\n", components);
17581759
if ((*buflen -= 4) < 0)
17591760
return nfserr_resource;
17601761
WRITE32(0); /* We will fill this in with @count later */
17611762
end = str = components;
17621763
while (*end) {
1763-
for (; *end && (*end != sep); end++)
1764-
; /* Point to end of component */
1764+
bool found_esc = false;
1765+
1766+
/* try to parse as esc_start, ..., esc_end, sep */
1767+
if (*str == esc_enter) {
1768+
for (; *end && (*end != esc_exit); end++)
1769+
/* find esc_exit or end of string */;
1770+
next = end + 1;
1771+
if (*end && (!*next || *next == sep)) {
1772+
str++;
1773+
found_esc = true;
1774+
}
1775+
}
1776+
1777+
if (!found_esc)
1778+
for (; *end && (*end != sep); end++)
1779+
/* find sep or end of string */;
1780+
17651781
strlen = end - str;
17661782
if (strlen) {
17671783
if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
@@ -1780,6 +1796,15 @@ static __be32 nfsd4_encode_components(char sep, char *components,
17801796
return 0;
17811797
}
17821798

1799+
/* Encode as an array of strings the string given with components
1800+
* separated @sep.
1801+
*/
1802+
static __be32 nfsd4_encode_components(char sep, char *components,
1803+
__be32 **pp, int *buflen)
1804+
{
1805+
return nfsd4_encode_components_esc(sep, components, pp, buflen, 0, 0);
1806+
}
1807+
17831808
/*
17841809
* encode a location element of a fs_locations structure
17851810
*/
@@ -1789,7 +1814,8 @@ static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
17891814
__be32 status;
17901815
__be32 *p = *pp;
17911816

1792-
status = nfsd4_encode_components(':', location->hosts, &p, buflen);
1817+
status = nfsd4_encode_components_esc(':', location->hosts, &p, buflen,
1818+
'[', ']');
17931819
if (status)
17941820
return status;
17951821
status = nfsd4_encode_components('/', location->path, &p, buflen);

0 commit comments

Comments
 (0)