summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-02-23 01:21:40 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2023-02-23 01:21:40 +0300
commit9fc2f99030b55027d84723b0dcbbe9f7e21b9c6c (patch)
treee0c158425e66d8168fe36f11f18c2a79040fe7e8 /include
parent25ac8c12ff7886e3d9b99feb85c53302a3cc5556 (diff)
parent4b471a8b847b82a3035709dcf87661915c340c8a (diff)
downloadlinux-9fc2f99030b55027d84723b0dcbbe9f7e21b9c6c.tar.xz
Merge tag 'nfsd-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd updates from Chuck Lever: "Two significant security enhancements are part of this release: - NFSD's RPC header encoding and decoding, including RPCSEC GSS and gssproxy header parsing, has been overhauled to make it more memory-safe. - Support for Kerberos AES-SHA2-based encryption types has been added for both the NFS client and server. This provides a clean path for deprecating and removing insecure encryption types based on DES and SHA-1. AES-SHA2 is also FIPS-140 compliant, so that NFS with Kerberos may now be used on systems with fips enabled. In addition to these, NFSD is now able to handle crossing into an auto-mounted mount point on an exported NFS mount. A number of fixes have been made to NFSD's server-side copy implementation. RPC metrics have been converted to per-CPU variables. This helps reduce unnecessary cross-CPU and cross-node memory bus traffic, and significantly reduces noise when KCSAN is enabled" * tag 'nfsd-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (121 commits) NFSD: Clean up nfsd_symlink() NFSD: copy the whole verifier in nfsd_copy_write_verifier nfsd: don't fsync nfsd_files on last close SUNRPC: Fix occasional warning when destroying gss_krb5_enctypes nfsd: fix courtesy client with deny mode handling in nfs4_upgrade_open NFSD: fix problems with cleanup on errors in nfsd4_copy nfsd: fix race to check ls_layouts nfsd: don't hand out delegation on setuid files being opened for write SUNRPC: Remove ->xpo_secure_port() SUNRPC: Clean up the svc_xprt_flags() macro nfsd: remove fs/nfsd/fault_inject.c NFSD: fix leaked reference count of nfsd4_ssc_umount_item nfsd: clean up potential nfsd_file refcount leaks in COPY codepath nfsd: zero out pointers after putting nfsd_files on COPY setup error SUNRPC: Fix whitespace damage in svcauth_unix.c nfsd: eliminate __nfs4_get_fd nfsd: add some kerneldoc comments for stateid preprocessing functions nfsd: eliminate find_deleg_file_locked nfsd: don't take nfsd4_copy ref for OP_OFFLOAD_STATUS SUNRPC: Add encryption self-tests ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/lockd/lockd.h4
-rw-r--r--include/linux/namei.h2
-rw-r--r--include/linux/nfs_ssc.h2
-rw-r--r--include/linux/sunrpc/gss_krb5.h196
-rw-r--r--include/linux/sunrpc/gss_krb5_enctypes.h41
-rw-r--r--include/linux/sunrpc/msg_prot.h5
-rw-r--r--include/linux/sunrpc/svc.h133
-rw-r--r--include/linux/sunrpc/svc_xprt.h1
-rw-r--r--include/linux/sunrpc/xdr.h28
-rw-r--r--include/trace/events/rpcgss.h22
-rw-r--r--include/trace/events/sunrpc.h28
11 files changed, 152 insertions, 310 deletions
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 2b7f067af3c4..0168ac9fdda8 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -196,9 +196,9 @@ struct nlm_block {
* Global variables
*/
extern const struct rpc_program nlm_program;
-extern const struct svc_procedure nlmsvc_procedures[];
+extern const struct svc_procedure nlmsvc_procedures[24];
#ifdef CONFIG_LOCKD_V4
-extern const struct svc_procedure nlmsvc_procedures4[];
+extern const struct svc_procedure nlmsvc_procedures4[24];
#endif
extern int nlmsvc_grace_period;
extern unsigned long nlmsvc_timeout;
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 0d4531fd46e7..0d797f3367ca 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -77,7 +77,7 @@ struct dentry *lookup_one_positive_unlocked(struct mnt_idmap *idmap,
struct dentry *base, int len);
extern int follow_down_one(struct path *);
-extern int follow_down(struct path *);
+extern int follow_down(struct path *path, unsigned int flags);
extern int follow_up(struct path *);
extern struct dentry *lock_rename(struct dentry *, struct dentry *);
diff --git a/include/linux/nfs_ssc.h b/include/linux/nfs_ssc.h
index 75843c00f326..22265b1ff080 100644
--- a/include/linux/nfs_ssc.h
+++ b/include/linux/nfs_ssc.h
@@ -53,6 +53,7 @@ static inline void nfs42_ssc_close(struct file *filep)
if (nfs_ssc_client_tbl.ssc_nfs4_ops)
(*nfs_ssc_client_tbl.ssc_nfs4_ops->sco_close)(filep);
}
+#endif
struct nfsd4_ssc_umount_item {
struct list_head nsui_list;
@@ -66,7 +67,6 @@ struct nfsd4_ssc_umount_item {
struct vfsmount *nsui_vfsmount;
char nsui_ipaddr[RPC_MAX_ADDRBUFLEN + 1];
};
-#endif
/*
* NFS_FS
diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
index 91f43d86879d..78a80bf3fdcb 100644
--- a/include/linux/sunrpc/gss_krb5.h
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -1,6 +1,4 @@
/*
- * linux/include/linux/sunrpc/gss_krb5_types.h
- *
* Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
* lib/gssapi/krb5/gssapiP_krb5.h, and others
*
@@ -36,6 +34,9 @@
*
*/
+#ifndef _LINUX_SUNRPC_GSS_KRB5_H
+#define _LINUX_SUNRPC_GSS_KRB5_H
+
#include <crypto/skcipher.h>
#include <linux/sunrpc/auth_gss.h>
#include <linux/sunrpc/gss_err.h>
@@ -44,80 +45,15 @@
/* Length of constant used in key derivation */
#define GSS_KRB5_K5CLENGTH (5)
-/* Maximum key length (in bytes) for the supported crypto algorithms*/
+/* Maximum key length (in bytes) for the supported crypto algorithms */
#define GSS_KRB5_MAX_KEYLEN (32)
-/* Maximum checksum function output for the supported crypto algorithms */
-#define GSS_KRB5_MAX_CKSUM_LEN (20)
+/* Maximum checksum function output for the supported enctypes */
+#define GSS_KRB5_MAX_CKSUM_LEN (24)
/* Maximum blocksize for the supported crypto algorithms */
#define GSS_KRB5_MAX_BLOCKSIZE (16)
-struct krb5_ctx;
-
-struct gss_krb5_enctype {
- const u32 etype; /* encryption (key) type */
- const u32 ctype; /* checksum type */
- const char *name; /* "friendly" name */
- const char *encrypt_name; /* crypto encrypt name */
- const char *cksum_name; /* crypto checksum name */
- const u16 signalg; /* signing algorithm */
- const u16 sealalg; /* sealing algorithm */
- const u32 blocksize; /* encryption blocksize */
- const u32 conflen; /* confounder length
- (normally the same as
- the blocksize) */
- const u32 cksumlength; /* checksum length */
- const u32 keyed_cksum; /* is it a keyed cksum? */
- const u32 keybytes; /* raw key len, in bytes */
- const u32 keylength; /* final key len, in bytes */
- u32 (*encrypt) (struct crypto_sync_skcipher *tfm,
- void *iv, void *in, void *out,
- int length); /* encryption function */
- u32 (*decrypt) (struct crypto_sync_skcipher *tfm,
- void *iv, void *in, void *out,
- int length); /* decryption function */
- u32 (*mk_key) (const struct gss_krb5_enctype *gk5e,
- struct xdr_netobj *in,
- struct xdr_netobj *out); /* complete key generation */
- u32 (*encrypt_v2) (struct krb5_ctx *kctx, u32 offset,
- struct xdr_buf *buf,
- struct page **pages); /* v2 encryption function */
- u32 (*decrypt_v2) (struct krb5_ctx *kctx, u32 offset, u32 len,
- struct xdr_buf *buf, u32 *headskip,
- u32 *tailskip); /* v2 decryption function */
-};
-
-/* krb5_ctx flags definitions */
-#define KRB5_CTX_FLAG_INITIATOR 0x00000001
-#define KRB5_CTX_FLAG_CFX 0x00000002
-#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
-
-struct krb5_ctx {
- int initiate; /* 1 = initiating, 0 = accepting */
- u32 enctype;
- u32 flags;
- const struct gss_krb5_enctype *gk5e; /* enctype-specific info */
- struct crypto_sync_skcipher *enc;
- struct crypto_sync_skcipher *seq;
- struct crypto_sync_skcipher *acceptor_enc;
- struct crypto_sync_skcipher *initiator_enc;
- struct crypto_sync_skcipher *acceptor_enc_aux;
- struct crypto_sync_skcipher *initiator_enc_aux;
- u8 Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */
- u8 cksum[GSS_KRB5_MAX_KEYLEN];
- atomic_t seq_send;
- atomic64_t seq_send64;
- time64_t endtime;
- struct xdr_netobj mech_used;
- u8 initiator_sign[GSS_KRB5_MAX_KEYLEN];
- u8 acceptor_sign[GSS_KRB5_MAX_KEYLEN];
- u8 initiator_seal[GSS_KRB5_MAX_KEYLEN];
- u8 acceptor_seal[GSS_KRB5_MAX_KEYLEN];
- u8 initiator_integ[GSS_KRB5_MAX_KEYLEN];
- u8 acceptor_integ[GSS_KRB5_MAX_KEYLEN];
-};
-
/* The length of the Kerberos GSS token header */
#define GSS_KRB5_TOK_HDR_LEN (16)
@@ -150,6 +86,12 @@ enum seal_alg {
SEAL_ALG_DES3KD = 0x0002
};
+/*
+ * These values are assigned by IANA and published via the
+ * subregistry at the link below:
+ *
+ * https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml#kerberos-parameters-2
+ */
#define CKSUMTYPE_CRC32 0x0001
#define CKSUMTYPE_RSA_MD4 0x0002
#define CKSUMTYPE_RSA_MD4_DES 0x0003
@@ -160,6 +102,10 @@ enum seal_alg {
#define CKSUMTYPE_HMAC_SHA1_DES3 0x000c
#define CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f
#define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010
+#define CKSUMTYPE_CMAC_CAMELLIA128 0x0011
+#define CKSUMTYPE_CMAC_CAMELLIA256 0x0012
+#define CKSUMTYPE_HMAC_SHA256_128_AES128 0x0013
+#define CKSUMTYPE_HMAC_SHA384_192_AES256 0x0014
#define CKSUMTYPE_HMAC_MD5_ARCFOUR -138 /* Microsoft md5 hmac cksumtype */
/* from gssapi_err_krb5.h */
@@ -180,6 +126,11 @@ enum seal_alg {
/* per Kerberos v5 protocol spec crypto types from the wire.
* these get mapped to linux kernel crypto routines.
+ *
+ * These values are assigned by IANA and published via the
+ * subregistry at the link below:
+ *
+ * https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml#kerberos-parameters-1
*/
#define ENCTYPE_NULL 0x0000
#define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */
@@ -193,8 +144,12 @@ enum seal_alg {
#define ENCTYPE_DES3_CBC_SHA1 0x0010
#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011
#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012
+#define ENCTYPE_AES128_CTS_HMAC_SHA256_128 0x0013
+#define ENCTYPE_AES256_CTS_HMAC_SHA384_192 0x0014
#define ENCTYPE_ARCFOUR_HMAC 0x0017
#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
+#define ENCTYPE_CAMELLIA128_CTS_CMAC 0x0019
+#define ENCTYPE_CAMELLIA256_CTS_CMAC 0x001A
#define ENCTYPE_UNKNOWN 0x01ff
/*
@@ -216,103 +171,4 @@ enum seal_alg {
#define KG_USAGE_INITIATOR_SEAL (24)
#define KG_USAGE_INITIATOR_SIGN (25)
-/*
- * This compile-time check verifies that we will not exceed the
- * slack space allotted by the client and server auth_gss code
- * before they call gss_wrap().
- */
-#define GSS_KRB5_MAX_SLACK_NEEDED \
- (GSS_KRB5_TOK_HDR_LEN /* gss token header */ \
- + GSS_KRB5_MAX_CKSUM_LEN /* gss token checksum */ \
- + GSS_KRB5_MAX_BLOCKSIZE /* confounder */ \
- + GSS_KRB5_MAX_BLOCKSIZE /* possible padding */ \
- + GSS_KRB5_TOK_HDR_LEN /* encrypted hdr in v2 token */\
- + GSS_KRB5_MAX_CKSUM_LEN /* encryption hmac */ \
- + 4 + 4 /* RPC verifier */ \
- + GSS_KRB5_TOK_HDR_LEN \
- + GSS_KRB5_MAX_CKSUM_LEN)
-
-u32
-make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen,
- struct xdr_buf *body, int body_offset, u8 *cksumkey,
- unsigned int usage, struct xdr_netobj *cksumout);
-
-u32
-make_checksum_v2(struct krb5_ctx *, char *header, int hdrlen,
- struct xdr_buf *body, int body_offset, u8 *key,
- unsigned int usage, struct xdr_netobj *cksum);
-
-u32 gss_get_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
- struct xdr_netobj *);
-
-u32 gss_verify_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
- struct xdr_netobj *);
-
-u32
-gss_wrap_kerberos(struct gss_ctx *ctx_id, int offset,
- struct xdr_buf *outbuf, struct page **pages);
-
-u32
-gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset, int len,
- struct xdr_buf *buf);
-
-
-u32
-krb5_encrypt(struct crypto_sync_skcipher *key,
- void *iv, void *in, void *out, int length);
-
-u32
-krb5_decrypt(struct crypto_sync_skcipher *key,
- void *iv, void *in, void *out, int length);
-
-int
-gss_encrypt_xdr_buf(struct crypto_sync_skcipher *tfm, struct xdr_buf *outbuf,
- int offset, struct page **pages);
-
-int
-gss_decrypt_xdr_buf(struct crypto_sync_skcipher *tfm, struct xdr_buf *inbuf,
- int offset);
-
-s32
-krb5_make_seq_num(struct krb5_ctx *kctx,
- struct crypto_sync_skcipher *key,
- int direction,
- u32 seqnum, unsigned char *cksum, unsigned char *buf);
-
-s32
-krb5_get_seq_num(struct krb5_ctx *kctx,
- unsigned char *cksum,
- unsigned char *buf, int *direction, u32 *seqnum);
-
-int
-xdr_extend_head(struct xdr_buf *buf, unsigned int base, unsigned int shiftlen);
-
-u32
-krb5_derive_key(const struct gss_krb5_enctype *gk5e,
- const struct xdr_netobj *inkey,
- struct xdr_netobj *outkey,
- const struct xdr_netobj *in_constant,
- gfp_t gfp_mask);
-
-u32
-gss_krb5_des3_make_key(const struct gss_krb5_enctype *gk5e,
- struct xdr_netobj *randombits,
- struct xdr_netobj *key);
-
-u32
-gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e,
- struct xdr_netobj *randombits,
- struct xdr_netobj *key);
-
-u32
-gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
- struct xdr_buf *buf,
- struct page **pages);
-
-u32
-gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len,
- struct xdr_buf *buf, u32 *plainoffset,
- u32 *plainlen);
-
-void
-gss_krb5_make_confounder(char *p, u32 conflen);
+#endif /* _LINUX_SUNRPC_GSS_KRB5_H */
diff --git a/include/linux/sunrpc/gss_krb5_enctypes.h b/include/linux/sunrpc/gss_krb5_enctypes.h
deleted file mode 100644
index 87eea679d750..000000000000
--- a/include/linux/sunrpc/gss_krb5_enctypes.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Define the string that exports the set of kernel-supported
- * Kerberos enctypes. This list is sent via upcall to gssd, and
- * is also exposed via the nfsd /proc API. The consumers generally
- * treat this as an ordered list, where the first item in the list
- * is the most preferred.
- */
-
-#ifndef _LINUX_SUNRPC_GSS_KRB5_ENCTYPES_H
-#define _LINUX_SUNRPC_GSS_KRB5_ENCTYPES_H
-
-#ifdef CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES
-
-/*
- * NB: This list includes DES3_CBC_SHA1, which was deprecated by RFC 8429.
- *
- * ENCTYPE_AES256_CTS_HMAC_SHA1_96
- * ENCTYPE_AES128_CTS_HMAC_SHA1_96
- * ENCTYPE_DES3_CBC_SHA1
- */
-#define KRB5_SUPPORTED_ENCTYPES "18,17,16"
-
-#else /* CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES */
-
-/*
- * NB: This list includes encryption types that were deprecated
- * by RFC 8429 and RFC 6649.
- *
- * ENCTYPE_AES256_CTS_HMAC_SHA1_96
- * ENCTYPE_AES128_CTS_HMAC_SHA1_96
- * ENCTYPE_DES3_CBC_SHA1
- * ENCTYPE_DES_CBC_MD5
- * ENCTYPE_DES_CBC_CRC
- * ENCTYPE_DES_CBC_MD4
- */
-#define KRB5_SUPPORTED_ENCTYPES "18,17,16,3,1,2"
-
-#endif /* CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES */
-
-#endif /* _LINUX_SUNRPC_GSS_KRB5_ENCTYPES_H */
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index 02117ed0fa2e..c4b0eb2b2f04 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -34,6 +34,11 @@ enum rpc_auth_flavors {
RPC_AUTH_GSS_SPKMP = 390011,
};
+/* Maximum size (in octets) of the machinename in an AUTH_UNIX
+ * credential (per RFC 5531 Appendix A)
+ */
+#define RPC_MAX_MACHINENAME (255)
+
/* Maximum size (in bytes) of an rpc credential or verifier */
#define RPC_MAX_AUTH_SIZE (400)
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index ed722dd33b46..877891536c2f 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -21,14 +21,6 @@
#include <linux/mm.h>
#include <linux/pagevec.h>
-/* statistics for svc_pool structures */
-struct svc_pool_stats {
- atomic_long_t packets;
- unsigned long sockets_queued;
- atomic_long_t threads_woken;
- atomic_long_t threads_timedout;
-};
-
/*
*
* RPC service thread pool.
@@ -45,7 +37,12 @@ struct svc_pool {
struct list_head sp_sockets; /* pending sockets */
unsigned int sp_nrthreads; /* # of threads in pool */
struct list_head sp_all_threads; /* all server threads */
- struct svc_pool_stats sp_stats; /* statistics on pool operation */
+
+ /* statistics on pool operation */
+ struct percpu_counter sp_sockets_queued;
+ struct percpu_counter sp_threads_woken;
+ struct percpu_counter sp_threads_timedout;
+
#define SP_TASK_PENDING (0) /* still work to do even if no
* xprt is queued. */
#define SP_CONGESTED (1)
@@ -193,40 +190,6 @@ extern u32 svc_max_payload(const struct svc_rqst *rqstp);
#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE \
+ 2 + 1)
-static inline u32 svc_getnl(struct kvec *iov)
-{
- __be32 val, *vp;
- vp = iov->iov_base;
- val = *vp++;
- iov->iov_base = (void*)vp;
- iov->iov_len -= sizeof(__be32);
- return ntohl(val);
-}
-
-static inline void svc_putnl(struct kvec *iov, u32 val)
-{
- __be32 *vp = iov->iov_base + iov->iov_len;
- *vp = htonl(val);
- iov->iov_len += sizeof(__be32);
-}
-
-static inline __be32 svc_getu32(struct kvec *iov)
-{
- __be32 val, *vp;
- vp = iov->iov_base;
- val = *vp++;
- iov->iov_base = (void*)vp;
- iov->iov_len -= sizeof(__be32);
- return val;
-}
-
-static inline void svc_putu32(struct kvec *iov, __be32 val)
-{
- __be32 *vp = iov->iov_base + iov->iov_len;
- *vp = val;
- iov->iov_len += sizeof(__be32);
-}
-
/*
* The context of a single thread, including the request currently being
* processed.
@@ -285,6 +248,7 @@ struct svc_rqst {
void * rq_argp; /* decoded arguments */
void * rq_resp; /* xdr'd results */
+ __be32 *rq_accept_statp;
void * rq_auth_data; /* flavor-specific data */
__be32 rq_auth_stat; /* authentication status */
int rq_auth_slack; /* extra space xdr code
@@ -345,29 +309,6 @@ static inline struct sockaddr *svc_daddr(const struct svc_rqst *rqst)
return (struct sockaddr *) &rqst->rq_daddr;
}
-/*
- * Check buffer bounds after decoding arguments
- */
-static inline int
-xdr_argsize_check(struct svc_rqst *rqstp, __be32 *p)
-{
- char *cp = (char *)p;
- struct kvec *vec = &rqstp->rq_arg.head[0];
- return cp >= (char*)vec->iov_base
- && cp <= (char*)vec->iov_base + vec->iov_len;
-}
-
-static inline int
-xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p)
-{
- struct kvec *vec = &rqstp->rq_res.head[0];
- char *cp = (char*)p;
-
- vec->iov_len = cp - (char*)vec->iov_base;
-
- return vec->iov_len <= PAGE_SIZE;
-}
-
static inline void svc_free_res_pages(struct svc_rqst *rqstp)
{
while (rqstp->rq_next_page != rqstp->rq_respages) {
@@ -394,7 +335,7 @@ struct svc_deferred_req {
struct svc_process_info {
union {
- int (*dispatch)(struct svc_rqst *, __be32 *);
+ int (*dispatch)(struct svc_rqst *rqstp);
struct {
unsigned int lovers;
unsigned int hivers;
@@ -433,7 +374,7 @@ struct svc_version {
u32 vs_vers; /* version number */
u32 vs_nproc; /* number of procedures */
const struct svc_procedure *vs_proc; /* per-procedure info */
- unsigned int *vs_count; /* call counts */
+ unsigned long __percpu *vs_count; /* call counts */
u32 vs_xdrsize; /* xdrsize needed for this version */
/* Don't register with rpcbind */
@@ -446,7 +387,7 @@ struct svc_version {
bool vs_need_cong_ctrl;
/* Dispatch function */
- int (*vs_dispatch)(struct svc_rqst *, __be32 *);
+ int (*vs_dispatch)(struct svc_rqst *rqstp);
};
/*
@@ -540,9 +481,6 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
* svcxdr_init_decode - Prepare an xdr_stream for Call decoding
* @rqstp: controlling server RPC transaction context
*
- * This function currently assumes the RPC header in rq_arg has
- * already been decoded. Upon return, xdr->p points to the
- * location of the upper layer header.
*/
static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
{
@@ -550,11 +488,7 @@ static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
struct xdr_buf *buf = &rqstp->rq_arg;
struct kvec *argv = buf->head;
- /*
- * svc_getnl() and friends do not keep the xdr_buf's ::len
- * field up to date. Refresh that field before initializing
- * the argument decoding stream.
- */
+ WARN_ON(buf->len != buf->head->iov_len + buf->page_len + buf->tail->iov_len);
buf->len = buf->head->iov_len + buf->page_len + buf->tail->iov_len;
xdr_init_decode(xdr, buf, argv->iov_base, NULL);
@@ -577,12 +511,53 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp)
xdr->buf = buf;
xdr->iov = resv;
xdr->p = resv->iov_base + resv->iov_len;
- xdr->end = resv->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
+ xdr->end = resv->iov_base + PAGE_SIZE;
buf->len = resv->iov_len;
xdr->page_ptr = buf->pages - 1;
buf->buflen = PAGE_SIZE * (rqstp->rq_page_end - buf->pages);
- buf->buflen -= rqstp->rq_auth_slack;
xdr->rqst = NULL;
}
+/**
+ * svcxdr_set_auth_slack -
+ * @rqstp: RPC transaction
+ * @slack: buffer space to reserve for the transaction's security flavor
+ *
+ * Set the request's slack space requirement, and set aside that much
+ * space in the rqstp's rq_res.head for use when the auth wraps the Reply.
+ */
+static inline void svcxdr_set_auth_slack(struct svc_rqst *rqstp, int slack)
+{
+ struct xdr_stream *xdr = &rqstp->rq_res_stream;
+ struct xdr_buf *buf = &rqstp->rq_res;
+ struct kvec *resv = buf->head;
+
+ rqstp->rq_auth_slack = slack;
+
+ xdr->end -= XDR_QUADLEN(slack);
+ buf->buflen -= rqstp->rq_auth_slack;
+
+ WARN_ON(xdr->iov != resv);
+ WARN_ON(xdr->p > xdr->end);
+}
+
+/**
+ * svcxdr_set_accept_stat - Reserve space for the accept_stat field
+ * @rqstp: RPC transaction context
+ *
+ * Return values:
+ * %true: Success
+ * %false: No response buffer space was available
+ */
+static inline bool svcxdr_set_accept_stat(struct svc_rqst *rqstp)
+{
+ struct xdr_stream *xdr = &rqstp->rq_res_stream;
+
+ rqstp->rq_accept_statp = xdr_reserve_space(xdr, XDR_UNIT);
+ if (unlikely(!rqstp->rq_accept_statp))
+ return false;
+ *rqstp->rq_accept_statp = rpc_success;
+ return true;
+}
+
#endif /* SUNRPC_SVC_H */
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index d42a75b3be10..775368802762 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -26,7 +26,6 @@ struct svc_xprt_ops {
void (*xpo_release_rqst)(struct svc_rqst *);
void (*xpo_detach)(struct svc_xprt *);
void (*xpo_free)(struct svc_xprt *);
- void (*xpo_secure_port)(struct svc_rqst *rqstp);
void (*xpo_kill_temp_xprt)(struct svc_xprt *);
void (*xpo_start_tls)(struct svc_xprt *);
};
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index f84e2a1358e1..72014c9216fc 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -188,7 +188,6 @@ xdr_adjust_iovec(struct kvec *iov, __be32 *p)
/*
* XDR buffer helper functions
*/
-extern void xdr_shift_buf(struct xdr_buf *, size_t);
extern void xdr_buf_from_iov(const struct kvec *, struct xdr_buf *);
extern int xdr_buf_subsegment(const struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int);
extern void xdr_buf_trim(struct xdr_buf *, unsigned int);
@@ -247,6 +246,7 @@ extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec,
size_t nbytes);
extern void __xdr_commit_encode(struct xdr_stream *xdr);
extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len);
+extern void xdr_truncate_decode(struct xdr_stream *xdr, size_t len);
extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen);
extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
unsigned int base, unsigned int len);
@@ -346,6 +346,11 @@ ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str,
size_t size);
ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
size_t maxlen, gfp_t gfp_flags);
+ssize_t xdr_stream_decode_opaque_auth(struct xdr_stream *xdr, u32 *flavor,
+ void **body, unsigned int *body_len);
+ssize_t xdr_stream_encode_opaque_auth(struct xdr_stream *xdr, u32 flavor,
+ void *body, unsigned int body_len);
+
/**
* xdr_align_size - Calculate padded size of an object
* @n: Size of an object being XDR encoded (in bytes)
@@ -470,6 +475,27 @@ xdr_stream_encode_u32(struct xdr_stream *xdr, __u32 n)
}
/**
+ * xdr_stream_encode_be32 - Encode a big-endian 32-bit integer
+ * @xdr: pointer to xdr_stream
+ * @n: integer to encode
+ *
+ * Return values:
+ * On success, returns length in bytes of XDR buffer consumed
+ * %-EMSGSIZE on XDR buffer overflow
+ */
+static inline ssize_t
+xdr_stream_encode_be32(struct xdr_stream *xdr, __be32 n)
+{
+ const size_t len = sizeof(n);
+ __be32 *p = xdr_reserve_space(xdr, len);
+
+ if (unlikely(!p))
+ return -EMSGSIZE;
+ *p = n;
+ return len;
+}
+
+/**
* xdr_stream_encode_u64 - Encode a 64-bit integer
* @xdr: pointer to xdr_stream
* @n: 64-bit integer to encode
diff --git a/include/trace/events/rpcgss.h b/include/trace/events/rpcgss.h
index 3f121eed369e..ba2d96a1bc2f 100644
--- a/include/trace/events/rpcgss.h
+++ b/include/trace/events/rpcgss.h
@@ -206,8 +206,30 @@ DECLARE_EVENT_CLASS(rpcgss_svc_gssapi_class,
), \
TP_ARGS(rqstp, maj_stat))
+DEFINE_SVC_GSSAPI_EVENT(wrap);
DEFINE_SVC_GSSAPI_EVENT(unwrap);
DEFINE_SVC_GSSAPI_EVENT(mic);
+DEFINE_SVC_GSSAPI_EVENT(get_mic);
+
+TRACE_EVENT(rpcgss_svc_wrap_failed,
+ TP_PROTO(
+ const struct svc_rqst *rqstp
+ ),
+
+ TP_ARGS(rqstp),
+
+ TP_STRUCT__entry(
+ __field(u32, xid)
+ __string(addr, rqstp->rq_xprt->xpt_remotebuf)
+ ),
+
+ TP_fast_assign(
+ __entry->xid = be32_to_cpu(rqstp->rq_xid);
+ __assign_str(addr, rqstp->rq_xprt->xpt_remotebuf);
+ ),
+
+ TP_printk("addr=%s xid=0x%08x", __get_str(addr), __entry->xid)
+);
TRACE_EVENT(rpcgss_svc_unwrap_failed,
TP_PROTO(
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index 37604e0e5963..3ca54536f8f7 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -1819,20 +1819,20 @@ TRACE_EVENT(svc_stats_latency,
#define show_svc_xprt_flags(flags) \
__print_flags(flags, "|", \
- { (1UL << XPT_BUSY), "XPT_BUSY"}, \
- { (1UL << XPT_CONN), "XPT_CONN"}, \
- { (1UL << XPT_CLOSE), "XPT_CLOSE"}, \
- { (1UL << XPT_DATA), "XPT_DATA"}, \
- { (1UL << XPT_TEMP), "XPT_TEMP"}, \
- { (1UL << XPT_DEAD), "XPT_DEAD"}, \
- { (1UL << XPT_CHNGBUF), "XPT_CHNGBUF"}, \
- { (1UL << XPT_DEFERRED), "XPT_DEFERRED"}, \
- { (1UL << XPT_OLD), "XPT_OLD"}, \
- { (1UL << XPT_LISTENER), "XPT_LISTENER"}, \
- { (1UL << XPT_CACHE_AUTH), "XPT_CACHE_AUTH"}, \
- { (1UL << XPT_LOCAL), "XPT_LOCAL"}, \
- { (1UL << XPT_KILL_TEMP), "XPT_KILL_TEMP"}, \
- { (1UL << XPT_CONG_CTRL), "XPT_CONG_CTRL"})
+ { BIT(XPT_BUSY), "BUSY" }, \
+ { BIT(XPT_CONN), "CONN" }, \
+ { BIT(XPT_CLOSE), "CLOSE" }, \
+ { BIT(XPT_DATA), "DATA" }, \
+ { BIT(XPT_TEMP), "TEMP" }, \
+ { BIT(XPT_DEAD), "DEAD" }, \
+ { BIT(XPT_CHNGBUF), "CHNGBUF" }, \
+ { BIT(XPT_DEFERRED), "DEFERRED" }, \
+ { BIT(XPT_OLD), "OLD" }, \
+ { BIT(XPT_LISTENER), "LISTENER" }, \
+ { BIT(XPT_CACHE_AUTH), "CACHE_AUTH" }, \
+ { BIT(XPT_LOCAL), "LOCAL" }, \
+ { BIT(XPT_KILL_TEMP), "KILL_TEMP" }, \
+ { BIT(XPT_CONG_CTRL), "CONG_CTRL" })
TRACE_EVENT(svc_xprt_create_err,
TP_PROTO(