7 Melakukan

Penulis SHA1 Pesan Tanggal
e76988ee77 shared: SandboxedProcessor: Enable fallback for non-landlock systems
Unless it's a processor that does not need fs access, this would
fail on systems without landlock, so we must fallback to
chroot() etc. again.
2022-06-09 10:04:48 +02:00
f29f997289 gui: ipc sandbox: Restrict sandbox further
Switch to QCoreApplication, since the ipc worker is not a GUI application.

We can also remove some vows this ways. Furthermore, disable connect() syscall
explicitly.
2022-06-09 10:04:48 +02:00
afa9d33f3d submodules: exile.h: Update 2022-06-09 10:04:48 +02:00
fc92b963d4 Release: v0.2 2022-06-07 00:01:35 +02:00
9acbd5dccf Add .gitignore 2022-06-07 00:00:54 +02:00
87ebc137d5 shared/gui: Add LOOQS_DISABLE_SANDBOX env to allow disabling sandboxing
Mainly for devs to check whether a problem is caused by sandboxing.
2022-06-06 23:23:07 +02:00
67189f34c6 gui: main: Make sandboxing work on kernels without landlock
Those are still around of course, so deal with that
2022-06-06 22:16:36 +02:00
9 mengubah file dengan 81 tambahan dan 12 penghapusan

11
.gitignore vendored Normal file
Melihat File

@ -0,0 +1,11 @@
.user
.o
*.user
*.o
*.a
moc_*.cpp
moc_*.h
Makefile
cli/looqs
gui/looqs-gui
qrc_*

Melihat File

@ -1,5 +1,10 @@
# looqs: Release notes
## 2022-06-07 - v0.2
CHANGES:
- Sandboxing: Add environment variable `LOOQS_DISABLE_SANDBOXING` to disable sandboxing. This is intended for troubleshooting
- Sandboxing: Fix issue where activation failed on kernels without landlock
## 2022-06-06 - v0.1
The first release comes with basic functionality. It's a start that can be considered useful to some degree.

Melihat File

@ -12,6 +12,8 @@ The architecture ensures that the parsing of documents and the preview generatio
Qt code is considered trusted in this model. While one may critize this, it was the only practical solution. looqs uses its serialization mechanism and other classes to communicate between the non-sandboxed GUI process and the sandboxed processes.
Set the enviornment variable `LOOQS_DISABLE_SANDBOX=1` to disable sandboxing. It's intended for troublehshooting.
## Database
The heart is sqlite, with the FTS5 extensions behind the full-text search. I definitly did not
want to run some heavy Java based solutions. I explored other options like Postgresql, I've discard them due to some limitations back then.

Melihat File

@ -30,7 +30,7 @@ There is no need to write the long form of filters. There are also booleans avai
## Current status
Last version: 2022-06-06, v0.1
Last version: 2022-06-07, v0.2
Please see [Changelog](CHANGELOG.md) for a human readable list of changes.

Melihat File

