Linux filesystem development
 help / color / mirror / Atom feed
From: David Laight <david.laight.linux@gmail.com>
To: wen.yang@linux.dev
Cc: Joel Granados <joel.granados@kernel.org>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH 01/39] sysctl: replace overloaded extra pointers with typed bounds and context
Date: Wed, 28 Oct 2026 21:09:11 +0000	[thread overview]
Message-ID: <20261028210911.30a8100d@pumpkin> (raw)
In-Reply-To: <fec089bb7a3ea62a5e2006cf578b1efec2df4aff.1793204511.git.wen.yang@linux.dev>

On Thu, 29 Oct 2026 00:34:40 +0800
wen.yang@linux.dev wrote:

> To: Joel Granados <joel.granados@kernel.org>
> Cc: Wen Yang <wen.yang@linux.dev>,  linux-fsdevel@vger.kernel.org,  linux-kernel@vger.kernel.org
> Subject: [RFC PATCH 01/39] sysctl: replace overloaded extra pointers with typed bounds and context
> Date: Thu, 29 Oct 2026 00:34:40 +0800
> 
> From: Wen Yang <wen.yang@linux.dev>
> 
> struct ctl_table has two untyped misc pointers, extra1 and extra2, whose
> meaning depends on the handler that reads them. In-tree use has grown to
> cover at least seven unrelated jobs: a fixed bound, a bound read through a
> pointer on every call, an object or namespace pointer, a small integer
> cookie encoded into the pointer, a lock signal, NULL standing for "no
> bound", and a value the core itself casts to unsigned int while validating
> a u8 range. Nothing in the entry says which job applies, so readers and
> writers have to infer it from the handler, and the core itself gets it
> wrong where it treats extra1 as an unsigned int.
> 
> The overloading is also a memory-safety hazard. An entry that stores
> handler context in data cannot be handed to a standard handler without
> first restoring the real storage, because proc_dointvec() writes through
> data. Every call site has to remember the restore, and one that forgets
> turns a user-supplied integer into a write over a kernel pointer. nf_log
> reaches the same problem from the other side: it replaces data with a
> local buffer inside a single handler, so data means two things within one
> function.
> 
> Replace both jobs with two fields that cannot be confused:
> 
>   - min/max hold numeric bounds by value. Signed handlers read them as
>     signed longs; an absent endpoint is the type limit, not NULL, so zero
>     stays a real bound. A range that changes at run time is refreshed
>     before every call instead of being snapshotted at registration.
> 
>   - priv holds handler context. The core never reads it, standard handlers
>     never touch it, and registration rejects it on a standard handler so
>     context cannot be silently ignored. data and maxlen keep the meaning
>     their handler gives them, including proc_dostring() name lengths and
>     proc_do_large_bitmap() bit counts.
> 
> The range converters read min/max whenever extra1 and extra2 are both
> clear, and keep reading the pointers while they are set. That lets callers
> migrate one subsystem at a time without renaming handlers or adding a
> parallel API: the existing proc_*_minmax entry points keep their names and
> gain numeric semantics as entries drop their extras. Entries that already
> relied on NULL meaning "no bound" now state their type limits explicitly,
> so their behaviour does not change and the meaning of zero stays
> unambiguous.
> 
> This patch is the refactor itself. The next patch converts the debug test
> module to numeric bounds as the first user, and the KUnit suite after it
> makes the contract executable; everything after those is migration of
> existing users and adds no new semantics: fixed bounds become numeric
> values, run-time bounds are refreshed per call, context moves off data, and
> the extra pointers and the compatibility read are removed once the last
> user is gone. Owners that can still be recovered from data keep using
> container_of(); priv is only for entries where no derivation exists.
> 
> Replacing the two pointers with unsigned long min/max follows Eric
> Biederman's suggestion; priv is added here because the same pair of fields
> also carries handler context, which a numeric bound cannot express.
> 
> Suggested-by: Eric W. Biederman <ebiederm@xmission.com>
> Suggested-by: Joel Granados <joel.granados@kernel.org>
> Signed-off-by: Wen Yang <wen.yang@linux.dev>
...
> 
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index b5c2abd12432..294897f3fbb5 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -10,6 +10,7 @@
>  #define pr_fmt(fmt) "mobility: " fmt
>  
>  #include <linux/cpu.h>
> +#include <linux/limits.h>
>  #include <linux/kernel.h>
>  #include <linux/kobject.h>
>  #include <linux/nmi.h>
> @@ -61,6 +62,8 @@ static const struct ctl_table nmi_wd_lpm_factor_ctl_table[] = {
>  		.maxlen		= sizeof(int),
>  		.mode		= 0644,
>  		.proc_handler	= proc_douintvec_minmax,
> +		.min		= 0,
> +		.max		= UINT_MAX,
>  	},

