diff options
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 74c00bc92b9a..4949667c84ea 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -1674,12 +1674,12 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
1674 | 1674 | ||
1675 | static void write32(__be32 **p, u32 n) | 1675 | static void write32(__be32 **p, u32 n) |
1676 | { | 1676 | { |
1677 | *(*p)++ = n; | 1677 | *(*p)++ = htonl(n); |
1678 | } | 1678 | } |
1679 | 1679 | ||
1680 | static void write64(__be32 **p, u64 n) | 1680 | static void write64(__be32 **p, u64 n) |
1681 | { | 1681 | { |
1682 | write32(p, (u32)(n >> 32)); | 1682 | write32(p, (n >> 32)); |
1683 | write32(p, (u32)n); | 1683 | write32(p, (u32)n); |
1684 | } | 1684 | } |
1685 | 1685 | ||
@@ -1744,15 +1744,16 @@ static void encode_seqid_op_tail(struct nfsd4_compoundres *resp, __be32 *save, _ | |||
1744 | } | 1744 | } |
1745 | 1745 | ||
1746 | /* Encode as an array of strings the string given with components | 1746 | /* Encode as an array of strings the string given with components |
1747 | * separated @sep. | 1747 | * separated @sep, escaped with esc_enter and esc_exit. |
1748 | */ | 1748 | */ |
1749 | static __be32 nfsd4_encode_components(char sep, char *components, | 1749 | static __be32 nfsd4_encode_components_esc(char sep, char *components, |
1750 | __be32 **pp, int *buflen) | 1750 | __be32 **pp, int *buflen, |
1751 | char esc_enter, char esc_exit) | ||
1751 | { | 1752 | { |
1752 | __be32 *p = *pp; | 1753 | __be32 *p = *pp; |
1753 | __be32 *countp = p; | 1754 | __be32 *countp = p; |
1754 | int strlen, count=0; | 1755 | int strlen, count=0; |
1755 | char *str, *end; | 1756 | char *str, *end, *next; |
1756 | 1757 | ||
1757 | dprintk("nfsd4_encode_components(%s)\n", components); | 1758 | dprintk("nfsd4_encode_components(%s)\n", components); |
1758 | if ((*buflen -= 4) < 0) | 1759 | if ((*buflen -= 4) < 0) |
@@ -1760,8 +1761,23 @@ static __be32 nfsd4_encode_components(char sep, char *components, | |||
1760 | WRITE32(0); /* We will fill this in with @count later */ | 1761 | WRITE32(0); /* We will fill this in with @count later */ |
1761 | end = str = components; | 1762 | end = str = components; |
1762 | while (*end) { | 1763 | while (*end) { |
1763 | for (; *end && (*end != sep); end++) | 1764 | bool found_esc = false; |
1764 | ; /* Point to end of component */ | 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 | |||
1765 | strlen = end - str; | 1781 | strlen = end - str; |
1766 | if (strlen) { | 1782 | if (strlen) { |
1767 | if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0) | 1783 | if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0) |
@@ -1780,6 +1796,15 @@ static __be32 nfsd4_encode_components(char sep, char *components, | |||
1780 | return 0; | 1796 | return 0; |
1781 | } | 1797 | } |
1782 | 1798 | ||
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 | |||
1783 | /* | 1808 | /* |
1784 | * encode a location element of a fs_locations structure | 1809 | * encode a location element of a fs_locations structure |
1785 | */ | 1810 | */ |
@@ -1789,7 +1814,8 @@ static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location, | |||
1789 | __be32 status; | 1814 | __be32 status; |
1790 | __be32 *p = *pp; | 1815 | __be32 *p = *pp; |
1791 | 1816 | ||
1792 | status = nfsd4_encode_components(':', location->hosts, &p, buflen); | 1817 | status = nfsd4_encode_components_esc(':', location->hosts, &p, buflen, |
1818 | '[', ']'); | ||
1793 | if (status) | 1819 | if (status) |
1794 | return status; | 1820 | return status; |
1795 | status = nfsd4_encode_components('/', location->path, &p, buflen); | 1821 | status = nfsd4_encode_components('/', location->path, &p, buflen); |
@@ -3251,7 +3277,7 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w | |||
3251 | } | 3277 | } |
3252 | 3278 | ||
3253 | static __be32 | 3279 | static __be32 |
3254 | nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr, | 3280 | nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, |
3255 | struct nfsd4_exchange_id *exid) | 3281 | struct nfsd4_exchange_id *exid) |
3256 | { | 3282 | { |
3257 | __be32 *p; | 3283 | __be32 *p; |
@@ -3306,7 +3332,7 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr, | |||
3306 | } | 3332 | } |
3307 | 3333 | ||
3308 | static __be32 | 3334 | static __be32 |
3309 | nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, | 3335 | nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr, |
3310 | struct nfsd4_create_session *sess) | 3336 | struct nfsd4_create_session *sess) |
3311 | { | 3337 | { |
3312 | __be32 *p; | 3338 | __be32 *p; |
@@ -3355,14 +3381,14 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, | |||
3355 | } | 3381 | } |
3356 | 3382 | ||
3357 | static __be32 | 3383 | static __be32 |
3358 | nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr, | 3384 | nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, __be32 nfserr, |
3359 | struct nfsd4_destroy_session *destroy_session) | 3385 | struct nfsd4_destroy_session *destroy_session) |
3360 | { | 3386 | { |
3361 | return nfserr; | 3387 | return nfserr; |
3362 | } | 3388 | } |
3363 | 3389 | ||
3364 | static __be32 | 3390 | static __be32 |
3365 | nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr, | 3391 | nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, |
3366 | struct nfsd4_free_stateid *free_stateid) | 3392 | struct nfsd4_free_stateid *free_stateid) |
3367 | { | 3393 | { |
3368 | __be32 *p; | 3394 | __be32 *p; |
@@ -3371,13 +3397,13 @@ nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr, | |||
3371 | return nfserr; | 3397 | return nfserr; |
3372 | 3398 | ||
3373 | RESERVE_SPACE(4); | 3399 | RESERVE_SPACE(4); |
3374 | WRITE32(nfserr); | 3400 | *p++ = nfserr; |
3375 | ADJUST_ARGS(); | 3401 | ADJUST_ARGS(); |
3376 | return nfserr; | 3402 | return nfserr; |
3377 | } | 3403 | } |
3378 | 3404 | ||
3379 | static __be32 | 3405 | static __be32 |
3380 | nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, | 3406 | nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, |
3381 | struct nfsd4_sequence *seq) | 3407 | struct nfsd4_sequence *seq) |
3382 | { | 3408 | { |
3383 | __be32 *p; | 3409 | __be32 *p; |
@@ -3399,8 +3425,8 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, | |||
3399 | return 0; | 3425 | return 0; |
3400 | } | 3426 | } |
3401 | 3427 | ||
3402 | __be32 | 3428 | static __be32 |
3403 | nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, | 3429 | nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, |
3404 | struct nfsd4_test_stateid *test_stateid) | 3430 | struct nfsd4_test_stateid *test_stateid) |
3405 | { | 3431 | { |
3406 | struct nfsd4_test_stateid_id *stateid, *next; | 3432 | struct nfsd4_test_stateid_id *stateid, *next; |
@@ -3503,7 +3529,7 @@ static nfsd4_enc nfsd4_enc_ops[] = { | |||
3503 | * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so | 3529 | * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so |
3504 | * will be at least a page and will therefore hold the xdr_buf head. | 3530 | * will be at least a page and will therefore hold the xdr_buf head. |
3505 | */ | 3531 | */ |
3506 | int nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad) | 3532 | __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad) |
3507 | { | 3533 | { |
3508 | struct xdr_buf *xb = &resp->rqstp->rq_res; | 3534 | struct xdr_buf *xb = &resp->rqstp->rq_res; |
3509 | struct nfsd4_session *session = NULL; | 3535 | struct nfsd4_session *session = NULL; |