2

I'm trying to run my application as root with Xcode on macOS, but I keep getting this bizarre error..

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

It's literally just a hello world. All I've added was a printf to the default Obj-C application, tried running it as root, aaaand it ends up on a ud2 instruction somehow. I've tried running Xcode with sudo, editing the scheme, the combination of the two, and nothing works. It seems like just the thought of root shudders causes Xcode to insert some undefined instruction and crash.

edit: I'm on macOS Catalina 10.15.3 and Xcode 11.4, which I just downloaded yesterday, and this is the code I'm trying to run:

#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[]) {
    printf("Hello world\n");
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
    }
    return NSApplicationMain(argc, argv);
}

'My code' doesn't actually do anything. Removing the printf still causes the ud2 instruction crash, so the actual boilerplate developed by Apple doesn't work when run as root..

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • I suppose you already checked this page: https://stackoverflow.com/questions/1033026/debugging-in-xcode-as-root and that you need to authenticate and that sometimes you need to quit and restart Xcode, right? If so, it would help if you said which Xcode and macOS versions you are using. – jvarela Mar 28 '20 at 09:37
  • It would also help if you posted the exact code you are using. – jvarela Mar 28 '20 at 09:40
  • Done and done. I've edited my question. I already found that answer, it's actually why I modified the scheme in the first place. – somethingunderscore Mar 28 '20 at 09:46
  • Ok, I will try to reproduce it. Perhaps we’ll need to submit a bug report to Apple. – jvarela Mar 28 '20 at 09:49
  • Note that there is no reason to debug your programs as root. Please don't do that. – fuz Mar 28 '20 at 11:37
  • I'm trying to call mprotect on the text segment to make it writable. If you know how to do that without "Permission denied", please let me know. – somethingunderscore Mar 28 '20 at 11:53
  • @jvarela and @ OP: clang/LLVM will emit a `ud2` in some code paths that have compile-time visible Undefined Behaviour (when compiling C and C++ at least). e.g. falling off the end of a non-`void` function. Which source line does the `ud2` correspond to? – Peter Cordes Mar 28 '20 at 15:41
  • 1
    @PeterCordes I have no idea no idea how to find that. It says "libsystem_secinit.dylib`_libsecinit_appsandbox.cold.5:" at the top, and it doesn't matter if I insert any code or not. Does that help? – somethingunderscore Mar 28 '20 at 15:55
  • 1
    Also, Apple's system libraries/frameworks also use `ud2` as a sort of assert/abort. I'm guessing you're running afoul of System Integrity Protection / the hardened runtime. Or, I guess, the sandbox. ;) – Ken Thomases Mar 28 '20 at 15:55
  • 1
    Backtrace up the callstack to find where that was called from. The library function names might shed some light, and hopefully you can see which source line of your code it was ultimately called from. Since the `ud2` was in a library, not in machine code that was directly emitted by the compiler for your source, @KenThomases's comment is probably on the money: illegal instruction as an assert/abort in response to passing args it didn't like to some function. I don't use a Mac or Objective C so I can't help any more than that. (I'm just here for the assembly tag.) – Peter Cordes Mar 28 '20 at 15:58
  • I would expect something to be logged to console. Given that it looks sandbox related, the obvious thing to try is to disable the sandbox for your app (in the target settings). Oh, and the hardened runtime is likely why `mprotect()` is failing. You can either disable that, too, or add the entitlement to allow for executable memory. – Ken Thomases Mar 28 '20 at 16:03
  • @KenThomases I have no idea how to see the callstack in Xcode, but it _looks_ like only `_dyld_start` was called before, since that was also the one to call `_libsecinit_appsandbox.cold.5`. With regards to my code, it is literally just Apple boilerplate. The fact that I add a single `printf` call doesn't seem to make a difference. – somethingunderscore Mar 28 '20 at 16:33
  • Also, with regards to `mprotect`, I _think_ I got it working with entitlements, buuuuut now it crashes when run as root, so... yea. – somethingunderscore Mar 28 '20 at 16:34
  • Well, I think you need then to reformulate your question, because what you are asking now is different from what you asked before. I tried to run different Apple boilerplate code even as root and all of them work perfectly. It seems as though you are trying to mix and match code that is incompatible. For example, to run a Cocoa application as root is a really bad idea. What you need to do is to separate your UI code (Cocoa) from what needs to be run as root. The latter should be build as CLI app, not as a Cocoa app. Finally, did you know that mprotect only works with mmap'ed memory? – jvarela Mar 29 '20 at 12:51
  • My question is still how to run an Xcode app as root. Nothing works, still. I just tried opening Xcode, clicking "New Project", Obj-C/Swift doesn't matter. If I go under Product > Scheme > Edit Scheme and switch it to "root" under "Debug Process As", it _always_ crashed on a `ud2` instruction. It doesn't matter if I touch the code. The fact that it works for you surprises me. Did we do the same thing? No, I was under the impression to make pages in the text segment writable was to call `mprotect` on the address rounded down to the nearest page size. It just fails as "Permission denied". – somethingunderscore Mar 29 '20 at 15:17
  • Try to restart your computer and see if that helps. Perhaps you are dealing with corrupted memory. If that fails, I would reinstall Xcode. Finally, if neither of those solutions work, just post on GitHub a project that crashes in your machine and then let us know about that, so that we can try to reproduce your bug. If that also fails, I would post a bug report with the Feedback Assistant, attaching all the crash reports you are getting. – jvarela Mar 29 '20 at 16:27
  • @jvarela Okay, so I got out my Air, downloaded Xcode, made a new App with Obj-C and XIB, edited the scheme to have it run as root and the same thing happened. Restarting doesn't help, neither does reinstalling Xcode. I uploaded a project here https://github.com/something-underscore/dsfsdkfsdf as usual, it's literally just boilerplate. No changes, besides editing the scheme. I'm guessing I'm doing that wrong? – somethingunderscore Mar 29 '20 at 20:17

1 Answers1

5

I tried your project I downloaded from the GitHub link you provided and I can tell you I'm able to reproduce the bug you reported. Apparently, there is some incompatibility between libsystem_secinit initialization code and when you turn on the entitlement App Sandbox to YES. If you turn it off, the crash goes away.

That reminds me of a bug described by Eskimo, who is a really helpful Apple engineer. He described also some incompatibilities between entitlements and libsystem_secinit.

I would definitely recommend that you file a bug against this incompatibility with Feedback Assistant. At least, Apple's boiler plate code should work without crashing.

jvarela
  • 3,744
  • 1
  • 22
  • 43