linux_dsm_epyc7002/include/linux/sunrpc/gss_api.h
Chuck Lever a7e429a6fa SUNRPC: Fix GSS privacy computation of auth->au_ralign
When the au_ralign field was added to gss_unwrap_resp_priv, the
wrong calculation was used. Setting au_rslack == au_ralign is
probably correct for kerberos_v1 privacy, but kerberos_v2 privacy
adds additional GSS data after the clear text RPC message.
au_ralign needs to be smaller than au_rslack in that fairly common
case.

When xdr_buf_trim() is restored to gss_unwrap_kerberos_v2(), it does
exactly what I feared it would: it trims off part of the clear text
RPC message. However, that's because rpc_prepare_reply_pages() does
not set up the rq_rcv_buf's tail correctly because au_ralign is too
large.

Fixing the au_ralign computation also corrects the alignment of
rq_rcv_buf->pages so that the client does not have to shift reply
data payloads after they are received.

Fixes: 35e77d21ba ("SUNRPC: Add rpc_auth::au_ralign field")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2020-04-27 10:58:30 -04:00

164 lines
4.4 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/include/linux/sunrpc/gss_api.h
*
* Somewhat simplified version of the gss api.
*
* Dug Song <dugsong@monkey.org>
* Andy Adamson <andros@umich.edu>
* Bruce Fields <bfields@umich.edu>
* Copyright (c) 2000 The Regents of the University of Michigan
*/
#ifndef _LINUX_SUNRPC_GSS_API_H
#define _LINUX_SUNRPC_GSS_API_H
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/uio.h>
/* The mechanism-independent gss-api context: */
struct gss_ctx {
struct gss_api_mech *mech_type;
void *internal_ctx_id;
unsigned int slack, align;
};
#define GSS_C_NO_BUFFER ((struct xdr_netobj) 0)
#define GSS_C_NO_CONTEXT ((struct gss_ctx *) 0)
#define GSS_C_QOP_DEFAULT (0)
/*XXX arbitrary length - is this set somewhere? */
#define GSS_OID_MAX_LEN 32
struct rpcsec_gss_oid {
unsigned int len;
u8 data[GSS_OID_MAX_LEN];
};
/* From RFC 3530 */
struct rpcsec_gss_info {
struct rpcsec_gss_oid oid;
u32 qop;
u32 service;
};
/* gss-api prototypes; note that these are somewhat simplified versions of
* the prototypes specified in RFC 2744. */
int gss_import_sec_context(
const void* input_token,
size_t bufsize,
struct gss_api_mech *mech,
struct gss_ctx **ctx_id,
time64_t *endtime,
gfp_t gfp_mask);
u32 gss_get_mic(
struct gss_ctx *ctx_id,
struct xdr_buf *message,
struct xdr_netobj *mic_token);
u32 gss_verify_mic(
struct gss_ctx *ctx_id,
struct xdr_buf *message,
struct xdr_netobj *mic_token);
u32 gss_wrap(
struct gss_ctx *ctx_id,
int offset,
struct xdr_buf *outbuf,
struct page **inpages);
u32 gss_unwrap(
struct gss_ctx *ctx_id,
int offset,
int len,
struct xdr_buf *inbuf);
u32 gss_delete_sec_context(
struct gss_ctx **ctx_id);
rpc_authflavor_t gss_svc_to_pseudoflavor(struct gss_api_mech *, u32 qop,
u32 service);
u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor);
bool gss_pseudoflavor_to_datatouch(struct gss_api_mech *, u32 pseudoflavor);
char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service);
struct pf_desc {
u32 pseudoflavor;
u32 qop;
u32 service;
char *name;
char *auth_domain_name;
bool datatouch;
};
/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and
* mechanisms may be dynamically registered or unregistered by modules. */
/* Each mechanism is described by the following struct: */
struct gss_api_mech {
struct list_head gm_list;
struct module *gm_owner;
struct rpcsec_gss_oid gm_oid;
char *gm_name;
const struct gss_api_ops *gm_ops;
/* pseudoflavors supported by this mechanism: */
int gm_pf_num;
struct pf_desc * gm_pfs;
/* Should the following be a callback operation instead? */
const char *gm_upcall_enctypes;
};
/* and must provide the following operations: */
struct gss_api_ops {
int (*gss_import_sec_context)(
const void *input_token,
size_t bufsize,
struct gss_ctx *ctx_id,
time64_t *endtime,
gfp_t gfp_mask);
u32 (*gss_get_mic)(
struct gss_ctx *ctx_id,
struct xdr_buf *message,
struct xdr_netobj *mic_token);
u32 (*gss_verify_mic)(
struct gss_ctx *ctx_id,
struct xdr_buf *message,
struct xdr_netobj *mic_token);
u32 (*gss_wrap)(
struct gss_ctx *ctx_id,
int offset,
struct xdr_buf *outbuf,
struct page **inpages);
u32 (*gss_unwrap)(
struct gss_ctx *ctx_id,
int offset,
int len,
struct xdr_buf *buf);
void (*gss_delete_sec_context)(
void *internal_ctx_id);
};
int gss_mech_register(struct gss_api_mech *);
void gss_mech_unregister(struct gss_api_mech *);
/* returns a mechanism descriptor given an OID, and increments the mechanism's
* reference count. */
struct gss_api_mech * gss_mech_get_by_OID(struct rpcsec_gss_oid *);
/* Given a GSS security tuple, look up a pseudoflavor */
rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *);
/* Given a pseudoflavor, look up a GSS security tuple */
int gss_mech_flavor2info(rpc_authflavor_t, struct rpcsec_gss_info *);
/* Returns a reference to a mechanism, given a name like "krb5" etc. */
struct gss_api_mech *gss_mech_get_by_name(const char *);
/* Similar, but get by pseudoflavor. */
struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32);
struct gss_api_mech * gss_mech_get(struct gss_api_mech *);
/* For every successful gss_mech_get or gss_mech_get_by_* call there must be a
* corresponding call to gss_mech_put. */
void gss_mech_put(struct gss_api_mech *);
#endif /* _LINUX_SUNRPC_GSS_API_H */