Skip to content

Commit cf64b9b

Browse files
neilbrownchucklever
authored andcommitted
SUNRPC: return proper error from get_expiry()
The get_expiry() function currently returns a timestamp, and uses the special return value of 0 to indicate an error. Unfortunately this causes a problem when 0 is the correct return value. On a system with no RTC it is possible that the boot time will be seen to be "3". When exportfs probes to see if a particular filesystem supports NFS export it tries to cache information with an expiry time of "3". The intention is for this to be "long in the past". Even with no RTC it will not be far in the future (at most a second or two) so this is harmless. But if the boot time happens to have been calculated to be "3", then get_expiry will fail incorrectly as it converts the number to "seconds since bootime" - 0. To avoid this problem we change get_expiry() to report the error quite separately from the expiry time. The error is now the return value. The expiry time is reported through a by-reference parameter. Reported-by: Jerry Zhang <jerry@skydio.com> Tested-by: Jerry Zhang <jerry@skydio.com> Signed-off-by: NeilBrown <neilb@suse.de> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 2f90e18 commit cf64b9b

File tree

5 files changed

+30
-30
lines changed

5 files changed

+30
-30
lines changed

fs/nfsd/export.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
123123

124124
/* OK, we seem to have a valid key */
125125
key.h.flags = 0;
126-
key.h.expiry_time = get_expiry(&mesg);
127-
if (key.h.expiry_time == 0)
126+
err = get_expiry(&mesg, &key.h.expiry_time);
127+
if (err)
128128
goto out;
129129

130-
key.ek_client = dom;
130+
key.ek_client = dom;
131131
key.ek_fsidtype = fsidtype;
132132
memcpy(key.ek_fsid, buf, len);
133133

@@ -610,9 +610,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
610610
exp.ex_devid_map = NULL;
611611

612612
/* expiry */
613-
err = -EINVAL;
614-
exp.h.expiry_time = get_expiry(&mesg);
615-
if (exp.h.expiry_time == 0)
613+
err = get_expiry(&mesg, &exp.h.expiry_time);
614+
if (err)
616615
goto out3;
617616

618617
/* flags */
@@ -624,7 +623,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
624623
if (err || an_int < 0)
625624
goto out3;
626625
exp.ex_flags= an_int;
627-
626+
628627
/* anon uid */
629628
err = get_int(&mesg, &an_int);
630629
if (err)

fs/nfsd/nfs4idmap.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
240240
goto out;
241241

242242
/* expiry */
243-
ent.h.expiry_time = get_expiry(&buf);
244-
if (ent.h.expiry_time == 0)
243+
error = get_expiry(&buf, &ent.h.expiry_time);
244+
if (error)
245245
goto out;
246246

247247
error = -ENOMEM;
@@ -408,8 +408,8 @@ nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
408408
memcpy(ent.name, buf1, sizeof(ent.name));
409409

410410
/* expiry */
411-
ent.h.expiry_time = get_expiry(&buf);
412-
if (ent.h.expiry_time == 0)
411+
error = get_expiry(&buf, &ent.h.expiry_time);
412+
if (error)
413413
goto out;
414414

415415
/* ID */

include/linux/sunrpc/cache.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -300,17 +300,18 @@ static inline int get_time(char **bpp, time64_t *time)
300300
return 0;
301301
}
302302

303-
static inline time64_t get_expiry(char **bpp)
303+
static inline int get_expiry(char **bpp, time64_t *rvp)
304304
{
305-
time64_t rv;
305+
int error;
306306
struct timespec64 boot;
307307

308-
if (get_time(bpp, &rv))
309-
return 0;
310-
if (rv < 0)
311-
return 0;
308+
error = get_time(bpp, rvp);
309+
if (error)
310+
return error;
311+
312312
getboottime64(&boot);
313-
return rv - boot.tv_sec;
313+
(*rvp) -= boot.tv_sec;
314+
return 0;
314315
}
315316

316317
#endif /* _LINUX_SUNRPC_CACHE_H_ */

net/sunrpc/auth_gss/svcauth_gss.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,11 @@ static int rsi_parse(struct cache_detail *cd,
257257

258258
rsii.h.flags = 0;
259259
/* expiry */
260-
expiry = get_expiry(&mesg);
261-
status = -EINVAL;
262-
if (expiry == 0)
260+
status = get_expiry(&mesg, &expiry);
261+
if (status)
263262
goto out;
264263

264+
status = -EINVAL;
265265
/* major/minor */
266266
len = qword_get(&mesg, buf, mlen);
267267
if (len <= 0)
@@ -483,11 +483,11 @@ static int rsc_parse(struct cache_detail *cd,
483483

484484
rsci.h.flags = 0;
485485
/* expiry */
486-
expiry = get_expiry(&mesg);
487-
status = -EINVAL;
488-
if (expiry == 0)
486+
status = get_expiry(&mesg, &expiry);
487+
if (status)
489488
goto out;
490489

490+
status = -EINVAL;
491491
rscp = rsc_lookup(cd, &rsci);
492492
if (!rscp)
493493
goto out;

net/sunrpc/svcauth_unix.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,9 @@ static int ip_map_parse(struct cache_detail *cd,
225225
return -EINVAL;
226226
}
227227

228-
expiry = get_expiry(&mesg);
229-
if (expiry ==0)
230-
return -EINVAL;
228+
err = get_expiry(&mesg, &expiry);
229+
if (err)
230+
return err;
231231

232232
/* domainname, or empty for NEGATIVE */
233233
len = qword_get(&mesg, buf, mlen);
@@ -506,9 +506,9 @@ static int unix_gid_parse(struct cache_detail *cd,
506506
uid = make_kuid(current_user_ns(), id);
507507
ug.uid = uid;
508508

509-
expiry = get_expiry(&mesg);
510-
if (expiry == 0)
511-
return -EINVAL;
509+
err = get_expiry(&mesg, &expiry);
510+
if (err)
511+
return err;
512512

513513
rv = get_int(&mesg, &gids);
514514
if (rv || gids < 0 || gids > 8192)

0 commit comments

Comments
 (0)