Merge pull request #5 from sailfishos/jb54498_sandbox_as_requested

Sandbox apps when requested
pull/1/head
Tomi Leppänen 5 years ago committed by GitHub
commit b812c81e0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -26,6 +26,7 @@
#define SAILJAIL_KEY_ORGANIZATION_NAME "OrganizationName"
#define SAILJAIL_KEY_APPLICATION_NAME "ApplicationName"
#define SAILJAIL_KEY_PERMISSIONS "Permissions"
#define SAILJAIL_KEY_MODE "Mode"
#define NEMO_KEY_APPLICATION_TYPE "X-Nemo-Application-Type"
#define NEMO_KEY_SINGLE_INSTANCE "X-Nemo-Single-Instance"
#define MAEMO_KEY_FIXED_ARGS "X-Maemo-Fixed-Args"
@ -49,6 +50,10 @@
#define PERMISSIONMGR_SIGNAL_APP_CHANGED "ApplicationChanged"
#define PERMISSIONMGR_SIGNAL_APP_REMOVED "ApplicationRemoved"
/* Sailjaild errors */
#define CODE_INVALID_ARGS "org.freedesktop.DBus.Error.InvalidArgs"
#define ERROR_INVALID_APPNAME "Invalid application name: "
static DBusConnection *
sailjail_connect_bus(void)
{
@ -121,7 +126,7 @@ iter_at(DBusMessageIter *iter, int type)
static GHashTable *
sailjail_application_info(DBusConnection *con, const char *desktop)
{
GHashTable *info = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
GHashTable *info = NULL;
DBusError err = DBUS_ERROR_INIT;
DBusMessage *req = NULL;
DBusMessage *rsp = NULL;
@ -140,7 +145,10 @@ sailjail_application_info(DBusConnection *con, const char *desktop)
}
if (!(rsp = dbus_connection_send_with_reply_and_block(con, req, DBUS_TIMEOUT_INFINITE, &err))) {
error("method call failed: %s: %s", err.name, err.message);
if (strcmp(err.name, CODE_INVALID_ARGS) ||
strncmp(err.message, ERROR_INVALID_APPNAME, strlen(ERROR_INVALID_APPNAME))) {
error("method call failed: %s: %s", err.name, err.message);
}
goto EXIT;
}
@ -160,6 +168,8 @@ sailjail_application_info(DBusConnection *con, const char *desktop)
goto EXIT;
}
info = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
DBusMessageIter ArrayIter;
dbus_message_iter_recurse(&bodyIter, &ArrayIter);
while (!iter_at(&ArrayIter, DBUS_TYPE_INVALID)) {
@ -557,3 +567,29 @@ EXIT:
return allowed;
}
bool sailjail_sandbox(const char *desktop)
{
bool sandboxed = false;
DBusConnection *con = NULL;
GHashTable *info = NULL;
const char *mode;
if (!(con = sailjail_connect_bus()))
goto EXIT;
if (!(info = sailjail_application_info(con, desktop)))
goto EXIT;
if ((mode = appinfo_string(info, SAILJAIL_KEY_MODE)) && g_strcmp0(mode, "None")) {
// Mode is either "Normal" or "Compatibility"
sandboxed = true;
}
EXIT:
if (info)
g_hash_table_destroy(info);
sailjail_disconnect_bus(con);
return sandboxed;
}

@ -6,8 +6,12 @@
G_BEGIN_DECLS
#define SAILJAIL_PATH "/usr/bin/sailjail"
bool sailjail_verify_launch(const char *desktop, const char **argv);
bool sailjail_sandbox(const char *desktop);
G_END_DECLS
#endif // SAILJAIL_H_

@ -3,12 +3,13 @@ set(COMMON "${CMAKE_HOME_DIRECTORY}/src/common")
# Find dbus
include(FindPkgConfig)
pkg_check_modules(DBUS dbus-1 REQUIRED)
pkg_check_modules(GLIB glib-2.0 REQUIRED)
# Set sources
set(SRC invokelib.c invoker.c ${COMMON}/report.c search.c)
set(SRC invokelib.c invoker.c ${COMMON}/report.c search.c ${COMMON}/sailjail.c)
# Set include dirs
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${DBUS_INCLUDE_DIRS} ${COMMON})
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${DBUS_INCLUDE_DIRS} ${GLIB_INCLUDE_DIRS} ${COMMON})
# Set precompiler flags
add_definitions(-DPROG_NAME_INVOKER="invoker")
@ -16,7 +17,7 @@ add_definitions(-DPROG_NAME_INVOKER="invoker")
# Set target
add_executable(invoker ${SRC})
target_link_libraries(invoker ${DBUS_LDFLAGS})
target_link_libraries(invoker ${DBUS_LDFLAGS} ${GLIB_LDFLAGS})
# Add install rule
install(TARGETS invoker DESTINATION ${CMAKE_INSTALL_FULL_BINDIR})

