Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7571e4c authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

nfsd4: skip encoder in trivial error cases



Most encoders do nothing in the error case.  But they can still screw
things up in that case: most errors happen very early in rpc processing,
possibly before argument fields are filled in and bounds-tested, so
encoders that do anything other than immediately bail on error can
easily crash in odd error cases.

So just handle errors centrally most of the time to remove the chance of
error.

Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 34b1744c
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -2141,13 +2141,15 @@ static const struct nfsd4_operation nfsd4_ops[] = {
	},
	[OP_LOCK] = {
		.op_func = nfsd4_lock,
		.op_flags = OP_MODIFIES_SOMETHING,
		.op_flags = OP_MODIFIES_SOMETHING |
				OP_NONTRIVIAL_ERROR_ENCODE,
		.op_name = "OP_LOCK",
		.op_rsize_bop = nfsd4_lock_rsize,
		.op_set_currentstateid = nfsd4_set_lockstateid,
	},
	[OP_LOCKT] = {
		.op_func = nfsd4_lockt,
		.op_flags = OP_NONTRIVIAL_ERROR_ENCODE,
		.op_name = "OP_LOCKT",
		.op_rsize_bop = nfsd4_lock_rsize,
	},
@@ -2277,14 +2279,16 @@ static const struct nfsd4_operation nfsd4_ops[] = {
	[OP_SETATTR] = {
		.op_func = nfsd4_setattr,
		.op_name = "OP_SETATTR",
		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME
				| OP_NONTRIVIAL_ERROR_ENCODE,
		.op_rsize_bop = nfsd4_setattr_rsize,
		.op_get_currentstateid = nfsd4_get_setattrstateid,
	},
	[OP_SETCLIENTID] = {
		.op_func = nfsd4_setclientid,
		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
				| OP_MODIFIES_SOMETHING | OP_CACHEME,
				| OP_MODIFIES_SOMETHING | OP_CACHEME
				| OP_NONTRIVIAL_ERROR_ENCODE,
		.op_name = "OP_SETCLIENTID",
		.op_rsize_bop = nfsd4_setclientid_rsize,
	},
+3 −0
Original line number Diff line number Diff line
@@ -4461,6 +4461,9 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)

	if (op->opnum == OP_ILLEGAL)
		goto status;
	if (op->status && opdesc &&
			!(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE))
		goto status;
	BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
	       !nfsd4_enc_ops[op->opnum]);
	encoder = nfsd4_enc_ops[op->opnum];
+2 −0
Original line number Diff line number Diff line
@@ -778,6 +778,8 @@ enum nfsd4_op_flags {
	 * These are ops which clear current state id.
	 */
	OP_CLEAR_STATEID = 1 << 7,
	/* Most ops return only an error on failure; some may do more: */
	OP_NONTRIVIAL_ERROR_ENCODE = 1 << 8,
};

struct nfsd4_operation {