[llvm-dev] Compiling and Linking in Sandboxed app using LLVM binary

88 views
Skip to first unread message

Edmund Furse via llvm-dev

unread,
Mar 18, 2020, 10:35:48 AM3/18/20
to llvm...@lists.llvm.org
I am trying to build a sandboxed MacOSX app that can compile and link Objective C files.

I can succeed in doing this if sandboxing is turned off.
However, when sandboxing is turned on, the compiling works but linking fails with the error:
clang-9 xcrun: error: cannot be used within an App Sandbox.

I have downloaded the LLVM binary and created a Tools folder that contains the folders of the binary, namely bin, include, li, libexec, share.  

My example app uses NSTask to call clang from Tools/bin/clang.
If you call clang from usr/bin/clang then sandboxing will not allow compilation.

I do not understand why compiling works but linking fails.
Is it possible to make the linking work within a sandboxed application?

My code follows.

Error Message:
2020-03-18 12:31:46.517403+0000 NewClangM21[799:13738] Compilation was successfull.
2020-03-18 12:31:46.585428+0000 NewClangM21[799:13738] There was a linking error: clang version 9.0.0 (git://github.com/llvm/llvm-project.git 0399d5a9682b3cef71c653373e38890c63c4c365)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Users/edmundfurse/Documents/NewClang/NewClangM21/DerivedData/NewClangM21/Build/Products/Debug/NewClangM21.app/Contents/Resources/Tools/bin
 "/Applications/Xcode.app/Contents/Developer/usr/bin/ld" -demangle -lto_library /Users/edmundfurse/Documents/NewClang/NewClangM21/DerivedData/NewClangM21/Build/Products/Debug/NewClangM21.app/Contents/Resources/Tools/lib/libLTO.dylib -dynamic -arch x86_64 -bundle -macosx_version_min 10.14.0 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -o "/Users/edmundfurse/Library/Containers/com.uk.imitation.NewClangM21/Data/Library/Application Support/NewClangM21/ImitateScriptSystem/TemporaryFiles/TestMainTestMain" "/Users/edmundfurse/Library/Containers/com.uk.imitation.NewClangM21/Data/Library/Application Support/NewClangM21/ImitateScriptSystem/TemporaryFiles//TestMain.o" -framework Cocoa -framework Foundation -lSystem /Users/edmundfurse/Documents/NewClang/NewClangM21/DerivedData/NewClangM21/Build/Products/Debug/NewClangM21.app/Contents/Resources/Tools/lib/clang/9.0.0/lib/darwin/libclang_rt.osx.a "-F/Users/edmundfurse/Library/Containers/com.uk.imitation.NewClangM21/Data/Library/Application Support/NewClangM21/ImitateScriptSystem/TemporaryFiles/"
xcrun: error: cannot be used within an App Sandbox.
clang-9: error: linker command failed with exit code 1 (use -v to see invocation)
2020-03-18 12:31:46.586103+0000 NewClangM21[799:13738] CASE 1 LINK ERROR


//
//  AppDelegate.m
//  NewClangM21
//
//  Created by Edmund Furse on 06/03/2020.
//  Copyright © 2020 Imitation Ltd. All rights reserved.
//

#import "AppDelegate.h"
#import "NSFileManager+DirectoryLocations.h"

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    NSString* compileResult = [self compileScriptFile:@"TestMain"];
    if ([compileResult isEqualToString:@""])
    {
        NSLog(@"Compilation was successfull.");
    }
    BOOL linkResult = [self linkScriptFiles:@"TestMain"];
    if (linkResult)
    {
        NSLog(@"Linking was successfull.");
    }
}


- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
}

- (NSString*)compileScriptFile:(NSString*)theScriptName
{
    NSString *applicationSupportDirectoryPath = [[NSFileManager defaultManager] applicationSupportDirectory];
    NSString* temporaryFilesDirectoryName = concatenate(applicationSupportDirectoryPath, @"/ImitateScriptSystem/TemporaryFiles/");
    NSString* result = [self compileFile:theScriptName
                             inDirectory:temporaryFilesDirectoryName
                             toDirectory:temporaryFilesDirectoryName];
    if (![result isEqualToString:@""])
    {
        NSLog(@"There was an error compiling the file");
        return result;
    }
    return @"";
}

