Most of the time they're not bugs in the JIT - they're bugs in other parts of the software, basically your path to exploit is:
1. Find bug that gives you arbitrary read
2. and a bug that lets you write to some arbitrary location
3. Find bug the lets you jump to some location
4. Use [1] to find the location of the RWX region
5. use [2] to copy your exploit code into [4]
6. use [3] to jump to [4]
7. Profit
Often times a single use after free gives you 1, 2, and 3. Essentially you use the UaF to get multiple different objects pointing to the same place, but as different types. e.g You get a JS function allocated over the top of a typed array's backing store, then from JS you have an object that the runtime thinks is a typed array, but the pointer to its backing store is actually pointing to part of the RWX heap. Then all you have to do is copy your shell code into the corrupted typed array, and call the function object.
(This requires a GC related use after free, and most of the JS runtimes have gotten progressively more aggressive about validating the heap metadata, but fundamentally if there's a GC bug it's mostly likely just a matter of how much work will be needed to exploit it)
1. Find bug that gives you arbitrary read
2. and a bug that lets you write to some arbitrary location
3. Find bug the lets you jump to some location
4. Use [1] to find the location of the RWX region
5. use [2] to copy your exploit code into [4]
6. use [3] to jump to [4]
7. Profit
Often times a single use after free gives you 1, 2, and 3. Essentially you use the UaF to get multiple different objects pointing to the same place, but as different types. e.g You get a JS function allocated over the top of a typed array's backing store, then from JS you have an object that the runtime thinks is a typed array, but the pointer to its backing store is actually pointing to part of the RWX heap. Then all you have to do is copy your shell code into the corrupted typed array, and call the function object.
(This requires a GC related use after free, and most of the JS runtimes have gotten progressively more aggressive about validating the heap metadata, but fundamentally if there's a GC bug it's mostly likely just a matter of how much work will be needed to exploit it)