@ -23,25 +23,51 @@ void enableIpcSandbox()
qCritical() << "Failed to init policy for sandbox";
exit(EXIT_FAILURE);
}
policy->namespace_options = EXILE_UNSHARE_NETWORK | EXILE_UNSHARE_USER;
policy->namespace_options = EXILE_UNSHARE_USER | EXILE_UNSHARE_MOUNT | EXILE_UNSHARE_NETWORK;
policy->no_new_privs = 1;
policy->drop_caps = 1;
policy->vow_promises =
exile_vows_from_str("thread cpath wpath rpath unix stdio prot_exec proc shm fsnotify ioctl error");
policy->vow_promises = exile_vows_from_str("thread cpath rpath unix stdio proc error");
policy->mount_path_policies_to_chroot = 1;
QString ipcSocketPath = Common::ipcSocketPath();
QFileInfo info{ipcSocketPath};
QString ipcSocketPathDir = info.absolutePath();
std::string stdIpcSocketPath = ipcSocketPathDir.toStdString();
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ, "/");
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_ALL_WRITE, stdIpcSocketPath.c_str());
/* we only need the 'server' side of the 'unix' vow (for unix sockets)'. The process
* has no business to connect anywhere.
*
* Maybe this case should be handled by exile at some point, but for now deal with it here */
exile_append_syscall_policy(policy, EXILE_SYS(connect), EXILE_SYSCALL_DENY_RET_ERROR, NULL, 0);
/* ALLOW_EXEC is needed for fallback, not in landlock mode. It does not allow executing anything though here
* due to the vows */
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_EXEC, "/");
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_ALL_WRITE | EXILE_FS_ALLOW_EXEC,
stdIpcSocketPath.c_str());
int ret = exile_enable_policy(policy);
if(ret != 0)
{
qDebug() << "Failed to establish sandbox";
qDebug() << "Failed to establish sandbox" << Qt::endl;
exit(EXIT_FAILURE);
}
/* Arguments are irrelevant for sandbox test, just want to silence analyzer/compiler warnings */
ret = socket(AF_INET, SOCK_STREAM, 0);
if(ret != -1 || errno != EACCES)
{
qCritical() << "Sandbox sanity check failed" << Qt::endl;
exit(EXIT_FAILURE);
}
const struct sockaddr *addr = {};
ret = connect(3, addr, sizeof(*addr));
if(ret != -1 || errno != EACCES)
{
qCritical() << "Sandbox sanity check failed" << Qt::endl;
exit(EXIT_FAILURE);
}
exile_free_policy(policy);
}
@ -54,14 +80,21 @@ int main(int argc, char *argv[])
if(arg == "ipc")
{
Common::setupAppInfo();
enableIpcSandbox();
QApplication a(argc, argv);
if(Common::noSandboxModeRequested())
{
qInfo() << "Launching with no sandbox!" << Qt::endl;
}
else
{
enableIpcSandbox();
}
QCoreApplication a(argc, argv);
IpcServer *ipcserver = new IpcServer();
qDebug() << "Launching IPC Server";
if(!ipcserver->startSpawner(socketPath))
{
qCritical() << "Error failed to spawn";
qCritical() << "Error failed to spawn" << Qt::endl;
return 1;
}
qDebug() << "Launched IPC Server";

Melihat File

@ -157,6 +157,16 @@ QString Common::databasePath()
return env;
}
bool Common::noSandboxModeRequested()
{
QString env = getenv("LOOQS_DISABLE_SANDBOX");
if(env == "1")
{
return true;
}
return false;
}
QString Common::ipcSocketPath()
{
return "/tmp/.looqs/looqs-ipc-socket";

Melihat File

@ -15,6 +15,7 @@ QStringList excludedPaths();
QStringList mountPaths();
bool isTextFile(QFileInfo fileInfo);
bool isMountPath(QString path);
bool noSandboxModeRequested();
QString versionText();
} // namespace Common
#endif

Melihat File

@ -27,10 +27,15 @@ static QMap<QString, Processor *> processors{
void SandboxedProcessor::enableSandbox(QString readablePath)
{
if(Common::noSandboxModeRequested())
{
qInfo() << "Sandbox is disabled!" << Qt::endl;
return;
}
struct exile_policy *policy = exile_init_policy();
if(policy == NULL)
{
qCritical() << "Could not init exile";
qCritical() << "Could not init exile" << Qt::endl;
exit(EXIT_FAILURE);
}
policy->namespace_options = EXILE_UNSHARE_NETWORK | EXILE_UNSHARE_USER;
@ -38,6 +43,8 @@ void SandboxedProcessor::enableSandbox(QString readablePath)
std::string readablePathLocation;
if(!readablePath.isEmpty())
{
policy->namespace_options |= EXILE_UNSHARE_MOUNT;
policy->mount_path_policies_to_chroot = 1;
readablePathLocation = readablePath.toStdString();
if(exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ, readablePathLocation.c_str()) != 0)
{