| 1663ea5b | 12-Jul-2026 |
Chuck Lever <cel@kernel.org> |
xdrgen: Reject out-of-range program, version, and procedure numbers
RFC 5531 assigns only unsigned constants to program, version, and procedure numbers (Section 12.3) and encodes each as an unsigned
xdrgen: Reject out-of-range program, version, and procedure numbers
RFC 5531 assigns only unsigned constants to program, version, and procedure numbers (Section 12.3) and encodes each as an unsigned 32-bit integer (Section 9), so a valid number falls within [0, 2**32 - 1]. RFC 4506 Section 6.2 permits a signed decimal constant for XDR constants in general and sets no ceiling on magnitude, so the grammar accepts an out-of-range value without complaint. It reaches generated code -- a negative procedure number emerges as an enumerator such as "FOO = -5", valid C that compiles cleanly even though the wire field is an unsigned 32-bit integer. Thus the xdrgen front end is the only place that can reject the malformed value.
Extend the semantic checks to require each program, version, and procedure number to fall within [0, 2**32 - 1].
Link: https://patch.msgid.link/20260712203451.124902-6-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
show more ...
|
| 69b89515 | 12-Jul-2026 |
Chuck Lever <cel@kernel.org> |
xdrgen: Enforce RFC 5531 name and number scoping for RPC programs
The duplicate-identifier check enforces the RFC 4506 name space for XDR type and constant identifiers but ignores what an RPC progra
xdrgen: Enforce RFC 5531 name and number scoping for RPC programs
The duplicate-identifier check enforces the RFC 4506 name space for XDR type and constant identifiers but ignores what an RPC program definition adds. RFC 5531 Section 12.3 completes the model: a program identifier shares the specification-wide name space with constant and type identifiers, a version name and number are unique within their program, and a procedure name and number are unique within their version.
xdrgen currently accepts a specification that breaks any of these rules, and the symptom depends on which rule. A duplicate procedure name reaches the generated header as a redeclared enumerator, which the C compiler rejects. A duplicate procedure number is more dangerous because it is silent: the two procedures emit enumerators of equal value -- valid C that compiles cleanly -- leaving a dispatch collision to surface only at run time. A duplicate program name shares the specification-wide name space with constants and types and is caught alongside them.
Extend the check to enforce RFC 5531 scoping in full.
Link: https://patch.msgid.link/20260712203451.124902-5-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
show more ...
|
| b75e1a25 | 12-Jul-2026 |
Chuck Lever <cel@kernel.org> |
xdrgen: Reject specifications that define a name twice
When an RPC specification defines the same type or constant name more than once, currently xdrgen emits every definition without complaint. The
xdrgen: Reject specifications that define a name twice
When an RPC specification defines the same type or constant name more than once, currently xdrgen emits every definition without complaint. The duplication surfaces later as a C compiler error about a redefined struct or function that points at generated code instead of the actual offending line in the .x source.
RFC 4506 Section 6.4 places constant and type identifiers in a single name space that must be unique within a specification. Add a semantic check that enforces this rule.
Link: https://patch.msgid.link/20260712203451.124902-4-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
show more ...
|
| e1391920 | 12-Jul-2026 |
Chuck Lever <cel@kernel.org> |
xdrgen: Record the source position of each declared identifier
In preparation for semantic checks that reject a malformed specification, record where each declared identifier appears in the source s
xdrgen: Record the source position of each declared identifier
In preparation for semantic checks that reject a malformed specification, record where each declared identifier appears in the source so a diagnostic can point at the name in error.
The transformer keeps each identifier's spelling but discards its position, retaining only the position of the enclosing definition. A caret built from that position falls on the definition keyword rather than on the identifier, because the definition production begins at the keyword.
Store the identifier's own line and column on every named construct: constants, enumerated types and their enumerators, structs, unions, pointers, typedef declarations, and RPC program, version, and procedure names. The fields live on the AST base node and are keyword-only, so lark's positional construction of each node is unaffected; a construct whose position is not recorded leaves them zero.
Link: https://patch.msgid.link/20260712203451.124902-3-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
show more ...
|
| 883fe9a7 | 12-Jul-2026 |
Chuck Lever <cel@kernel.org> |
xdrgen: Align the error caret under tab-indented source
When xdrgen reports a parse or transform error, it prints the offending source line followed by a caret marking the column. The source line is
xdrgen: Align the error caret under tab-indented source
When xdrgen reports a parse or transform error, it prints the offending source line followed by a caret marking the column. The source line is emitted with its tab characters intact, but the caret offset is computed from a tab-expanded copy of the text ahead of the column. A terminal expands the line's leading tabs relative to the four-space output indent, while the caret math expands the same tabs from column zero, so the two disagree whenever the line is indented with tabs and the caret lands past the token it should mark.
Render the displayed line with its tabs already expanded so the line and the caret share one tab origin and the four-space indent cancels. Fold the now-identical line-and-caret formatting out of both error handlers into a single helper, so every caller reports the same aligned output.
Link: https://patch.msgid.link/20260712203451.124902-2-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
show more ...
|
| daa52e37 | 12-Jul-2026 |
Chuck Lever <cel@kernel.org> |
xdrgen: Fix opaque and string encoders for unbounded members
The variable-length opaque and string encoder templates emit an unconditional bound check, "if (value->NAME.len > MAXSIZE) return false".
xdrgen: Fix opaque and string encoders for unbounded members
The variable-length opaque and string encoder templates emit an unconditional bound check, "if (value->NAME.len > MAXSIZE) return false". XDR represents an unbounded specifier (opaque foo<>, string foo<>) as a maxsize of 0, so for an unbounded member the check degenerates to "len > 0" and the generated encoder refuses every non-empty value.
The decoder does not share this defect. It delegates to xdrgen_decode_opaque() and xdrgen_decode_string(), which treat a maxlen of 0 as unbounded and skip the length check. The sibling variable-length array templates already guard their bound check with maxsize != "0".
Guard the bound check the same way in each affected template -- the struct and pointer forms of both the opaque and string encoders -- so an unbounded member encodes a payload of any length while a bounded member keeps its limit.
An explicit zero-length bound (foo<0>) parses to the same maxsize of 0 and so also skips the check; xdrgen does not distinguish it from the unbounded form, matching the decoder and the array encoders.
Fixes: 4b132aacb076 ("tools: Add xdrgen") Link: https://patch.msgid.link/20260712193122.116845-6-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
show more ...
|
| d4ca0b0a | 12-Jul-2026 |
Chuck Lever <cel@kernel.org> |
xdrgen: Do not declare union XDR functions in the definitions header
Unlike the struct, enum, typedef, and pointer templates, the union definitions template also emits xdrgen_decode_*() and xdrgen_e
xdrgen: Do not declare union XDR functions in the definitions header
Unlike the struct, enum, typedef, and pointer templates, the union definitions template also emits xdrgen_decode_*() and xdrgen_encode_*() prototypes for a public union into that header. Those prototypes name struct xdr_stream, which the definitions header neither includes nor forward-declares, so any translation unit that includes the definitions header without xdr.h already in scope draws -Wvisibility warnings. The same public prototypes are emitted into the declarations header, which does include <linux/sunrpc/xdr.h>, making the definitions-header copies redundant.
Drop the prototype emission from the union definitions template so it matches the other type templates. Public unions keep their encode and decode prototypes through the declarations header.
Fixes: 4b132aacb076 ("tools: Add xdrgen") Link: https://patch.msgid.link/20260712193122.116845-4-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
show more ...
|
| 0cfead4c | 12-Jul-2026 |
Chuck Lever <cel@kernel.org> |
xdrgen: Share void RPC procedure handlers across programs
The generated server-side decoder and encoder for a void procedure argument or result are named after the RPC program (for example, nfs_svc_
xdrgen: Share void RPC procedure handlers across programs
The generated server-side decoder and encoder for a void procedure argument or result are named after the RPC program (for example, nfs_svc_decode_void). xdrgen derives that prefix from the program name alone, not the version, so two versions of one program built into the same module emit the identical symbol. NFSv2 and NFSv3 both declare program NFS_PROGRAM; once both are converted, fs/nfsd fails to link with multiple definitions of nfs_svc_decode_void and nfs_svc_encode_void.
A void handler carries no program- or version-specific behavior: each merely forwards to xdrgen_decode_void() or xdrgen_encode_void(). Define one shared pair, xdrgen_svc_decode_void() and xdrgen_svc_encode_void(), in the xdrgen builtins, and stop the program generator from emitting a per-program void handler.
lockd is the one in-tree consumer that already emits per-program void handlers, so regenerate the NLMv3 and NLMv4 XDR code to drop nlm_svc_{decode,encode}_void() and nlm4_svc_{decode,encode}_void() and point both procedure tables at the shared handlers. The shared handlers are identical to the generated ones they replace, so no wire behavior changes.
Only the server (svc) handlers are affected. The client-side void stubs remain static and per-program, so they do not collide.
Link: https://patch.msgid.link/20260712193122.116845-3-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
show more ...
|
| 6bc85bab | 09-Jan-2026 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Implement pass-through lines in specifications
XDR specification files can contain lines prefixed with '%' that pass through unchanged to generated output. Traditional rpcgen removes the '%'
xdrgen: Implement pass-through lines in specifications
XDR specification files can contain lines prefixed with '%' that pass through unchanged to generated output. Traditional rpcgen removes the '%' and emits the remainder verbatim, allowing direct insertion of C includes, pragma directives, or other language- specific content into the generated code.
Until now, xdrgen silently discarded these lines during parsing. This prevented specifications from including necessary headers or preprocessor directives that might be required for the generated code to compile correctly.
The grammar now captures pass-through lines instead of ignoring them. A new AST node type represents pass-through content, and the AST transformer strips the leading '%' character. Definition and source generators emit pass-through content in document order, preserving the original placement within the specification.
This brings xdrgen closer to feature parity with traditional rpcgen while maintaining the existing document-order processing model.
Existing generated xdrgen source code has been regenerated.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| 5288993c | 26-Dec-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Add enum value validation to generated decoders
XDR enum decoders generated by xdrgen do not verify that incoming values are valid members of the enum. Incoming out-of-range values from mali
xdrgen: Add enum value validation to generated decoders
XDR enum decoders generated by xdrgen do not verify that incoming values are valid members of the enum. Incoming out-of-range values from malicious or buggy peers propagate through the system unchecked.
Add validation logic to generated enum decoders using a switch statement that explicitly lists valid enumerator values. The compiler optimizes this to a simple range check when enum values are dense (contiguous), while correctly rejecting invalid values for sparse enums with gaps in their value ranges.
The --no-enum-validation option on the source subcommand disables this validation when not needed.
The minimum and maximum fields in _XdrEnum, which were previously unused placeholders for a range-based validation approach, have been removed since the switch-based validation handles both dense and sparse enums correctly.
Because the new mechanism results in substantive changes to generated code, existing .x files are regenerated. Unrelated white space and semicolon changes in the generated code are due to recent commit 1c873a2fd110 ("xdrgen: Don't generate unnecessary semicolon") and commit 38c4df91242b ("xdrgen: Address some checkpatch whitespace complaints").
Reviewed-by: NeilBrown <neil@brown.name> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| 4c53b890 | 26-Dec-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Emit a max_arg_sz macro
struct svc_service has a .vs_xdrsize field that is filled in by servers for each of their RPC programs. This field is supposed to contain the size of the largest proc
xdrgen: Emit a max_arg_sz macro
struct svc_service has a .vs_xdrsize field that is filled in by servers for each of their RPC programs. This field is supposed to contain the size of the largest procedure argument in the RPC program. This value is also sometimes used to size network transport buffers.
Currently, server implementations must manually calculate and hard-code this value, which is error-prone and requires updates when procedure arguments change.
Update xdrgen to determine which procedure argument structure is largest, and emit a macro with a well-known name that contains the size of that structure. Server code then uses this macro when initializing the .vs_xdrsize field.
For NLM version 4, xdrgen now emits:
#define NLM4_MAX_ARGS_SZ (NLM4_nlm4_lockargs_sz)
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| 63a5425f | 26-Dec-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Extend error reporting to AST transformation phase
Commit 277df18d7df9 ("xdrgen: Improve parse error reporting") added clean, compiler-style error messages for syntax errors detected during
xdrgen: Extend error reporting to AST transformation phase
Commit 277df18d7df9 ("xdrgen: Improve parse error reporting") added clean, compiler-style error messages for syntax errors detected during parsing. However, semantic errors discovered during AST transformation still produce verbose Python stack traces.
When an XDR specification references an undefined type, the transformer raises a VisitError wrapping a KeyError. Before this change:
Traceback (most recent call last): File ".../lark/visitors.py", line 124, in _call_userfunc return f(children) ... KeyError: 'fsh4_mode' ... lark.exceptions.VisitError: Error trying to process rule "basic": 'fsh4_mode'
After this change:
file.x:156:2: semantic error Undefined type 'fsh4_mode'
fsh4_mode mode; ^
The new handle_transform_error() function extracts position information from the Lark tree node metadata and formats the error consistently with parse error messages.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| 9abb3549 | 22-Dec-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Improve parse error reporting
The current verbose Lark exception output makes it difficult to quickly identify and fix syntax errors in XDR specifications. Users must wade through hundreds o
xdrgen: Improve parse error reporting
The current verbose Lark exception output makes it difficult to quickly identify and fix syntax errors in XDR specifications. Users must wade through hundreds of lines of cascading errors to find the root cause.
Replace this with concise, compiler-style error messages showing file, line, column, the unexpected token, and the source line with a caret pointing to the error location.
Before: Unexpected token Token('__ANON_1', '+1') at line 14, column 35. Expected one of: * SEMICOLON Previous tokens: [Token('__ANON_0', 'LM_MAXSTRLEN')] [hundreds more cascading errors...]
After: file.x:14:35: parse error Unexpected number '+1'
const LM_MAXNAMELEN = LM_MAXSTRLEN+1; ^
The error handler now raises XdrParseError on the first error, preventing cascading messages that obscure the root cause.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| eb1f3b55 | 22-Dec-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Remove inclusion of nlm4.h header
The client-side source code template mistakenly includes the nlm4.h header file, which is specific to the NLM protocol and should not be present in the gene
xdrgen: Remove inclusion of nlm4.h header
The client-side source code template mistakenly includes the nlm4.h header file, which is specific to the NLM protocol and should not be present in the generic template that generates client stubs for all XDR-based protocols.
Fixes: 903a7d37d9ea ("xdrgen: Update the files included in client-side source code") Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| ae78eb49 | 16-Dec-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Implement short (16-bit) integer types
"short" and "unsigned short" types are not defined in RFC 4506, but are supported by the rpcgen program. An upcoming protocol specification includes at
xdrgen: Implement short (16-bit) integer types
"short" and "unsigned short" types are not defined in RFC 4506, but are supported by the rpcgen program. An upcoming protocol specification includes at least one "unsigned short" field, so xdrgen needs to implement support for these types.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| bf0fe9ad | 08-Dec-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Fix struct prefix for typedef types in program wrappers
The program templates for decoder/argument.j2 and encoder/result.j2 unconditionally add 'struct' prefix to all types. This is incorrec
xdrgen: Fix struct prefix for typedef types in program wrappers
The program templates for decoder/argument.j2 and encoder/result.j2 unconditionally add 'struct' prefix to all types. This is incorrect when an RPC protocol specification lists a typedef'd basic type or an enum as a procedure argument or result (e.g., NFSv2's fhandle or stat), resulting in compiler errors when building generated C code.
Fixes: 4b132aacb076 ("tools: Add xdrgen") Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| 4329010a | 01-Dec-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Address some checkpatch whitespace complaints
This is a roll-up of three template fixes that eliminate noise from checkpatch output so that it's easier to spot non-trivial problems.
To foll
xdrgen: Address some checkpatch whitespace complaints
This is a roll-up of three template fixes that eliminate noise from checkpatch output so that it's easier to spot non-trivial problems.
To follow conventional kernel C style, when a union declaration is marked with "pragma public", there should be a blank line between the emitted "union xxx { ... };" and the decoder and encoder function declarations.
Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| 9654a038 | 20-Nov-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Generate "if" instead of "switch" for boolean union enumerators
Eliminate this warning in code generated by xdrgen:
fs/nfsd/nfs3xdr_gen.c:220:2: warning: switch condition has boolean value
xdrgen: Generate "if" instead of "switch" for boolean union enumerators
Eliminate this warning in code generated by xdrgen:
fs/nfsd/nfs3xdr_gen.c:220:2: warning: switch condition has boolean value [-Wswitch-bool] 220 | switch (ptr->attributes_follow) { | ^ ~~~~~~~~~~~~~~~~~~~~~~
No more -Wswitch-bool warnings when compiling with W=1.
The generated code is functionally equivalent but somewhat more idiomatic.
Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202511172336.Y75zj4v6-lkp@intel.com/ Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| f7cb94fa | 05-Nov-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Fix union declarations
Add a missing template file. This file is used when a union is defined as a public API (ie, "pragma public <union name>;").
Signed-off-by: Chuck Lever <chuck.lever@or
xdrgen: Fix union declarations
Add a missing template file. This file is used when a union is defined as a public API (ie, "pragma public <union name>;").
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| b0f8e1f1 | 29-Oct-2025 |
Khushal Chitturi <kc9282016@gmail.com> |
xdrgen: handle _XdrString in union encoder/decoder
Running xdrgen on xdrgen/tests/test.x fails when generating encoder or decoder functions for union members of type _XdrString. It was because _XdrS
xdrgen: handle _XdrString in union encoder/decoder
Running xdrgen on xdrgen/tests/test.x fails when generating encoder or decoder functions for union members of type _XdrString. It was because _XdrString does not have a spec attribute like _XdrBasic, leading to AttributeError.
This patch updates emit_union_case_spec_definition and emit_union_case_spec_decoder/encoder to handle _XdrString by assigning type_name = "char *" and avoiding referencing to spec.
Testing: Fixed xdrgen tool was run on originally failing test file (tools/net/sunrpc/xdrgen/tests/test.x) and now completes without AttributeError. Modified xdrgen tool was also run against nfs4_1.x (Documentation/sunrpc/xdr/nfs4_1.x). The output header file matches with nfs4_1.h (include/linux/sunrpc/xdrgen/nfs4_1.h). This validates the patch for all XDR input files currently within the kernel.
Changes since v2: - Moved the shebang to the first line - Removed SPDX header to match style of current xdrgen files
Changes since v1: - Corrected email address in Signed-off-by. - Wrapped patch description lines to 72 characters.
Signed-off-by: Khushal Chitturi <kc9282016@gmail.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|
| 42ba5bd2 | 27-Oct-2025 |
Chuck Lever <chuck.lever@oracle.com> |
xdrgen: Fix the variable-length opaque field decoder template
Ensure that variable-length opaques are decoded into the named field, and do not overwrite the structure itself.
Signed-off-by: Chuck L
xdrgen: Fix the variable-length opaque field decoder template
Ensure that variable-length opaques are decoded into the named field, and do not overwrite the structure itself.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
show more ...
|