summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@fys.uio.no>2004-04-10 21:24:37 -0700
committerTrond Myklebust <trond.myklebust@fys.uio.no>2004-04-10 21:24:37 -0700
commit01d37f031f0cda3caeeafa599c8e7e54b862d93c (patch)
tree7f25807a4c3fb187e5234cb76fb4043b44185b25
parentbcb23e3c86a64106b899fa6d96c84c4a925dc374 (diff)
RPCSEC_GSS: Fix RPC padding in two instances of RPCSEC_GSS code.
RPC: Clean up XDR encoding of opaque data.
-rw-r--r--fs/nfs/nfs4xdr.c13
-rw-r--r--include/linux/sunrpc/xdr.h8
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c7
-rw-r--r--net/sunrpc/sunrpc_syms.c1
-rw-r--r--net/sunrpc/xdr.c48
5 files changed, 51 insertions, 26 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index e370ffe1d13f..742958ee2f9e 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -297,7 +297,7 @@ struct compound_hdr {
*p++ = htonl((uint32_t)(n)); \
} while (0)
#define WRITEMEM(ptr,nbytes) do { \
- p = xdr_writemem(p, ptr, nbytes); \
+ p = xdr_encode_opaque_fixed(p, ptr, nbytes); \
} while (0)
#define RESERVE_SPACE(nbytes) do { \
@@ -306,17 +306,6 @@ struct compound_hdr {
BUG_ON(!p); \
} while (0)
-static inline
-uint32_t *xdr_writemem(uint32_t *p, const void *ptr, int nbytes)
-{
- int tmp = XDR_QUADLEN(nbytes);
- if (!tmp)
- return p;
- p[tmp-1] = 0;
- memcpy(p, ptr, nbytes);
- return p + tmp;
-}
-
static int
encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
{
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 0ccaff2cdee2..deac01c2e96a 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -87,7 +87,8 @@ struct xdr_buf {
/*
* Miscellaneous XDR helper functions
*/
-u32 * xdr_encode_array(u32 *p, const void *s, unsigned int len);
+u32 * xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len);
+u32 * xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len);
u32 * xdr_encode_string(u32 *p, const char *s);
u32 * xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen);
u32 * xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen);
@@ -100,6 +101,11 @@ void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
void xdr_inline_pages(struct xdr_buf *, unsigned int,
struct page **, unsigned int, unsigned int);
+static inline u32 *xdr_encode_array(u32 *p, const void *s, unsigned int len)
+{
+ return xdr_encode_opaque(p, s, len);
+}
+
/*
* Decode 64bit quantities (NFSv3 support)
*/
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 84ec888bdc39..b1b922f09257 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -721,8 +721,7 @@ gss_marshal(struct rpc_task *task, u32 *p, int ruid)
printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
goto out_put_ctx;
}
- *p++ = htonl(mic.len);
- p += XDR_QUADLEN(mic.len);
+ p = xdr_encode_opaque(p, NULL, mic.len);
gss_put_ctx(ctx);
return p;
out_put_ctx:
@@ -857,9 +856,7 @@ gss_wrap_req(struct rpc_task *task,
status = -EIO; /* XXX? */
if (maj_stat)
goto out;
- q = p;
- *q++ = htonl(mic.len);
- q += XDR_QUADLEN(mic.len);
+ q = xdr_encode_opaque(p, NULL, mic.len);
offset = (u8 *)q - (u8 *)p;
iov->iov_len += offset;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 9061f6498cc4..104bd5679272 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -120,7 +120,6 @@ EXPORT_SYMBOL(svcauth_unix_purge);
EXPORT_SYMBOL(unix_domain_find);
/* Generic XDR */
-EXPORT_SYMBOL(xdr_encode_array);
EXPORT_SYMBOL(xdr_encode_string);
EXPORT_SYMBOL(xdr_decode_string);
EXPORT_SYMBOL(xdr_decode_string_inplace);
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index accfdd9284df..a0b977cfbfc5 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -53,16 +53,50 @@ xdr_decode_netobj(u32 *p, struct xdr_netobj *obj)
return p + XDR_QUADLEN(len);
}
-u32 *
-xdr_encode_array(u32 *p, const void *array, unsigned int len)
+/**
+ * xdr_encode_opaque_fixed - Encode fixed length opaque data
+ * @p - pointer to current position in XDR buffer.
+ * @ptr - pointer to data to encode (or NULL)
+ * @nbytes - size of data.
+ *
+ * Copy the array of data of length nbytes at ptr to the XDR buffer
+ * at position p, then align to the next 32-bit boundary by padding
+ * with zero bytes (see RFC1832).
+ * Note: if ptr is NULL, only the padding is performed.
+ *
+ * Returns the updated current XDR buffer position
+ *
+ */
+u32 *xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int nbytes)
{
- int quadlen = XDR_QUADLEN(len);
+ if (likely(nbytes != 0)) {
+ unsigned int quadlen = XDR_QUADLEN(nbytes);
+ unsigned int padding = (quadlen << 2) - nbytes;
+
+ if (ptr != NULL)
+ memcpy(p, ptr, nbytes);
+ if (padding != 0)
+ memset((char *)p + nbytes, 0, padding);
+ p += quadlen;
+ }
+ return p;
+}
+EXPORT_SYMBOL(xdr_encode_opaque_fixed);
- p[quadlen] = 0;
- *p++ = htonl(len);
- memcpy(p, array, len);
- return p + quadlen;
+/**
+ * xdr_encode_opaque - Encode variable length opaque data
+ * @p - pointer to current position in XDR buffer.
+ * @ptr - pointer to data to encode (or NULL)
+ * @nbytes - size of data.
+ *
+ * Returns the updated current XDR buffer position
+ */
+u32 *xdr_encode_opaque(u32 *p, const void *ptr, unsigned int nbytes)
+{
+ *p++ = htonl(nbytes);
+ return xdr_encode_opaque_fixed(p, ptr, nbytes);
}
+EXPORT_SYMBOL(xdr_encode_opaque);
u32 *
xdr_encode_string(u32 *p, const char *string)