I believe the host (your CPU app) owns the context, and the context owns the resources. So when your app terminates, the context should be cleaned up and the resources it owns freed.
For a hint as to how this might be done, see the following link. Some OpenCL implementations expose an API to trigger “fast context cleanup” (outside of the normal ref counting cleanup), and program termination is mentioned as one use case for this. See:
I just wonder what happens with the data that I wrote to a cl_mem object when my program terminates? Will the memory block I reserved with clCreateBuffer of the specified size be now forever in my GPU RAM? Also the program that I build, will it be forever in my GPU RAM?
What happens if you malloc memory but never free it (or any other equivalents)?
The answer for CPU memory is no different than the answer for GPU memory. Interacting with either requires OS permission. The OS knows what memory you can access, and it knows when your process has ended. It therefore will release those resources when your program terminates.