I still haven't been able to figure out why this isn't working.

I worked around it using a custom implementation of setjmp/longjmp from here.

https://github.com/GlinkieGamesInc/longjmp_win64

But, it'd be much nicer if the built-in function worked correctly. If anyone has any idea why this isn't working, I'd love to hear it.

On 2024-01-17 20:02, Brad Robinson via Tinycc-devel wrote:

A little more information on this from here [5]:

You also have the option of dynamically controlling the set of icall target addresses that are considered valid by CFG using the SetProcessValidCallTargets [1] from the Memory Management API. The same API can be used to specify whether pages are invalid or valid targets for CFG. The VirtualProtect [2] and VirtualAlloc [3] functions will by default treat a specified region of executable and committed pages as valid indirect call targets. It is possible to override this behavior, such as when implementing a Just-in-Time compiler, by specifying PAGE_TARGETS_INVALID when calling VirtualAlloc or PAGE_TARGETS_NO_UPDATE when calling VirtualProtect as detailed under Memory Protection Constants [4].

On 2024-01-17 19:25, Brad Robinson via Tinycc-devel wrote:

Hi All,

I'm trying to use setjmp/longjmp in code that needs to be compiled to in-memory.

On Windows 11 (and presumably Windows 10) when you have Control Flow Guard enabled, it crashes on calling longjmp.

If compiled to .exe it works fine. When Control Flow Guard is disabled (Control Panel ... -> ... Exploit Protection) is works fine.

I've read up a little on this and it seems like it's an exception being thrown in kernel, by a call to check the call target from the CRT. I've also read that the call target should be allowed if the target address' page has been marked executable - so I think this should work, but it's definitely not.

Sample program test.c below that fails in the longjmp call when running `tcc -run test.c`

Any ideas?

Brad

#include <stdio.h>
#include <setjmp.h>
jmp_buf jmpbuf;
void my_function()
{
longjmp(jmpbuf, 1);
}
int main()
{
if (setjmp(jmpbuf) == 0)
{
printf("A\n");
my_function();
printf("B\n");
}
printf("C\n");
return 0;
}

_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel



Links:
------
[1] https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-setprocessvalidcalltargets [2] https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualprotect [3] https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc [4] https://learn.microsoft.com/en-us/windows/desktop/Memory/memory-protection-constants [5] https://learn.microsoft.com/en-us/windows/win32/secbp/control-flow-guard
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to