# Using w^x and troubleshooting (i.e. vscode)



## cmoerz (Aug 24, 2022)

I've finally enabled w^x for on 13.1-RELEASE-p1:

```
# sysctl -a |grep wx
kern.elf32.allow_wx: 0
kern.elf64.allow_wx: 0
```
For the usual suspects that struggle with this, I've used `elfctl` or `proccontrol` to circumvent the restriction.

Unfortunately, I've come across one program that persistently refuses to work: editors/vscode. I suppose this mixture of electron, javascript et al are a nightmare in terms of making it work with wx but I've not yet given up.

I've gotten to the point where I walked through the different wrapper scripts and found the actual ELF binary at /usr/local/share/code-oss/code-oss - blessed that one with "wxneeded".


```
elfctl -e +wxneeded /usr/local/share/code-oss/code-oss
```

However, it still doesn't work. I keep getting


```
Trace/BPT trap
```

Using `truss` on it, I believe I found the culprit still in the aforementioned binary, as if it ignores the wxneeded flag:

```
85598: 0.061100988 <new process>
84229: 0.061112792 fork()                        = 85598 (0x14e5e)
85598: 0.061195718 close(10)                     = 0 (0x0)
85598: 0.062726836 execve("/usr/local/share/code-oss/bin/../code-oss",[ "/usr/local/share/code-oss/bin/../code-oss", "/usr/local/share/code-oss/bin/../resources/app/out/cli.js", "--ms-enable-electron-run-as-node", "--user-data-dir", "/home/lclchristianm/.vscode-oss/" ],0x4c511a134b8) EJUSTRETURN
85598: 0.062878537 mmap(0x0,135168,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 11343831310336 (0xa5131092000)
85598: 0.063000378 mprotect(0x339fbf3f5000,4096,PROT_READ) = 0 (0x0)
85598: 0.063071456 issetugid()                   = 0 (0x0)

*snip*

85598: 0.966208943 <new thread 115441>
85598: 0.966283598 sigprocmask(SIG_SETMASK,{ SIGHUP|SIGINT|SIGQUIT|SIGILL|SIGTRAP|SIGABRT|SIGEMT|SIGFPE|SIGKILL|SIGBUS|SIGSEGV|SIGSYS|SIGPIPE|SIGALRM|SIGTERM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2 },{ }) = 0 (0x0)
85598: 0.966372940 sigaction(SIGUSR1,{ 0xa5132049a00 SA_SIGINFO ss_t },{ SIG_DFL SA_RESTART ss_t }) = 0 (0x0)
85598: 0.966453477 sigprocmask(SIG_SETMASK,{ },0x0) = 0 (0x0)
85598: 0.966533327 sigprocmask(SIG_UNBLOCK,{ SIGUSR1 },0x0) = 0 (0x0)
85598: 0.966617703 sigfastblock(0x1,0xa518a983838) = 0 (0x0)
85598: 0.990134929 madvise(0x189d001c0000,262144,MADV_FREE) = 0 (0x0)
85598: 0.990271557 mprotect(0x189d001c0000,12288,PROT_READ|PROT_WRITE) = 0 (0x0)
85598: 0.990355885 madvise(0x189d001c3000,4096,MADV_FREE) = 0 (0x0)
85598: 0.990433271 mprotect(0x189d001c4000,241664,PROT_READ|PROT_WRITE) = 0 (0x0)
85598: 0.990516606 madvise(0x189d001ff000,4096,MADV_FREE) = 0 (0x0)
85598: 0.990641502 mprotect(0x189d001c4000,241664,PROT_READ|PROT_WRITE|PROT_EXEC) ERR#13 'Permission denied'
85598: 0.990701163 SIGNAL 5 (SIGTRAP) code=TRAP_BRKPT
```

I understand it appears to get the permission denied upon attempting memory access in WX fashion.

I can make it start/work if I disable w^x globally, start the application and after it's initialized, I can re-enable w^x without any apparent negative impact. This kind of counters the security aspect of the whole undertaking however.

I should probably mention, that I've attempted this with the most recent vscode installed via `pkg`. I've also downgraded to an older version (1.64.2_2) to no avail.

I found a similar, unresolved issue in this thread: https://forums.freebsd.org/threads/rclone-not-working-with-w-x.80279/
Those binaries seem to be compiled via go apparently and don't lend themselves to blessing via `elfctl`.

I found similar ELF executables in /usr/local/share/code-oss and its subfolders, I.e. attempting to run `elfctl` gives

```
# elfctl /usr/local/share/code-oss/resources/app/node_modules.asar.unpacked/@parcel/watcher/build/Release/watcher.node
elfctl: NT_FREEBSD_FEATURE_CTL note not found
```
However, my truss listing doesn't lend itself to the conclusion that these ELF binaries may be the root cause.

Is it possible to troubleshoot this any further?
Does anyone of you have any suggestions for fixing this?
Is it possible that there are binaries that simply ignore flags set via `elfctl`?


----------



## _martin (Aug 24, 2022)

cmoerz said:


> Is it possible that there are binaries that simply ignore flags set via `elfctl`?


Yes, they do. I mentioned that in the post you shared above.

It's been over a year since I was looking at that code but I had to use my own linker script when I compiled my test binary.


----------



## cmoerz (Aug 25, 2022)

I missed that part on NT_FREEBSD_ABI_TAG on the first read through, thanks. 

I suppose I can attempt diving into the build procedure of vscode if I can manipulate it just enough to get the necessary headers straightened out. Probably a time consuming rabbit hole.

The `cc` call you mentioned only works when you're linking so won't work on existing executables, if I read this right?

Makes me wonder if there's a way to rebuild just the ELF header so it gets picked up properly by the kernel. elf() likely offers something that might do the trick but it's going to take a while to walk through that man page and understand enough of it to actually implement it.


----------



## _martin (Aug 25, 2022)

cmoerz said:


> The `cc` call you mentioned only works when you're linking so won't work on existing executables, if I read this right?


There are tools that can modify ELFs though I've never used them personally.



cmoerz said:


> Makes me wonder if there's a way to rebuild just the ELF header so it gets picked up properly by the kernel.


Well, editors/bvi ftw. Last time I did that other than playing around was on raspberry pi and some older raspian where stack was rwx on all running processes. It was a mistake in linker script that took way too long to fix in upstream.


----------

