> On Dec 2, 2022, at 3:48 PM, Kees Cook <keescook@xxxxxxxxxxxx> wrote: > > When built with Control Flow Integrity, function prototypes between > caller and function declaration must match. These mismatches are visible > at compile time with the new -Wcast-function-type-strict in Clang[1]. > > There were 97 warnings produced by NFS. For example: > > fs/nfsd/nfs4xdr.c:2228:17: warning: cast from '__be32 (*)(struct nfsd4_compoundargs *, struct nfsd4_access *)' (aka 'unsigned int (*)(struct nfsd4_compoundargs *, struct nfsd4_access *)') to 'nfsd4_dec' (aka 'unsigned int (*)(struct nfsd4_compoundargs *, void *)') converts to incompatible function type [-Wcast-function-type-strict] > [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > The enc/dec callbacks were defined as passing "void *" as the second > argument, but were being implicitly cast to a new type. Replace the > argument with union nfsd4_op_u, and perform explicit member selection > in the function body. There are no resulting binary differences. > > Changes were made mechanically using the following Coccinelle script, > with minor by-hand fixes for members that didn't already match their > existing argument name: > > @find@ > identifier func; > type T, opsT; > identifier ops, N; > @@ > > opsT ops[] = { > [N] = (T) func, > }; > > @already_void@ > identifier find.func; > identifier name; > @@ > > func(..., > -void > +union nfsd4_op_u > *name) > { > ... > } > > @proto depends on !already_void@ > identifier find.func; > type T; > identifier name; > position p; > @@ > > func@p(..., > T name > ) { > ... > } > > @script:python get_member@ > type_name << proto.T; > member; > @@ > > coccinelle.member = cocci.make_ident(type_name.split("_", 1)[1].split(' ',1)[0]) > > @convert@ > identifier find.func; > type proto.T; > identifier proto.name; > position proto.p; > identifier get_member.member; > @@ > > func@p(..., > - T name > + union nfsd4_op_u *u > ) { > + T name = &u->member; > ... > } > > @cast@ > identifier find.func; > type T, opsT; > identifier ops, N; > @@ > > opsT ops[] = { > [N] = > - (T) > func, > }; > > Cc: Chuck Lever <chuck.lever@xxxxxxxxxx> > Cc: Jeff Layton <jlayton@xxxxxxxxxx> > Cc: Gustavo A. R. Silva <gustavoars@xxxxxxxxxx> > Cc: linux-nfs@xxxxxxxxxxxxxxx > Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx> > --- > v1: https://lore.kernel.org/lkml/20221007235406.2951724-1-keescook@xxxxxxxxxxxx/ > v2: switch to using "union nfsd4_op_u" (chuck) > --- > fs/nfsd/nfs4xdr.c | 632 +++++++++++++++++++++++++++------------------- > 1 file changed, 377 insertions(+), 255 deletions(-) Lightly tested here and applied for v6.2. Many thanks! -- Chuck Lever