- (NSString*)compileFile:(NSString*)fileName
             inDirectory:(NSString*)fromDirectoryPath
             toDirectory:(NSString*)toDirectoryPath
// compiles the file using clang
{
    NSTask* compileTask = [[NSTask alloc] init];
    NSString* clangPath = [[NSBundle mainBundle] pathForResource:@"clang" ofType:@"" inDirectory:@"Tools/bin/"];
    [compileTask setLaunchPath:clangPath];
    [compileTask setArguments:[NSArray arrayWithObjects:@"-c",concatenate3(fromDirectoryPath, fileName, @".m"),
                               @"-isysroot",
                            @"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk",
                               @"-o",
                               concatenate3(toDirectoryPath, fileName, @".o"),
                               nil]];
    NSPipe* errorPipe = [[NSPipe alloc] init];
    NSFileHandle* errorReader = [errorPipe fileHandleForReading];
    [compileTask setStandardError:errorPipe];
    [compileTask launch];
    [compileTask waitUntilExit];
    NSString*  errorString = [[NSString alloc] initWithData:[errorReader readDataToEndOfFile]
                                                   encoding:NSUTF8StringEncoding];

    

    if ([errorString length] != 0)
    {
        NSLog(@"There was a Compilation error: %@", errorString);
        return errorString;
    }
    return @"";
}

- (BOOL)linkScriptFiles:(NSString*)theScriptName
{
    NSString *applicationSupportDirectoryPath = [[NSFileManager defaultManager] applicationSupportDirectory];
    NSString* temporaryFilesDirectoryName = concatenate(applicationSupportDirectoryPath, @"/ImitateScriptSystem/TemporaryFiles/");

    NSString* linkResult = [self linkTheScriptFilesToScriptName:theScriptName
                                                  intoDirectory:concatenate(temporaryFilesDirectoryName, theScriptName)];
    if (![linkResult isEqualToString:@""])
    {
        if (searchOfString(@"error", linkResult) != -1 || searchOfString(@"Error", linkResult) != -1 || searchOfString(@"ERROR", linkResult) != -1)
        {
            NSLog(@"CASE 1 LINK ERROR");
            return NO;
        }
        else if (searchOfString(@"warning", linkResult) != -1 || searchOfString(@"Warning", linkResult) != -1 || searchOfString(@"WARNING", linkResult) != -1)
        {
            NSLog(@"CASE 2 LINK WARNING");
            return YES;
        }
        else
        {
            NSLog(@"CASE 3 UNKNOWN LINK PROBLEM");
            return NO;
        }

        

    }
    return YES;
}

- (NSString*)linkTheScriptFilesToScriptName:(NSString*)theScriptName intoDirectory:(NSString*)dir
// links the file using clang
{
   NSString *applicationSupportDirectoryPath = [[NSFileManager defaultManager] applicationSupportDirectory];
    NSString* temporaryFilesDirectoryName = concatenate(applicationSupportDirectoryPath, @"/ImitateScriptSystem/TemporaryFiles/");
    NSTask* linkTask = [[NSTask alloc] init];
    NSString* clangPath = [[NSBundle mainBundle] pathForResource:@"clang" ofType:@"" inDirectory:@"Tools/bin/"];
     [linkTask setLaunchPath:clangPath];
     [linkTask setArguments:[NSArray arrayWithObjects:
                            concatenate4(temporaryFilesDirectoryName, @"/", theScriptName, @".o"),
                            @"-framework",
                            @"Cocoa",
                            @"-framework",
                            @"Foundation",
                            concatenate(@"-F", temporaryFilesDirectoryName),
                            @"-v",
                            @"-isysroot",
        @"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk",
                             @"-bundle",
                            @"-o",
                            concatenate(dir, theScriptName),
                            nil]];
    NSPipe* errorPipe = [[NSPipe alloc] init];
    NSFileHandle* errorReader = [errorPipe fileHandleForReading];
    [linkTask setStandardError:errorPipe];
    [linkTask launch];
    [linkTask waitUntilExit];
    NSString*  errorString = [[NSString alloc] initWithData:[errorReader readDataToEndOfFile]
                                                   encoding:NSUTF8StringEncoding];
    if ([errorString length] != 0)
    {
        NSLog(@"There was a linking error: %@", errorString);
        if ((searchOfString(@"error", errorString) != -1) ||
            (searchOfString(@"ERROR", errorString) != -1))
        {
            return errorString;
        }
        else
        {
            return @""; // ALLOW WARNINGS.
        }
        return errorString;
    }
    return @"";
}