You could save a lot of churn by not adding the '.min = 0' line
and making the function treat the 'silly' case where both min and max
are zero as meaning 'no upper bound'.

As well as saving a lot of diffs, it will be less error prone.

David

  reply	other threads:[~2026-10-28 21:09 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-28 16:34 [RFC PATCH 00/39] sysctl: replace overloaded extra pointers with typed bounds and context wen.yang
2026-10-28 16:34 ` [RFC PATCH 01/39] " wen.yang
2026-10-28 21:09   ` David Laight [this message]
2026-10-28 16:34 ` [RFC PATCH 02/39] test_sysctl: convert bounds to numeric values wen.yang
2026-10-28 16:34 ` [RFC PATCH 03/39] sysctl: add KUnit coverage for numeric bounds and handlers wen.yang
2026-10-28 16:34 ` [RFC PATCH 04/39] sysctl: cover runtime ranges and context lifecycles in KUnit wen.yang
2026-10-28 16:34 ` [RFC PATCH 05/39] sysctl: cover priv in KUnit and the debug test module wen.yang
2026-10-28 16:34 ` [RFC PATCH 06/39] sysctl: convert core table bounds to numeric values wen.yang
2026-10-28 16:34 ` [RFC PATCH 07/39] sysctl: store architecture sysctl bounds by value wen.yang
2026-10-28 16:34 ` [RFC PATCH 08/39] sysctl: store crypto " wen.yang
2026-10-28 16:34 ` [RFC PATCH 09/39] sysctl: store device " wen.yang
2026-10-28 16:34 ` [RFC PATCH 10/39] sysctl: store filesystem " wen.yang
2026-10-28 16:34 ` [RFC PATCH 11/39] sysctl: store message-queue " wen.yang
2026-10-28 16:34 ` [RFC PATCH 12/39] sysctl: store kernel " wen.yang
2026-10-28 16:34 ` [RFC PATCH 13/39] sysctl: store memory-management " wen.yang
2026-10-28 16:34 ` [RFC PATCH 14/39] sysctl: store IPv6 scalar " wen.yang
2026-10-28 16:34 ` [RFC PATCH 15/39] sysctl: store netfilter " wen.yang
2026-10-28 16:34 ` [RFC PATCH 16/39] sysctl: store RPC " wen.yang
2026-10-28 16:34 ` [RFC PATCH 17/39] sysctl: store remaining network " wen.yang
2026-10-28 16:34 ` [RFC PATCH 18/39] sysctl: store security " wen.yang
2026-10-28 16:34 ` [RFC PATCH 19/39] io_uring: store its " wen.yang
2026-10-28 16:34 ` [RFC PATCH 20/39] sysctl: refresh dynamic scheduler and PID bounds per call wen.yang
2026-10-28 16:35 ` [RFC PATCH 21/39] sysctl: refresh device-dependent " wen.yang
2026-10-28 16:35 ` [RFC PATCH 22/39] sysctl: refresh namespace IPC " wen.yang
2026-10-28 16:35 ` [RFC PATCH 23/39] yama: preserve scope locking with numeric sysctl bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 24/39] net: refresh core sysctl limits without bound pointers wen.yang
2026-10-28 16:35 ` [RFC PATCH 25/39] sctp: resolve numeric ranges from the current namespace wen.yang
2026-10-28 16:35 ` [RFC PATCH 26/39] rds: preserve live reconnect limits with numeric bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 27/39] ipv4: preserve live and vector bounds with numeric sysctls wen.yang
2026-10-28 16:35 ` [RFC PATCH 28/39] net: refresh fragment and remaining dynamic sysctl bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 29/39] neighbour: derive sysctl ownership independently of bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 30/39] net: resolve sysctl owners from their backing data wen.yang
2026-10-28 16:35 ` [RFC PATCH 31/39] ipvs: derive sysctl ownership from numeric storage wen.yang
2026-10-28 16:35 ` [RFC PATCH 32/39] sysctl: remove obsolete nr_open bound variables wen.yang
2026-10-28 16:35 ` [RFC PATCH 33/39] ipv6: move address sysctl context to priv wen.yang
2026-10-28 16:35 ` [RFC PATCH 34/39] ipv4: move device " wen.yang
2026-10-28 16:35 ` [RFC PATCH 35/39] netfilter: move logger " wen.yang
2026-10-28 16:35 ` [RFC PATCH 36/39] parport: move device " wen.yang
2026-10-28 16:35 ` [RFC PATCH 37/39] net: move namespace " wen.yang
2026-10-28 16:35 ` [RFC PATCH 38/39] arm64: move vector-length " wen.yang
2026-10-28 16:35 ` [RFC PATCH 39/39] sysctl: remove the extra pointers and the compatibility bounds read wen.yang

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=20261028210911.30a8100d@pumpkin \
    --to=david.laight.linux@gmail.com \
    --cc=joel.granados@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=wen.yang@linux.dev \
    /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