@ -48,6 +48,7 @@
#include "protocol.h"
#include "invokelib.h"
#include "search.h"
#include "sailjail.h"
#define BOOSTER_SESSION "silica-session"
#define BOOSTER_GENERIC "generic"
@ -627,7 +628,7 @@ static unsigned int get_delay(char *delay_arg, char *param_name,
return delay;
}
static void notify_app_lauch(const char *desktop_file)
static void notify_app_launch(const char *desktop_file)
{
DBusConnection *connection;
DBusMessage *message;
@ -651,6 +652,14 @@ static void notify_app_lauch(const char *desktop_file)
}
}
static bool ask_for_sandboxing(const char *app)
{
char *path = strdup(app);
bool ret_val = sailjail_sandbox(basename(path));
free(path);
return ret_val;
}
static int wait_for_launched_process_to_exit(int socket_fd)
{
int exit_status = EXIT_FAILURE;
@ -790,7 +799,7 @@ static int invoke_remote(int socket_fd, const InvokeArgs *args)
invoker_send_end(socket_fd);
if (args->desktop_file)
notify_app_lauch(args->desktop_file);
notify_app_launch(args->desktop_file);
if (args->wait_term) {
exit_status = wait_for_launched_process_to_exit(socket_fd),
@ -1080,6 +1089,25 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
// If arguments don't define sailjail and sailjaild says the app must be sandboxed,
// we force sandboxing here
if (strcmp(args.prog_name, SAILJAIL_PATH) && ask_for_sandboxing(args.prog_name)) {
// We must use generic booster here as nothing else would work
// to run sailjail which is not compiled for launching via booster
args.app_type = BOOSTER_GENERIC;
// Prepend sailjail
char **old_argv = args.prog_argv;
args.prog_argc += 2;
args.prog_argv = (char **)calloc(args.prog_argc + 1, sizeof *args.prog_argv);
args.prog_argv[0] = SAILJAIL_PATH;
args.prog_argv[1] = "--";
for (int i = 2; i < args.prog_argc + 1; ++i)
args.prog_argv[i] = old_argv[i-2];
// Don't free old_argv because it's probably not dynamically allocated
free(args.prog_name);
args.prog_name = strdup(SAILJAIL_PATH);
}
// Send commands to the launcher daemon
info("Invoking execution: '%s'\n", args.prog_name);
int ret_val = invoke(&args);

@ -19,6 +19,7 @@
#include "appdata.h"
#include "protocol.h"
#include "sailjail.h"
#include <stdint.h>
#include <stdio.h>
#include <sys/types.h>
@ -100,6 +101,16 @@ void AppData::setArgv(const char ** newArgv)
}
}
void AppData::prependArgv(const char * arg)
{
char **oldArgv = m_argv;
m_argv = (char **)calloc(++m_argc + 1, sizeof *m_argv);
m_argv[0] = strdup(arg);
for (int i = 1; i < m_argc + 1; ++i)
m_argv[i] = oldArgv[i-1];
free(oldArgv);
}
const char ** AppData::argv() const
{
return (const char **)m_argv;
@ -237,6 +248,16 @@ void AppData::checkPrivileges()
And then, any file in
/usr/share/mapplauncherd/privileges.d/
*/
/* Sailjail does not use this system to gain privileged group.
* It is skipped to avoid unintended consequenses when launching
* other apps via sailjail.
*/
if (m_fileName == SAILJAIL_PATH) {
m_privileges.clear();
return;
}
static const char *BOOSTER_APP_PRIVILEGES_LIST = "/usr/share/mapplauncherd/privileges";
static const char *BOOSTER_APP_PRIVILEGES_DIR = "/usr/share/mapplauncherd/privileges.d";
m_privileges = getPrivileges(BOOSTER_APP_PRIVILEGES_LIST);

@ -72,6 +72,9 @@ public:
//! Set address of the argument vector
void setArgv(const char ** argv);
//! Prepend to argv
void prependArgv(const char *arg);
//! Return address of the argument vector
const char ** argv() const;

@ -57,6 +57,11 @@
#include "sailjail.h"
static std::string basename(const std::string &str)
{
return str.substr(str.find_last_of("/") + 1);
}
Booster::Booster() :
m_appData(new AppData),
m_connection(NULL),
@ -287,6 +292,12 @@ int Booster::run(SocketManager * socketManager)
if (boostedApplication() != "default") {
if (!sailjail_verify_launch(boostedApplication().c_str(), m_appData->argv()))
throw std::runtime_error("Booster: Binary doesn't have launch permissions\n");
} else if (m_appData->fileName() != SAILJAIL_PATH &&
sailjail_sandbox(basename(m_appData->fileName()).c_str())) {
Logger::logDebug("Sandboxing '%s'", m_appData->fileName());
// Prepend sailjail to arguments
m_appData->prependArgv(SAILJAIL_PATH);
m_appData->setFileName(SAILJAIL_PATH);
}
return launchProcess();
@ -701,7 +712,7 @@ void Booster::resetOomAdj()
std::string Booster::getFinalName(const std::string &name)
{
if (name == "/usr/bin/sailjail") {
if (name == SAILJAIL_PATH) {
// This doesn't implement sailjail's parsing logic but instead
// has some assumptions about the arguments:
// - If there is --, then the application is

Loading…
Cancel
Save