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

Potential Use After Free in tee_se_manager_unregister_reader() #1965

Closed
viennadd opened this issue Nov 23, 2017 · 4 comments
Closed

Potential Use After Free in tee_se_manager_unregister_reader() #1965

viennadd opened this issue Nov 23, 2017 · 4 comments

Comments

@viennadd
Copy link
Contributor

Hi all,

Our code scanner Pinpoint has reported a potential use after free in the following for loop, the freed proxy still used in the for loop (var) = ((var)->field.tqe_next)),

I can see there is a critical section locked by ctx->mutex, could there are other threads that are not using this mutex object but acquiring memory from process heap in the same time (after free, but before (var) = ((var)->field.tqe_next)))? the content pointed by proxy might be overwritten by other threads then.

TEE_Result tee_se_manager_unregister_reader(struct tee_se_reader *r)
{
struct tee_se_manager_ctx *ctx = &se_manager_ctx;
struct tee_se_reader_proxy *proxy;
mutex_lock(&ctx->mutex);
TAILQ_FOREACH(proxy, &ctx->reader_proxies, link)
{
if (proxy->reader == r)
TAILQ_REMOVE(&ctx->reader_proxies, proxy, link);
free(proxy);
}
ctx->reader_count--;
mutex_unlock(&ctx->mutex);
return TEE_SUCCESS;
}

#define	TAILQ_FOREACH(var, head, field)					\
	for ((var) = ((head)->tqh_first);				\
		(var);							\
		(var) = ((var)->field.tqe_next))

Regards,
Alex, Sourcebrella Inc.

@jenswi-linaro
Copy link
Contributor

Thanks, for reporting. Using TAILQ_FOREACH_SAFE() instead of TAILQ_FOREACH() here should take care of the problem.

Would you mind supplying a pull request?

Thanks,
Jens

@viennadd
Copy link
Contributor Author

viennadd commented Nov 23, 2017

@jenswi-linaro Sure I can do that, one more question though..

the implementation of TAILQ_FOREACH_SAFE,

#define	TAILQ_FOREACH_SAFE(var, head, field, next)			\
	for ((var) = ((head)->tqh_first);				\
		(var) != NULL && ((next) = TAILQ_NEXT(var, field), 1);	\
		(var) = (next))

if the race condition occurs, the TAILQ_NEXT inside TAILQ_FOREACH_SAFE might be still an issue ?

if proxy is freed in the loop body, the use of proxy variable in part 2 and part 3 are potential issues (memory block might be allocated by other threads and the content might not be the same) :

for (part 1; part 2; part 3)

I am thinking about an extra list to store the proxies will be freed in the future, and free those proxies after the TAILQ_FOREACH, it that OK or ?

Thank you,
Alex

@jenswi-linaro
Copy link
Contributor

next here is assigned in "part 2" before the element is freed.

Moving the elements to a different list first before freeing doesn't make any difference here.
On the other hand if you're more comfortable doing so I'm probably OK with that too (I say probably since I haven't seen the code yet :-))

@viennadd
Copy link
Contributor Author

@jenswi-linaro I thought that twice, indeed the execution sequence is "part 1" -> "part 2" -> loop body -> "part 3", I must got that wrong... I will supply a pull request in later today to replace TAILQ_FOREACH with TAILQ_FOREACH_SAFE,

Thanks,
Alex

viennadd added a commit to viennadd/optee_os that referenced this issue Nov 23, 2017
Signed-off-by: Alex CHEN <viennadd@gmail.com>
viennadd added a commit to viennadd/optee_os that referenced this issue Nov 23, 2017
Signed-off-by: viennadd <viennadd@gmail.com>
viennadd added a commit to viennadd/optee_os that referenced this issue Nov 23, 2017
Signed-off-by: Alex CHEN <viennadd@gmail.com>
viennadd added a commit to viennadd/optee_os that referenced this issue Nov 23, 2017
…or loop, it leaves potential risk of UAF crashing, replace `TAILQ_FOREACH()` with `TAILQ_FOREACH_SAFE()` to avoid second use of freed memory.

fixes: OP-TEE#1965

Signed-off-by: Alex CHEN <viennadd@gmail.com>
viennadd added a commit to viennadd/optee_os that referenced this issue Nov 23, 2017
…or loop, it leaves potential risk of UAF crashing, replace `TAILQ_FOREACH()` with `TAILQ_FOREACH_SAFE()` to avoid second use of freed memory.

fixes: OP-TEE#1965
Signed-off-by: Alex CHEN <viennadd@gmail.com>
viennadd added a commit to viennadd/optee_os that referenced this issue Nov 23, 2017
The freed `proxy` will be used again on the incremental part of the for loop, it leaves potential risk of UAF crashing, replace `TAILQ_FOREACH()` with `TAILQ_FOREACH_SAFE()` to avoid second use of freed memory.

fixes: OP-TEE#1965
Signed-off-by: Alex CHEN <viennadd@gmail.com>
viennadd added a commit to viennadd/optee_os that referenced this issue Nov 23, 2017
The freed `proxy` will be used again on the incremental part of the for
loop, it leaves potential risk of UAF crashing, replace `TAILQ_FOREACH()`
with `TAILQ_FOREACH_SAFE()` to avoid second use of freed memory.

fixes: OP-TEE#1965
Signed-off-by: Alex CHEN <viennadd@gmail.com>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
takuya-sakata pushed a commit to renesas-rcar/optee_os that referenced this issue May 28, 2018
The freed `proxy` will be used again on the incremental part of the for
loop, it leaves potential risk of UAF crashing, replace `TAILQ_FOREACH()`
with `TAILQ_FOREACH_SAFE()` to avoid second use of freed memory.

Fixes: OP-TEE/optee_os#1965
Signed-off-by: Alex CHEN <viennadd@gmail.com>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
[jf: add 'se:' to subject, don't capitalize "use", capitalize 'Fixes:']
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
jordanrh1 pushed a commit to ms-iot/optee_os that referenced this issue Oct 16, 2018
The freed `proxy` will be used again on the incremental part of the for
loop, it leaves potential risk of UAF crashing, replace `TAILQ_FOREACH()`
with `TAILQ_FOREACH_SAFE()` to avoid second use of freed memory.

Fixes: OP-TEE/optee_os#1965
Signed-off-by: Alex CHEN <viennadd@gmail.com>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
[jf: add 'se:' to subject, don't capitalize "use", capitalize 'Fixes:']
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants