From: Chuck Lever <cel@kernel.org>
To: NeilBrown <neil@brown.name>, Jeff Layton <jlayton@kernel.org>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: <linux-nfs@vger.kernel.org>
Subject: [PATCH 4/5] xdrgen: Enforce RFC 5531 name and number scoping for RPC programs
Date: Sun, 12 Jul 2026 16:34:50 -0400 [thread overview]
Message-ID: <20260712203451.124902-5-cel@kernel.org> (raw)
In-Reply-To: <20260712203451.124902-1-cel@kernel.org>
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.
Signed-off-by: Chuck Lever <cel@kernel.org>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 49 ++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index cf68ff5dfe17..ec48506b239a 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -862,6 +862,50 @@ def _introduced_names(value):
yield value.declaration.name, value.declaration
elif isinstance(value, _XdrConstant):
yield value.name, value
+ elif isinstance(value, _RpcProgram):
+ yield value.name, value
+
+
+def _check_rpc_scope_names(program: "_RpcProgram") -> None:
+ """Enforce RFC 5531 Section 12.3 scoping within an RPC program.
+
+ A version name and number are unique within the program and a
+ procedure name and number are unique within its version.
+ """
+ version_names = set()
+ version_numbers = set()
+ for version in program.versions:
+ if version.name in version_names:
+ raise XdrSemanticError(
+ f"duplicate version name '{version.name}'"
+ f" in program '{program.name}'",
+ version,
+ )
+ version_names.add(version.name)
+ if version.number in version_numbers:
+ raise XdrSemanticError(
+ f"duplicate version number {version.number}"
+ f" in program '{program.name}'",
+ version,
+ )
+ version_numbers.add(version.number)
+ procedure_names = set()
+ procedure_numbers = set()
+ for procedure in version.procedures:
+ if procedure.name in procedure_names:
+ raise XdrSemanticError(
+ f"duplicate procedure name '{procedure.name}'"
+ f" in version '{version.name}'",
+ procedure,
+ )
+ procedure_names.add(procedure.name)
+ if procedure.number in procedure_numbers:
+ raise XdrSemanticError(
+ f"duplicate procedure number {procedure.number}"
+ f" in version '{version.name}'",
+ procedure,
+ )
+ procedure_numbers.add(procedure.number)
def check_duplicate_definitions(root: "Specification") -> None:
@@ -869,6 +913,9 @@ def check_duplicate_definitions(root: "Specification") -> None:
RFC 4506 Section 6.4 places constant and type identifiers in a
single name space that must be unique within a specification.
+ RFC 5531 Section 12.3 adds RPC program names to that name space
+ and scopes version names and numbers to their program and
+ procedure names and numbers to their version.
"""
seen = {}
for definition in root.definitions:
@@ -882,6 +929,8 @@ def check_duplicate_definitions(root: "Specification") -> None:
where,
)
seen[name] = where
+ if isinstance(definition.value, _RpcProgram):
+ _check_rpc_scope_names(definition.value)
def transform_parse_tree(parse_tree):
--
2.54.0
next prev parent reply other threads:[~2026-07-12 20:34 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-12 20:34 [PATCH 0/5] xdrgen: Improve diagnostic reporting Chuck Lever
2026-07-12 20:34 ` [PATCH 1/5] xdrgen: Align the error caret under tab-indented source Chuck Lever
2026-07-12 20:34 ` [PATCH 2/5] xdrgen: Record the source position of each declared identifier Chuck Lever
2026-07-12 20:34 ` [PATCH 3/5] xdrgen: Reject specifications that define a name twice Chuck Lever
2026-07-12 20:34 ` Chuck Lever [this message]
2026-07-12 20:34 ` [PATCH 5/5] xdrgen: Reject out-of-range program, version, and procedure numbers Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260712203451.124902-5-cel@kernel.org \
--to=cel@kernel.org \
--cc=dai.ngo@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neil@brown.name \
--cc=okorniev@redhat.com \
--cc=tom@talpey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox