Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: fix some other Null Pointer Dereference bugs #18072

Closed
wants to merge 4 commits into from

Conversation

mugitya03
Copy link

Dear Developers,

We found and fixed some other potential Null Pointer Dereference bugs similar to 18067. Here are the details:

1
Function mgmt_be_send_ds_delete_notification passes a null value as the third argument to function __send_notification at line 371.

return __send_notification(__be_client, path, patch, NOTIFY_OP_DS_PATCH);

Then, in function __send_notification, when both the 2nd parameter xpath and 3rd parameter tree are null, a null pointer dereference bug occurs at line 331.

	assert(op != NOTIFY_OP_NOTIFICATION || xpath || tree);
	debug_be_client("%s: sending %sYANG %snotification: %s", __func__,
			op == NOTIFY_OP_DS_DELETE    ? "delete "
			: op == NOTIFY_OP_DS_REPLACE ? "replace "
			: op == NOTIFY_OP_DS_PATCH   ? "patch "
						     : "",
			op == NOTIFY_OP_NOTIFICATION ? "" : "DS ", xpath ?: tree->schema->name);

To prevent this, we have added a check to ensure that xpath and tree are not both null simultaneously.

2
Function vrf_get can return NULL value at line 148.

	if (vrf && vrf_id != VRF_UNKNOWN
	    && vrf->vrf_id != VRF_UNKNOWN
	    && vrf->vrf_id != vrf_id) {
		zlog_debug("VRF_GET: avoid %s creation(%u), same name exists (%u)",
			   name, vrf_id, vrf->vrf_id);
		return NULL;
	}

Then in function lib_vrf_create, the return value from vrf_get is dereferenced at line 948 without null value check, causing a null pointer dereference bug. We noticed that other caller functions both check the return value before dereferencing it (link), thus we add the null value check in function lib_vrf_create.

3

Function pullwr_resize, when need is false and pullwr->valid is false, the pointer newbuf is set to NULL at line (130)[https://github.com/FRRouting/frr/blob/2ef76a33506f39d98038d5239f0620e2bbf33d8c/lib/pullwr.c#L130].

	} else if (!pullwr->valid) {
		/* resize down, buffer empty */
		newsize = 0;
		newbuf = NULL;
	}

Then the pointer newbuf is passed as the first argument to function memcpy, causing a null pointer dereference bug.

	niov = pullwr_iov(pullwr, iov);
	if (niov >= 1) {
		memcpy(newbuf, iov[0].iov_base, iov[0].iov_len);
		if (niov >= 2)
			memcpy(newbuf + iov[0].iov_len,
				iov[1].iov_base, iov[1].iov_len);
	}

Thus, we add a null value check before calling the function memcpy.

@@ -323,6 +323,7 @@ static int __send_notification(struct mgmt_be_client *client, const char *xpath,
int ret = 0;

assert(op != NOTIFY_OP_NOTIFICATION || xpath || tree);
assert(xpath || tree);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks odd at all. Why an assert is required here at all? I see it was introduced here opensourcerouting@c88b489, but maybe we can just fixup it correctly instead of adding a second assert?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this commit not have the analysis of what is being done and it's in the PR? This makes no sense and I would like the commit to have this analysis. 5 years from now people are going to be looking at the code and commit messages not the PR

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. How about returning an error code when both xpath and tree are null instead of using an assert?
And I'll resubmit a PR with an analysis in the commit information.


SET_FLAG(vrfp->status, VRF_CONFIGURED);

if (vrfp)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should return a warning/error instead then? Also, check vrf_handler_create().

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. But I'm not sure which error code should be returned.

@@ -944,7 +944,6 @@ static int lib_vrf_create(struct nb_cb_create_args *args)
return NB_OK;

vrfp = vrf_get(VRF_UNKNOWN, vrfname);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this commit at all.

@donaldsharp
Copy link
Member

Please put the analysis in the commits themselves until then this is a nack from me

Copy link
Contributor

@eqvinox eqvinox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pullwr change is superfluous.

@@ -137,7 +137,7 @@ static void pullwr_resize(struct pullwr *pullwr, size_t need)
}

niov = pullwr_iov(pullwr, iov);
if (niov >= 1) {
if (newbuf && niov >= 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This NULL check is superfluous. For newbuf to be NULL, pullwr->valid must be 0. When pullwr->valid is 0, pullwr_iov returns 0. Therefore niov will be 0 and the condition here is not met.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants