8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 23:23:02 +01:00

Mac sandbox (#308)

* Get default tempdir from OS instead using /tmp
* Cleanup systemV IPC
* Turn off process sharing in case of working in sandbox
* Logging using native MacOS API
* Use standard log on MacOS when not in sandbox
This commit is contained in:
Alexander Peshkov 2021-01-29 10:30:50 +03:00 committed by GitHub
parent 44105b19ef
commit 6ec7a10aa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 168 additions and 1011 deletions

View File

@ -24,6 +24,11 @@ LIB_LINK_OPTIONS=$(LD_FLAGS) -dynamiclib -flat_namespace
LIB_LINK_SONAME:=-current_version @FIREBIRD_VERSION@ -compatibility_version @FIREBIRD_VERSION@ -seg1addr 0x30000000
LIB_LINK_MAPFILE=-Wl,-exported_symbols_list,$(1)
ADD_LIBS:=-lobjc -framework Foundation -framework Security
LINK_LIBS += $(ADD_LIBS)
STATICLINK_LIBS += $(ADD_LIBS)
SO_LINK_LIBS += $(ADD_LIBS)
PLATFORM_PATH=os/darwin
PLATFORM_FALLBACK=os/posix

View File

@ -94,6 +94,10 @@ $(OBJ)/%.o: $(SRC_ROOT)/%.c
$(CC) $(WCFLAGS) -c $(firstword $<) -o $@
@sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)
$(OBJ)/%.o: $(SRC_ROOT)/%.m
$(CC) $(WCFLAGS) -c $(firstword $<) -o $@
@sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)
$(OBJ)/%.o: $(OBJ)/%.cpp
$(CXX) $(WCXXFLAGS) -c $(firstword $<) -o $@
@sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)

View File

@ -1,8 +1,9 @@
# Helper functions
doObjects= $(patsubst %.y,%.o,$(patsubst %.epp,%.o,$(patsubst %.c,%.o,$(1:.cpp=.o))))
doObjects= $(patsubst %.m,%.o,$(patsubst %.y,%.o,$(patsubst %.epp,%.o,$(patsubst %.c,%.o,$(1:.cpp=.o)))))
makeObjects= $(addprefix $(OBJ)/$(patsubst ../%,%,$(1))/,$(call doObjects,$2))
dirFiles= $(notdir $(wildcard ../src/$(1)/*.cpp)) $(notdir $(wildcard ../src/$(1)/*.c)) \
$(notdir $(wildcard ../src/$(1)/*.epp)) $(notdir $(wildcard ../src/$(1)/*.y))
$(notdir $(wildcard ../src/$(1)/*.epp)) $(notdir $(wildcard ../src/$(1)/*.y)) \
$(notdir $(wildcard ../src/$(1)/*.m))
dirInPath= $(call makeObjects,$(1),$(call dirFiles,$(1)))
dirMaster= $(call dirInPath,$(1))

View File

@ -47,6 +47,7 @@
#include "../common/gdsassert.h"
#include "../common/os/path_utils.h"
#include "../common/classes/init.h"
#include "../common/os/mac_utils.h"
#include "../common/classes/TempFile.h"
@ -101,7 +102,11 @@ PathName TempFile::getTempPath()
}
if (path.empty())
{
path = DEFAULT_PATH;
const char* tmp = getTemporaryFolder();
if (tmp)
path = tmp;
else
path = DEFAULT_PATH;
}
fb_assert(path.length());

View File

@ -36,14 +36,6 @@
// Firebird platform-specific synchronization data structures
#if defined(DARWIN)
#define USE_FILELOCKS
#endif
#if defined(FREEBSD)
#define USE_SYS5SEMAPHORE
#endif
#ifdef LINUX
// This hack fixes CORE-2896 - embedded connections fail on linux.
// Looks like a lot of linux kernels are buggy when working with PRIO_INHERIT mutexes.
@ -52,67 +44,27 @@
#undef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL
#endif
#if defined(USE_FILELOCKS) && (!defined(USE_POSIX_SEMAPHORE))
#define USE_SYS5SEMAPHORE
#endif
#if defined(HAVE_MMAP) || defined(WIN_NT)
#define HAVE_OBJECT_MAP
#endif
#if defined(HAVE_MMAP) && (!defined(USE_SYS5SEMAPHORE))
#if defined(HAVE_MMAP)
#define USE_MUTEX_MAP
#endif
#ifndef USE_POSIX_SEMAPHORE
#ifndef USE_FILELOCKS
#ifndef USE_SYS5SEMAPHORE
#define USE_SHARED_FUTEX
#endif
#endif
#endif
#ifdef UNIX
#if defined(USE_SHARED_FUTEX)
#if defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP) && defined(HAVE_PTHREAD_MUTEX_CONSISTENT_NP)
#define USE_ROBUST_MUTEX
#endif // ROBUST mutex
#include "fb_pthread.h"
#endif // USE_SHARED_FUTEX
#ifndef USE_FILELOCKS
#define HAVE_SHARED_MUTEX_SECTION
#endif
namespace Firebird {
#ifdef USE_SYS5SEMAPHORE
struct Sys5Semaphore
{
int semSet; // index in shared memory table
unsigned short semNum; // number in semset
int getId();
};
#ifndef USE_FILELOCKS
struct mtx : public Sys5Semaphore
{
};
#endif
struct event_t : public Sys5Semaphore
{
SLONG event_count;
};
#endif // USE_SYS5SEMAPHORE
#ifdef USE_SHARED_FUTEX
struct mtx
{
pthread_mutex_t mtx_mutex[1];
@ -126,8 +78,6 @@ struct event_t
pthread_cond_t event_cond[1];
};
#endif // USE_SHARED_FUTEX
#endif // UNIX
@ -204,7 +154,7 @@ public:
#ifdef UNIX
#if defined(USE_FILELOCKS) || (!defined(HAVE_FLOCK))
#if !defined(HAVE_FLOCK)
#define USE_FCNTL
#endif
@ -297,17 +247,10 @@ public:
#ifdef HAVE_SHARED_MUTEX_SECTION
struct mtx* sh_mem_mutex;
#endif
#ifdef USE_FILELOCKS
Firebird::AutoPtr<FileLock> sh_mem_fileMutex;
Firebird::Mutex localMutex;
#endif
#ifdef UNIX
Firebird::AutoPtr<FileLock> initFile;
#endif
#ifdef USE_SYS5SEMAPHORE
Firebird::AutoPtr<FileLock> semFile;
#endif
ULONG sh_mem_length_mapped;
#ifdef WIN_NT
@ -319,12 +262,6 @@ public:
#endif
TEXT sh_mem_name[MAXPATHLEN];
MemoryHeader* volatile sh_mem_header;
#ifdef USE_SYS5SEMAPHORE
private:
int fileNum; // file number in shared table of shared files
bool getSem5(Sys5Semaphore* sem);
void freeSem5(Sys5Semaphore* sem);
#endif
private:
IpcObject* sh_mem_callback;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alexander Peshkoff
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2020 Alexander Peshkoff <peshkoff@mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*/
#import <Foundation/Foundation.h>
#import <Security/Security.h>
#import <os/log.h>
Boolean isSandboxed()
{
SecTaskRef task = SecTaskCreateFromSelf(nil);
CFTypeRef value = SecTaskCopyValueForEntitlement(task,
CFStringCreateWithCString(0, "com.apple.security.app-sandbox", kCFStringEncodingUTF8), nil);
return value != nil;
}
const char* getTemporaryFolder()
{
if (!isSandboxed())
return NULL;
NSString* tempDir = NSTemporaryDirectory();
if (tempDir == nil)
return NULL;
return tempDir.UTF8String;
}
void osLog(const char* msg)
{
os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_DEFAULT, "%{public}s", msg);
}

43
src/common/os/mac_utils.h Normal file
View File

@ -0,0 +1,43 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alexander Peshkoff
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2020 Alexander Peshkoff <peshkoff@mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*/
#ifndef COMMON_MAC_UTILS_H
#define COMMON_MAC_UTILS_H
#ifdef DARWIN
extern "C"
{
const char* getTemporaryFolder();
bool isSandboxed();
void osLog(const char*);
} // extern "C"
#else // DARWIN
inline const char* getTemporaryFolder() { return "/tmp"; }
inline bool isSandboxed() { return NULL; }
#endif // DARWIN
#endif // COMMON_MAC_UTILS_H

View File

@ -1803,7 +1803,8 @@ bool LockManager::create_process(CheckStatusWrapper* statusVector)
if (m_sharedMemory->eventInit(&process->prc_blocking) != FB_SUCCESS)
{
(Arg::StatusVector(statusVector) << Arg::Gds(isc_lockmanerr)).copyTo(statusVector);
(Arg::StatusVector(statusVector) << Arg::Gds(isc_lockmanerr) <<
Arg::Gds(isc_random) << Arg::Str("process blocking event failed to initialize properly")).copyTo(statusVector);
return false;
}
@ -1826,7 +1827,8 @@ bool LockManager::create_process(CheckStatusWrapper* statusVector)
}
catch (const Exception& ex)
{
(Arg::Gds(isc_lockmanerr) << Arg::StatusVector(ex)).copyTo(statusVector);
(Arg::Gds(isc_lockmanerr) << Arg::StatusVector(ex) <<
Arg::Gds(isc_random) << Arg::Str("blocking thread failed to start")).copyTo(statusVector);
return false;
}
@ -2302,7 +2304,8 @@ bool LockManager::init_owner_block(CheckStatusWrapper* statusVector, own* owner,
if (m_sharedMemory->eventInit(&owner->own_wakeup) != FB_SUCCESS)
{
(Arg::StatusVector(statusVector) << Arg::Gds(isc_lockmanerr)).copyTo(statusVector);
(Arg::StatusVector(statusVector) << Arg::Gds(isc_lockmanerr) <<
Arg::Gds(isc_random) << Arg::Str("owner wakeup event failed initialization")).copyTo(statusVector);
return false;
}

View File

@ -49,6 +49,7 @@
#include "../jrd/constants.h"
#include "../jrd/status.h"
#include "../common/os/os_utils.h"
#include "../common/os/mac_utils.h"
#include "../common/classes/BlrReader.h"
#include "../common/classes/alloc.h"
@ -1190,6 +1191,30 @@ void API_ROUTINE gds__log(const TEXT* text, ...)
now = time((time_t *)0);
#endif
TEXT hostName[MAXPATHLEN];
ISC_get_host(hostName, MAXPATHLEN);
#ifdef DARWIN
if (isSandboxed())
{
static Firebird::GlobalPtr<Firebird::Mutex> logMutex; // protects big static
static char buffer[10240]; // buffer for messages
Firebird::MutexLockGuard(logMutex, FB_FUNCTION);
fb_utils::snprintf(buffer, sizeof(buffer), "\n\n%s\t%.25s\t", hostName, ctime(&now));
unsigned hdrlen = strlen(buffer);
va_start(ptr, text);
VSNPRINTF(&buffer[hdrlen], sizeof(buffer) - hdrlen, text, ptr);
va_end(ptr);
buffer[sizeof(buffer) - 1] = '\0'; // be safe
osLog(buffer);
return;
}
#endif // DARWIN
Firebird::PathName name = fb_utils::getPrefix(Firebird::IConfigManager::DIR_LOG, LOGFILE);
#ifdef WIN_NT
@ -1216,8 +1241,7 @@ void API_ROUTINE gds__log(const TEXT* text, ...)
fseek(file, 0, SEEK_END);
#endif
TEXT buffer[MAXPATHLEN];
fprintf(file, "\n%s\t%.25s\t", ISC_get_host(buffer, MAXPATHLEN), ctime(&now));
fprintf(file, "\n%s\t%.25s\t", hostName, ctime(&now));
va_start(ptr, text);
vfprintf(file, text, ptr);
va_end(ptr);
@ -3785,7 +3809,11 @@ public:
}
if (!tempDir.length() || tempDir.length() >= MAXPATHLEN)
{
tempDir = WORKFILE;
const char* tmp = getTemporaryFolder();
if (tmp)
tempDir = tmp;
else
tempDir = WORKFILE;
}
tempDir.copyTo(fbTempDir, sizeof(fbTempDir));
@ -3795,8 +3823,11 @@ public:
Firebird::PathName lockPrefix;
if (!fb_utils::readenv(FB_LOCK_ENV, lockPrefix))
{
#ifndef WIN_NT
PathUtils::concatPath(lockPrefix, WORKFILE, LOCKDIR);
#if !defined(WIN_NT)
const char* tmp = getTemporaryFolder();
if (!tmp)
tmp = WORKFILE;
PathUtils::concatPath(lockPrefix, tmp, LOCKDIR);
#else
#ifdef WIN9X_SUPPORT
// shell32.dll version 5.0 and later supports SHGetFolderPath entry point