NSString* concatenate(NSString* x, NSString* y)
{
    if (!x && !y) return @"";
    else if(!x) return y;
    else if (!y) return x;
    return [x stringByAppendingString:y];
}

NSString* concatenate3(NSString* x, NSString* y, NSString* z)
{
    if (!x) x = @"";
    if (!y) y = @"";
    if (!z) z = @"";
    return [[x stringByAppendingString:y] stringByAppendingString:z];
}

NSString* concatenate4(NSString* w, NSString* x, NSString* y, NSString* z)
{
    if (!x) x = @"";
    if (!y) y = @"";
    if (!z) z = @"";
    if (!w) w = @"";
    return [[[w stringByAppendingString:x] stringByAppendingString:y] stringByAppendingString:z];
}

int searchOfString(NSString* x, NSString* str)
//searches for x within str, if not found returns -1
//otherwise returns its location.
{
    if ((int)[str length] == 0) return -1;
    if ((int)[x length] > (int)[str length]) return -1;
    NSRange myRange = [str rangeOfString:x];
    if (myRange.location != NSNotFound)
        return (int)myRange.location;
    else return -1;
}

@end

Denis Antrushin via llvm-dev

unread,
Mar 18, 2020, 10:45:56 AM3/18/20
to llvm...@lists.llvm.org
On 18.03.2020 17:34, Edmund Furse via llvm-dev wrote:
> I am trying to build a sandboxed MacOSX app that can compile and link Objective C files.
>
> I can succeed in doing this if sandboxing is turned off.
> However, when sandboxing is turned on, the compiling works but linking fails with the error:
> clang-9 xcrun: error: cannot be used within an App Sandbox.
>
> I have downloaded the LLVM binary and created a Tools folder that contains the folders of the binary, namely bin, include, li, libexec, share.
>
> My example app uses NSTask to call clang from Tools/bin/clang.
> If you call clang from usr/bin/clang then sandboxing will not allow compilation.
>
> I do not understand why compiling works but linking fails.

Because it tries to pull something from

-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk

?

> Is it possible to make the linking work within a sandboxed application?
>
> My code follows.
>
> Error Message:

