* [PATCH 0/2]
@ 2025-12-08 20:03 Sergey Shtylyov
2025-12-08 20:03 ` [PATCH 1/2] NFSv4: pass lease period in seconds to nfs4_set_lease_period() Sergey Shtylyov
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Sergey Shtylyov @ 2025-12-08 20:03 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker, linux-nfs; +Cc: Sergey Shtylyov
The nfs_client::cl_lease_time field (as well as the jiffies variable it's
used with) is declared as *unsigned long*, which is 32-bit type on 32-bit
arches and 64-bit type on 64-bit arches. When nfs4_set_lease_period() that
sets nfs_client::cl_lease_time is called, 32-bit nfs_fsinfo::lease_time
field is multiplied by HZ -- that might overflow before being implicitly
cast to *unsigned long*. Actually, there's no need to multiply by HZ at
all the call sites of nfs4_set_lease_period() -- it makes more sense to do
that once, inside that function. That way, we can avoid such overflow by
capping the lease period at e.g. 1 hour before multipying it by HZ...
The patches below are against the linux-next branch of Trond Myklebust's
linux-nfs.git repo.
Sergey Shtylyov (2):
NFSv4: pass lease period in seconds to nfs4_set_lease_period()
NFSv4: limit lease period in nfs4_set_lease_period()
fs/nfs/nfs4_fs.h | 3 +--
fs/nfs/nfs4proc.c | 2 +-
fs/nfs/nfs4renewd.c | 15 ++++++++++++---
fs/nfs/nfs4state.c | 2 +-
4 files changed, 15 insertions(+), 7 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] NFSv4: pass lease period in seconds to nfs4_set_lease_period()
2025-12-08 20:03 [PATCH 0/2] Sergey Shtylyov
@ 2025-12-08 20:03 ` Sergey Shtylyov
2025-12-08 20:03 ` [PATCH 2/2] NFSv4: limit lease period in nfs4_set_lease_period() Sergey Shtylyov
2025-12-08 20:07 ` [PATCH 0/2] Sergey Shtylyov
2 siblings, 0 replies; 4+ messages in thread
From: Sergey Shtylyov @ 2025-12-08 20:03 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker, linux-nfs; +Cc: Sergey Shtylyov
There's no need to multiply the lease period by HZ at all the call sites of
nfs4_set_lease_period() -- it makes more sense to do that only once, inside
that function, by passing to it lease period as 32-bit # of seconds instead
of 32/64-bit *unsigned long* # of jiffies...
Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
---
fs/nfs/nfs4_fs.h | 3 +--
fs/nfs/nfs4proc.c | 2 +-
fs/nfs/nfs4renewd.c | 7 ++++---
fs/nfs/nfs4state.c | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index c34c89af9c7d..44cf167f65c6 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -464,8 +464,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *);
extern void nfs4_schedule_state_renewal(struct nfs_client *);
extern void nfs4_kill_renewd(struct nfs_client *);
extern void nfs4_renew_state(struct work_struct *);
-extern void nfs4_set_lease_period(struct nfs_client *clp, unsigned long lease);
-
+extern void nfs4_set_lease_period(struct nfs_client *clp, u32 period);
/* nfs4state.c */
extern const nfs4_stateid current_stateid;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ec1ce593dea2..b66f97acafde 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5556,7 +5556,7 @@ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, str
err = _nfs4_do_fsinfo(server, fhandle, fsinfo);
trace_nfs4_fsinfo(server, fhandle, fsinfo->fattr, err);
if (err == 0) {
- nfs4_set_lease_period(server->nfs_client, fsinfo->lease_time * HZ);
+ nfs4_set_lease_period(server->nfs_client, fsinfo->lease_time);
break;
}
err = nfs4_handle_exception(server, err, &exception);
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 18ae614e5a6c..043b2de8d416 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -137,11 +137,12 @@ nfs4_kill_renewd(struct nfs_client *clp)
* nfs4_set_lease_period - Sets the lease period on a nfs_client
*
* @clp: pointer to nfs_client
- * @lease: new value for lease period
+ * @period: new value for lease period (in seconds)
*/
-void nfs4_set_lease_period(struct nfs_client *clp,
- unsigned long lease)
+void nfs4_set_lease_period(struct nfs_client *clp, u32 period)
{
+ unsigned long lease = period * HZ;
+
spin_lock(&clp->cl_lock);
clp->cl_lease_time = lease;
spin_unlock(&clp->cl_lock);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 01179f7de322..a435d4d47b3c 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -103,7 +103,7 @@ static int nfs4_setup_state_renewal(struct nfs_client *clp)
status = nfs4_proc_get_lease_time(clp, &fsinfo);
if (status == 0) {
- nfs4_set_lease_period(clp, fsinfo.lease_time * HZ);
+ nfs4_set_lease_period(clp, fsinfo.lease_time);
nfs4_schedule_state_renewal(clp);
}
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] NFSv4: limit lease period in nfs4_set_lease_period()
2025-12-08 20:03 [PATCH 0/2] Sergey Shtylyov
2025-12-08 20:03 ` [PATCH 1/2] NFSv4: pass lease period in seconds to nfs4_set_lease_period() Sergey Shtylyov
@ 2025-12-08 20:03 ` Sergey Shtylyov
2025-12-08 20:07 ` [PATCH 0/2] Sergey Shtylyov
2 siblings, 0 replies; 4+ messages in thread
From: Sergey Shtylyov @ 2025-12-08 20:03 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker, linux-nfs; +Cc: Sergey Shtylyov
In nfs4_set_lease_period(), the passed 32-bit lease period in seconds is
multiplied by HZ -- that might overflow before being implicitly cast to
*unsigned long* (32/64-bit type), while initializing the lease variable.
Cap the lease period at MAX_LEASE_PERIOD (#define'd to 1 hour for now),
before multipying to avoid such overflow...
Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.
Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
Suggested-by: Trond Myklebust <trondmy@kernel.org>
---
fs/nfs/nfs4renewd.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 043b2de8d416..30065df1482e 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -133,6 +133,8 @@ nfs4_kill_renewd(struct nfs_client *clp)
cancel_delayed_work_sync(&clp->cl_renewd);
}
+#define MAX_LEASE_PERIOD (60 * 60) /* 1 hour */
+
/**
* nfs4_set_lease_period - Sets the lease period on a nfs_client
*
@@ -141,7 +143,13 @@ nfs4_kill_renewd(struct nfs_client *clp)
*/
void nfs4_set_lease_period(struct nfs_client *clp, u32 period)
{
- unsigned long lease = period * HZ;
+ unsigned long lease;
+
+ /* Limit the lease period */
+ if (period < MAX_LEASE_PERIOD)
+ lease = period * HZ;
+ else
+ lease = MAX_LEASE_PERIOD * HZ;
spin_lock(&clp->cl_lock);
clp->cl_lease_time = lease;
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2]
2025-12-08 20:03 [PATCH 0/2] Sergey Shtylyov
2025-12-08 20:03 ` [PATCH 1/2] NFSv4: pass lease period in seconds to nfs4_set_lease_period() Sergey Shtylyov
2025-12-08 20:03 ` [PATCH 2/2] NFSv4: limit lease period in nfs4_set_lease_period() Sergey Shtylyov
@ 2025-12-08 20:07 ` Sergey Shtylyov
2 siblings, 0 replies; 4+ messages in thread
From: Sergey Shtylyov @ 2025-12-08 20:07 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker, linux-nfs
Argh, I forgot to finish the subject! :-/ I'll repost...
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-12-08 20:19 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-08 20:03 [PATCH 0/2] Sergey Shtylyov
2025-12-08 20:03 ` [PATCH 1/2] NFSv4: pass lease period in seconds to nfs4_set_lease_period() Sergey Shtylyov
2025-12-08 20:03 ` [PATCH 2/2] NFSv4: limit lease period in nfs4_set_lease_period() Sergey Shtylyov
2025-12-08 20:07 ` [PATCH 0/2] Sergey Shtylyov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox