Skip to content

Commit b61b2e3

Browse files
committed
nfs4: ensure that we validate stateids before READ/WRITE ops
Motivation: the current reference implementations of READ and WRITE ops doesn't validate provided state ids. Modification: Update OperationWRITE and OperationREAD to validate state ids in case of nfsv4.1 (v4.0 is implicitly validated by leas renewal). In addition, OperationWRITE will check file open mode. Result: Better spec compliance. Acked-by: Paul Millar Target: master
1 parent 99a0b0f commit b61b2e3

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

core/src/main/java/org/dcache/nfs/v4/OperationREAD.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009 - 2018 Deutsches Elektronen-Synchroton,
2+
* Copyright (c) 2009 - 2025 Deutsches Elektronen-Synchroton,
33
* Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY
44
*
55
* This library is free software; you can redistribute it and/or modify
@@ -65,9 +65,11 @@ public void process(CompoundContext context, nfs_resop4 result) throws IOExcepti
6565
* lease time done through SEQUENCE operations.
6666
*/
6767
context.getStateHandler().updateClientLeaseTime(_args.opread.stateid);
68+
} else {
69+
var client = context.getSession().getClient();
70+
client.state(_args.opread.stateid); // will throw BAD_STATEID if stateid is not valid
6871
}
6972

70-
7173
long offset = _args.opread.offset.value;
7274
int count = _args.opread.count.value;
7375

core/src/main/java/org/dcache/nfs/v4/OperationWRITE.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009 - 2018 Deutsches Elektronen-Synchroton,
2+
* Copyright (c) 2009 - 2025 Deutsches Elektronen-Synchroton,
33
* Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY
44
*
55
* This library is free software; you can redistribute it and/or modify
@@ -21,7 +21,8 @@
2121

2222
import java.io.IOException;
2323
import org.dcache.nfs.nfsstat;
24-
import org.dcache.nfs.v4.xdr.stable_how4;
24+
import org.dcache.nfs.status.OpenModeException;
25+
import org.dcache.nfs.v4.xdr.nfs4_prot;
2526
import org.dcache.nfs.v4.xdr.nfs_argop4;
2627
import org.dcache.nfs.v4.xdr.nfs_opnum4;
2728
import org.dcache.nfs.v4.xdr.count4;
@@ -63,6 +64,7 @@ public void process(CompoundContext context, nfs_resop4 result) throws ChimeraNF
6364
throw new InvalException("path is a symlink");
6465
}
6566

67+
NFS4Client client;
6668
if (context.getMinorversion() == 0) {
6769
/*
6870
* The NFSv4.0 spec requires lease renewal on WRITE.
@@ -72,6 +74,16 @@ public void process(CompoundContext context, nfs_resop4 result) throws ChimeraNF
7274
* lease time done through SEQUENCE operations.
7375
*/
7476
context.getStateHandler().updateClientLeaseTime(_args.opwrite.stateid);
77+
client = context.getStateHandler().getClientIdByStateId(_args.opwrite.stateid);
78+
} else {
79+
client = context.getSession().getClient();
80+
}
81+
82+
var inode = context.currentInode();
83+
// will throw BAD_STATEID if stateid is not valid
84+
int shareAccess = context.getStateHandler().getFileTracker().getShareAccess(client, inode, _args.opwrite.stateid);
85+
if ((shareAccess & nfs4_prot.OPEN4_SHARE_ACCESS_WRITE) == 0) {
86+
throw new OpenModeException("Invalid open mode");
7587
}
7688

7789
long offset = _args.opwrite.offset.value;

0 commit comments

Comments
 (0)