> *2020-03-18 12:31:46.517403+0000 NewClangM21[799:13738] Compilation was successfull.*
> *2020-03-18 12:31:46.585428+0000 NewClangM21[799:13738] There was a linking error: clang version 9.0.0 (git://github.com/llvm/llvm-project.git 0399d5a9682b3cef71c653373e38890c63c4c365)*
> *Target: x86_64-apple-darwin18.7.0*
> *Thread model: posix*
> *InstalledDir: /Users/edmundfurse/Documents/NewClang/NewClangM21/DerivedData/NewClangM21/Build/Products/Debug/NewClangM21.app/Contents/Resources/Tools/bin*
> * "/Applications/Xcode.app/Contents/Developer/usr/bin/ld" -demangle -lto_library /Users/edmundfurse/Documents/NewClang/NewClangM21/DerivedData/NewClangM21/Build/Products/Debug/NewClangM21.app/Contents/Resources/Tools/lib/libLTO.dylib -dynamic -arch x86_64 -bundle -macosx_version_min 10.14.0 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -o "/Users/edmundfurse/Library/Containers/com.uk.imitation.NewClangM21/Data/Library/Application Support/NewClangM21/ImitateScriptSystem/TemporaryFiles/TestMainTestMain" "/Users/edmundfurse/Library/Containers/com.uk.imitation.NewClangM21/Data/Library/Application Support/NewClangM21/ImitateScriptSystem/TemporaryFiles//TestMain.o" -framework Cocoa -framework Foundation -lSystem /Users/edmundfurse/Documents/NewClang/NewClangM21/DerivedData/NewClangM21/Build/Products/Debug/NewClangM21.app/Contents/Resources/Tools/lib/clang/9.0.0/lib/darwin/libclang_rt.osx.a
> "-F/Users/edmundfurse/Library/Containers/com.uk.imitation.NewClangM21/Data/Library/Application Support/NewClangM21/ImitateScriptSystem/TemporaryFiles/"*
> *xcrun: error: cannot be used within an App Sandbox.*
> *clang-9: error: linker command failed with exit code 1 (use -v to see invocation)*
> *2020-03-18 12:31:46.586103+0000 NewClangM21[799:13738] CASE 1 LINK ERROR*
> **
>
> ////
> ///  AppDelegate.m/
> ///  NewClangM21/
> ////
> ///  Created by Edmund Furse on 06/03/2020./
> ///  Copyright © 2020 Imitation Ltd. All rights reserved./
> ////
>
> #import "AppDelegate.h"
> #import "NSFileManager+DirectoryLocations.h"
>
> *@interface*AppDelegate()
>
> *@property*(*weak*) *IBOutlet*NSWindow*window;
> *@end*
>
> *@implementation*AppDelegate
>
> - (*void*)applicationDidFinishLaunching:(NSNotification *)aNotification {
> /// Insert code here to initialize your application/
> NSString* compileResult = [*self* compileScriptFile:@"TestMain"];
> *if* ([compileResult isEqualToString:@""])


>     {
> NSLog(@"Compilation was successfull.");
>     }

> *BOOL* linkResult = [*self* linkScriptFiles:@"TestMain"];
> *if* (linkResult)


>     {
> NSLog(@"Linking was successfull.");
>     }
> }
>
>

> - (*void*)applicationWillTerminate:(NSNotification *)aNotification {
> /// Insert code here to tear down your application/


> }
>
> - (NSString*)compileScriptFile:(NSString*)theScriptName
> {
> NSString *applicationSupportDirectoryPath = [[NSFileManager defaultManager] applicationSupportDirectory];
> NSString* temporaryFilesDirectoryName = concatenate(applicationSupportDirectoryPath, @"/ImitateScriptSystem/TemporaryFiles/");

> NSString* result = [*self* compileFile:theScriptName
> inDirectory:temporaryFilesDirectoryName
> toDirectory:temporaryFilesDirectoryName];
> *if* (![result isEqualToString:@""])


>     {
> NSLog(@"There was an error compiling the file");

> *return* result;
>     }
> *return* @"";


> }
>
> - (NSString*)compileFile:(NSString*)fileName
>              inDirectory:(NSString*)fromDirectoryPath
>              toDirectory:(NSString*)toDirectoryPath

> /// compiles the file using clang/


> {
> NSTask* compileTask = [[NSTask alloc] init];

> NSString* clangPath = [[NSBundlemainBundle] pathForResource:@"clang"ofType:@""inDirectory:@"Tools/bin/"];


>     [compileTask setLaunchPath:clangPath];
>     [compileTask setArguments:[NSArray arrayWithObjects:@"-c",concatenate3(fromDirectoryPath, fileName, @".m"),
> @"-isysroot",
> @"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk",
> @"-o",
> concatenate3(toDirectoryPath, fileName, @".o"),

> *nil*]];


> NSPipe* errorPipe = [[NSPipe alloc] init];
> NSFileHandle* errorReader = [errorPipe fileHandleForReading];
>     [compileTask setStandardError:errorPipe];
>     [compileTask launch];
>     [compileTask waitUntilExit];
> NSString*  errorString = [[NSString alloc] initWithData:[errorReader readDataToEndOfFile]
> encoding:NSUTF8StringEncoding];
>
>

> *if* ([errorString length] != 0)


>     {
> NSLog(@"There was a Compilation error: %@", errorString);

> *return* errorString;
>     }
> *return* @"";
> }
>
> - (*BOOL*)linkScriptFiles:(NSString*)theScriptName


> {
> NSString *applicationSupportDirectoryPath = [[NSFileManager defaultManager] applicationSupportDirectory];
> NSString* temporaryFilesDirectoryName = concatenate(applicationSupportDirectoryPath, @"/ImitateScriptSystem/TemporaryFiles/");
>

> NSString* linkResult = [*self* linkTheScriptFilesToScriptName:theScriptName
> intoDirectory:concatenate(temporaryFilesDirectoryName, theScriptName)];
> *if* (![linkResult isEqualToString:@""])
>     {
> *if* (searchOfString(@"error", linkResult) != -1 || searchOfString(@"Error", linkResult) != -1 || searchOfString(@"ERROR", linkResult) != -1)


>         {
> NSLog(@"CASE 1 LINK ERROR");

> *return* *NO*;
>         }
> *else* *if* (searchOfString(@"warning", linkResult) != -1 || searchOfString(@"Warning", linkResult) != -1 || searchOfString(@"WARNING", linkResult) != -1)


>         {
> NSLog(@"CASE 2 LINK WARNING");

> *return* *YES*;
>         }
> *else*


>         {
> NSLog(@"CASE 3 UNKNOWN LINK PROBLEM");

> *return* *NO*;
>         }
>
>
>     }
> *return**YES*;


> }
>
> - (NSString*)linkTheScriptFilesToScriptName:(NSString*)theScriptName intoDirectory:(NSString*)dir

> /// links the file using clang/


> {
> NSString *applicationSupportDirectoryPath = [[NSFileManager defaultManager] applicationSupportDirectory];
> NSString* temporaryFilesDirectoryName = concatenate(applicationSupportDirectoryPath, @"/ImitateScriptSystem/TemporaryFiles/");
> NSTask* linkTask = [[NSTask alloc] init];

> NSString* clangPath = [[NSBundlemainBundle] pathForResource:@"clang"ofType:@""inDirectory:@"Tools/bin/"];


>      [linkTask setLaunchPath:clangPath];
>      [linkTask setArguments:[NSArrayarrayWithObjects:
> concatenate4(temporaryFilesDirectoryName, @"/", theScriptName, @".o"),
> @"-framework",
> @"Cocoa",
> @"-framework",
> @"Foundation",
> concatenate(@"-F", temporaryFilesDirectoryName),
> @"-v",
> @"-isysroot",
> @"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk",
> @"-bundle",
> @"-o",
> concatenate(dir, theScriptName),

> *nil*]];


> NSPipe* errorPipe = [[NSPipe alloc] init];
> NSFileHandle* errorReader = [errorPipe fileHandleForReading];
>     [linkTask setStandardError:errorPipe];
>     [linkTask launch];
>     [linkTask waitUntilExit];
> NSString*  errorString = [[NSString alloc] initWithData:[errorReader readDataToEndOfFile]
> encoding:NSUTF8StringEncoding];

> *if* ([errorString length] != 0)


>     {
> NSLog(@"There was a linking error: %@", errorString);

> *if* ((searchOfString(@"error", errorString) != -1) ||


>             (searchOfString(@"ERROR", errorString) != -1))
>         {

> *return* errorString;
>         }
> *else*
>         {
> *return*@""; /// ALLOW WARNINGS./
>         }
> *return* errorString;
>     }
> *return* @"";


> }
>
> NSString* concatenate(NSString* x, NSString* y)
> {

> *if* (!x && !y) *return* @"";
> *else* *if*(!x) *return* y;
> *else* *if* (!y) *return* x;
> *return*[x stringByAppendingString:y];


> }
>
> NSString* concatenate3(NSString* x, NSString* y, NSString* z)
> {

> *if* (!x) x = @"";
> *if* (!y) y = @"";
> *if* (!z) z = @"";
> *return*[[x stringByAppendingString:y] stringByAppendingString:z];


> }
>
> NSString* concatenate4(NSString* w, NSString* x, NSString* y, NSString* z)
> {

> *if* (!x) x = @"";
> *if* (!y) y = @"";
> *if* (!z) z = @"";
> *if* (!w) w = @"";
> *return*[[[w stringByAppendingString:x] stringByAppendingString:y] stringByAppendingString:z];
> }
>
> *int* searchOfString(NSString* x, NSString* str)
> ///searches for x within str, if not found returns -1/
> ///otherwise returns its location./
> {
> *if* ((*int*)[str length] == 0) *return* -1;
> *if* ((*int*)[x length] > (*int*)[str length]) *return* -1;


> NSRange myRange = [str rangeOfString:x];

> *if* (myRange.location != NSNotFound)
> *return* (*int*)myRange.location;
> *else**return*-1;
> }
>
> *@end*
> *
> *
>
> _______________________________________________
> LLVM Developers mailing list
> llvm...@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Reply all
Reply to author
Forward
0 new messages