mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 01:48:58 -04:00
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 1c873a2fd1 ("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>
144 lines
4.2 KiB
Python
Executable File
144 lines
4.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# ex: set filetype=python:
|
|
|
|
"""Translate an XDR specification into executable code that
|
|
can be compiled for the Linux kernel."""
|
|
|
|
__author__ = "Chuck Lever"
|
|
__copyright__ = "Copyright (c) 2024 Oracle and/or its affiliates."
|
|
__license__ = "GPL-2.0 only"
|
|
__version__ = "0.2"
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
import argparse
|
|
|
|
_XDRGEN_DIR = Path(__file__).resolve().parent
|
|
if str(_XDRGEN_DIR) not in sys.path:
|
|
sys.path.insert(0, str(_XDRGEN_DIR))
|
|
|
|
from subcmds import definitions
|
|
from subcmds import declarations
|
|
from subcmds import lint
|
|
from subcmds import source
|
|
|
|
|
|
sys.path.insert(1, "@pythondir@")
|
|
|
|
|
|
def main() -> int:
|
|
"""Parse command-line options"""
|
|
parser = argparse.ArgumentParser(
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
description="Convert an XDR specification to Linux kernel source code",
|
|
epilog="""\
|
|
Copyright (c) 2024 Oracle and/or its affiliates.
|
|
|
|
License GPLv2: <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>
|
|
This is free software. You are free to change and redistribute it.
|
|
There is NO WARRANTY, to the extent permitted by law.""",
|
|
)
|
|
parser.add_argument(
|
|
"--version",
|
|
help="Display the version of this tool",
|
|
action="version",
|
|
version=__version__,
|
|
)
|
|
|
|
subcommands = parser.add_subparsers(title="Subcommands", required=True)
|
|
|
|
definitions_parser = subcommands.add_parser(
|
|
"definitions", help="Generate XDR definitions"
|
|
)
|
|
definitions_parser.add_argument(
|
|
"--annotate",
|
|
action="store_true",
|
|
default=False,
|
|
help="Add annotation comments",
|
|
)
|
|
definitions_parser.add_argument(
|
|
"--language",
|
|
action="store_true",
|
|
default="C",
|
|
help="Output language",
|
|
)
|
|
definitions_parser.add_argument(
|
|
"--peer",
|
|
choices=["server", "client",],
|
|
default="server",
|
|
help="Generate header code for client or server side",
|
|
type=str,
|
|
)
|
|
definitions_parser.add_argument("filename", help="File containing an XDR specification")
|
|
definitions_parser.set_defaults(func=definitions.subcmd)
|
|
|
|
declarations_parser = subcommands.add_parser(
|
|
"declarations", help="Generate function declarations"
|
|
)
|
|
declarations_parser.add_argument(
|
|
"--annotate",
|
|
action="store_true",
|
|
default=False,
|
|
help="Add annotation comments",
|
|
)
|
|
declarations_parser.add_argument(
|
|
"--language",
|
|
action="store_true",
|
|
default="C",
|
|
help="Output language",
|
|
)
|
|
declarations_parser.add_argument(
|
|
"--peer",
|
|
choices=["server", "client",],
|
|
default="server",
|
|
help="Generate code for client or server side",
|
|
type=str,
|
|
)
|
|
declarations_parser.add_argument("filename", help="File containing an XDR specification")
|
|
declarations_parser.set_defaults(func=declarations.subcmd)
|
|
|
|
linter_parser = subcommands.add_parser("lint", help="Check an XDR specification")
|
|
linter_parser.add_argument("filename", help="File containing an XDR specification")
|
|
linter_parser.set_defaults(func=lint.subcmd)
|
|
|
|
source_parser = subcommands.add_parser(
|
|
"source", help="Generate XDR encoder and decoder source code"
|
|
)
|
|
source_parser.add_argument(
|
|
"--annotate",
|
|
action="store_true",
|
|
default=False,
|
|
help="Add annotation comments",
|
|
)
|
|
source_parser.add_argument(
|
|
"--language",
|
|
action="store_true",
|
|
default="C",
|
|
help="Output language",
|
|
)
|
|
source_parser.add_argument(
|
|
"--peer",
|
|
choices=["server", "client",],
|
|
default="server",
|
|
help="Generate code for client or server side",
|
|
type=str,
|
|
)
|
|
source_parser.add_argument(
|
|
"--no-enum-validation",
|
|
action="store_true",
|
|
default=False,
|
|
help="Disable enum value validation in decoders",
|
|
)
|
|
source_parser.add_argument("filename", help="File containing an XDR specification")
|
|
source_parser.set_defaults(func=source.subcmd)
|
|
|
|
args = parser.parse_args()
|
|
return args.func(args)
|
|
|
|
|
|
try:
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|
|
except (KeyboardInterrupt, BrokenPipeError):
|
|
sys.exit(1)
|