Merge pull request #2590 from zonque/bus-endpoint-removal

Remove kdbus custom endpoint support
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2016-02-11 21:58:46 -05:00
commit b266400c92
21 changed files with 3 additions and 466 deletions

View file

@ -1136,8 +1136,6 @@ libcore_la_SOURCES = \
src/core/socket.h \
src/core/busname.c \
src/core/busname.h \
src/core/bus-endpoint.c \
src/core/bus-endpoint.h \
src/core/bus-policy.c \
src/core/bus-policy.h \
src/core/target.c \

View file

@ -272,42 +272,6 @@
</listitem>
</varlistentry>
<varlistentry>
<term><varname>BusPolicy=</varname></term>
<listitem><para>If specified, a custom kdbus
endpoint will be created and installed as the default bus node
for the service. Such a custom endpoint can hold an own set of
policy rules that are enforced on top of the bus-wide ones.
The custom endpoint is named after the service it was created
for, and its node will be bind-mounted over the default bus
node location, so the service can only access the bus through
its own endpoint. Note that custom bus endpoints default to a
"deny all" policy. Hence, if at least one
<varname>BusPolicy=</varname> directive is given, you have to
make sure to add explicit rules for everything the service
should be able to do.</para>
<para>The value of this directive is comprised
of two parts; the bus name, and a verb to
specify to granted access, which is one of
<option>see</option>,
<option>talk</option>, or
<option>own</option>.
<option>talk</option> implies
<option>see</option>, and <option>own</option>
implies both <option>talk</option> and
<option>see</option>.
If multiple access levels are specified for the
same bus name, the most powerful one takes
effect.
</para>
<para>Examples:</para>
<programlisting>BusPolicy=org.freedesktop.systemd1 talk</programlisting>
<programlisting>BusPolicy=org.foo.bar see</programlisting>
<para>This option is only available on kdbus enabled systems.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>ExecStart=</varname></term>
<listitem><para>Commands with their arguments that are

View file

@ -147,9 +147,6 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
case EXIT_MAKE_STARTER:
return "MAKE_STARTER";
case EXIT_BUS_ENDPOINT:
return "BUS_ENDPOINT";
case EXIT_SMACK_PROCESS_LABEL:
return "SMACK_PROCESS_LABEL";
}

View file

@ -77,7 +77,6 @@ typedef enum ExitStatus {
EXIT_RUNTIME_DIRECTORY,
EXIT_MAKE_STARTER,
EXIT_CHOWN,
EXIT_BUS_ENDPOINT,
EXIT_SMACK_PROCESS_LABEL,
} ExitStatus;

View file

@ -1,135 +0,0 @@
/***
This file is part of systemd.
Copyright 2014 Daniel Mack
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <stdlib.h>
#include "alloc-util.h"
#include "bus-endpoint.h"
#include "bus-kernel.h"
#include "bus-policy.h"
#include "kdbus.h"
int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
struct kdbus_cmd *update;
struct kdbus_item *n;
BusEndpointPolicy *po;
Iterator i;
size_t size;
int r;
size = ALIGN8(offsetof(struct kdbus_cmd, items));
HASHMAP_FOREACH(po, ep->policy_hash, i) {
size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
}
update = alloca0_align(size, 8);
update->size = size;
n = update->items;
HASHMAP_FOREACH(po, ep->policy_hash, i) {
n->type = KDBUS_ITEM_NAME;
n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
strcpy(n->str, po->name);
n = KDBUS_ITEM_NEXT(n);
n->type = KDBUS_ITEM_POLICY_ACCESS;
n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
n->policy_access.access = bus_kernel_translate_access(po->access);
n->policy_access.id = uid;
n = KDBUS_ITEM_NEXT(n);
}
r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
if (r < 0)
return -errno;
return 0;
}
int bus_endpoint_new(BusEndpoint **ep) {
assert(ep);
*ep = new0(BusEndpoint, 1);
if (!*ep)
return -ENOMEM;
return 0;
}
int bus_endpoint_add_policy(BusEndpoint *ep, const char *name, BusPolicyAccess access) {
_cleanup_free_ BusEndpointPolicy *po = NULL;
_cleanup_free_ char *key = NULL;
int r;
assert(ep);
assert(name);
assert(access > _BUS_POLICY_ACCESS_INVALID && access < _BUS_POLICY_ACCESS_MAX);
/* check if we already have this name in the policy list. If we do, see if the new access level
* is higher than the exising one, and upgrade the entry in that case. Otherwise, do nothing.
*/
if (ep->policy_hash) {
po = hashmap_get(ep->policy_hash, name);
if (po) {
if (po->access < access)
po->access = access;
return 0;
}
} else {
ep->policy_hash = hashmap_new(&string_hash_ops);
if (!ep->policy_hash)
return -ENOMEM;
}
po = new0(BusEndpointPolicy, 1);
if (!po)
return -ENOMEM;
key = strdup(name);
if (!key)
return -ENOMEM;
po->name = key;
po->access = access;
r = hashmap_put(ep->policy_hash, key, po);
if (r < 0)
return r;
po = NULL;
key = NULL;
return 0;
}
void bus_endpoint_free(BusEndpoint *endpoint) {
if (!endpoint)
return;
hashmap_free_free_free(endpoint->policy_hash);
free(endpoint);
}

View file

@ -1,42 +0,0 @@
#pragma once
/***
This file is part of systemd.
Copyright 2014 Daniel Mack
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
typedef struct BusEndpoint BusEndpoint;
typedef struct BusEndpointPolicy BusEndpointPolicy;
#include "bus-policy.h"
#include "hashmap.h"
struct BusEndpointPolicy {
char *name;
BusPolicyAccess access;
};
struct BusEndpoint {
Hashmap *policy_hash;
};
int bus_endpoint_new(BusEndpoint **ep);
void bus_endpoint_free(BusEndpoint *endpoint);
int bus_endpoint_add_policy(BusEndpoint *ep, const char *name, BusPolicyAccess access);
int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep);

View file

@ -23,6 +23,7 @@ typedef struct BusName BusName;
typedef struct BusNamePolicy BusNamePolicy;
#include "unit.h"
#include "bus-policy.h"
typedef enum BusNameResult {
BUSNAME_SUCCESS,

View file

@ -57,7 +57,6 @@
#endif
#include "async.h"
#include "barrier.h"
#include "bus-endpoint.h"
#include "cap-list.h"
#include "capability-util.h"
#include "def.h"
@ -1387,9 +1386,6 @@ static bool exec_needs_mount_namespace(
if (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir))
return true;
if (params->bus_endpoint_path)
return true;
if (context->private_devices ||
context->protect_system != PROTECT_SYSTEM_NO ||
context->protect_home != PROTECT_HOME_NO)
@ -1423,9 +1419,6 @@ static int close_remaining_fds(
n_dont_close += n_fds;
}
if (params->bus_endpoint_fd >= 0)
dont_close[n_dont_close++] = params->bus_endpoint_fd;
if (runtime) {
if (runtime->netns_storage_socket[0] >= 0)
dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
@ -1655,16 +1648,6 @@ static int exec_child(
}
}
if (params->bus_endpoint_fd >= 0 && context->bus_endpoint) {
uid_t ep_uid = (uid == UID_INVALID) ? 0 : uid;
r = bus_kernel_set_endpoint_policy(params->bus_endpoint_fd, ep_uid, context->bus_endpoint);
if (r < 0) {
*exit_status = EXIT_BUS_ENDPOINT;
return r;
}
}
/* If delegation is enabled we'll pass ownership of the cgroup
* (but only in systemd's own controller hierarchy!) to the
* user of the new process. */
@ -1787,7 +1770,6 @@ static int exec_child(
context->inaccessible_dirs,
tmp,
var,
params->bus_endpoint_path,
context->private_devices,
context->protect_home,
context->protect_system,
@ -2214,9 +2196,6 @@ void exec_context_done(ExecContext *c) {
c->address_families = set_free(c->address_families);
c->runtime_directory = strv_free(c->runtime_directory);
bus_endpoint_free(c->bus_endpoint);
c->bus_endpoint = NULL;
}
int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {

View file

@ -30,7 +30,6 @@ typedef struct ExecParameters ExecParameters;
#include <stdio.h>
#include <sys/capability.h>
#include "bus-endpoint.h"
#include "fdset.h"
#include "list.h"
#include "missing.h"
@ -201,9 +200,6 @@ struct ExecContext {
bool ioprio_set:1;
bool cpu_sched_set:1;
bool no_new_privileges_set:1;
/* custom dbus enpoint */
BusEndpoint *bus_endpoint;
};
#include "cgroup-util.h"
@ -234,9 +230,6 @@ struct ExecParameters {
int *idle_pipe;
char *bus_endpoint_path;
int bus_endpoint_fd;
int stdin_fd;
int stdout_fd;
int stderr_fd;

View file

@ -240,7 +240,7 @@ Service.BusName, config_parse_bus_name, 0,
Service.FileDescriptorStoreMax, config_parse_unsigned, 0, offsetof(Service, n_fd_store_max)
Service.NotifyAccess, config_parse_notify_access, 0, offsetof(Service, notify_access)
Service.Sockets, config_parse_service_sockets, 0, 0
Service.BusPolicy, config_parse_bus_endpoint_policy, 0, offsetof(Service, exec_context)
Service.BusPolicy, config_parse_warn_compat, DISABLED_LEGACY, 0
Service.USBFunctionDescriptors, config_parse_path, 0, offsetof(Service, usb_function_descriptors)
Service.USBFunctionStrings, config_parse_path, 0, offsetof(Service, usb_function_strings)
EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl

View file

@ -1902,59 +1902,6 @@ int config_parse_bus_policy(
return 0;
}
int config_parse_bus_endpoint_policy(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_free_ char *name = NULL;
BusPolicyAccess access;
ExecContext *c = data;
char *access_str;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
name = strdup(rvalue);
if (!name)
return log_oom();
access_str = strpbrk(name, WHITESPACE);
if (!access_str) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid endpoint policy value '%s'", rvalue);
return 0;
}
*access_str = '\0';
access_str++;
access_str += strspn(access_str, WHITESPACE);
access = bus_policy_access_from_string(access_str);
if (access <= _BUS_POLICY_ACCESS_INVALID ||
access >= _BUS_POLICY_ACCESS_MAX) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid endpoint policy access type '%s'", access_str);
return 0;
}
if (!c->bus_endpoint) {
r = bus_endpoint_new(&c->bus_endpoint);
if (r < 0)
return log_error_errno(r, "Failed to create bus endpoint object: %m");
}
return bus_endpoint_add_policy(c->bus_endpoint, name, access);
}
int config_parse_working_directory(
const char *unit,
const char *filename,

View file

@ -67,7 +67,6 @@ int config_parse_service_sockets(const char *unit, const char *filename, unsigne
int config_parse_busname_service(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bus_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bus_policy_world(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bus_endpoint_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_env_file(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_ip_tos(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_condition_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);

View file

@ -703,7 +703,6 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
.apply_permissions = true,
.apply_chroot = true,
.apply_tty_stdin = true,
.bus_endpoint_fd = -1,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,

View file

@ -51,7 +51,6 @@ typedef enum MountMode {
PRIVATE_TMP,
PRIVATE_VAR_TMP,
PRIVATE_DEV,
PRIVATE_BUS_ENDPOINT,
READWRITE
} MountMode;
@ -268,78 +267,6 @@ fail:
return r;
}
static int mount_kdbus(BindMount *m) {
char temporary_mount[] = "/tmp/kdbus-dev-XXXXXX";
_cleanup_free_ char *basepath = NULL;
_cleanup_umask_ mode_t u;
char *busnode = NULL, *root;
struct stat st;
int r;
assert(m);
u = umask(0000);
if (!mkdtemp(temporary_mount))
return log_error_errno(errno, "Failed create temp dir: %m");
root = strjoina(temporary_mount, "/kdbus");
(void) mkdir(root, 0755);
if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_STRICTATIME, "mode=777") < 0) {
r = -errno;
goto fail;
}
/* create a new /dev/null dev node copy so we have some fodder to
* bind-mount the custom endpoint over. */
if (stat("/dev/null", &st) < 0) {
r = log_error_errno(errno, "Failed to stat /dev/null: %m");
goto fail;
}
busnode = strjoina(root, "/bus");
if (mknod(busnode, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) {
r = log_error_errno(errno, "mknod() for %s failed: %m",
busnode);
goto fail;
}
r = mount(m->path, busnode, NULL, MS_BIND, NULL);
if (r < 0) {
r = log_error_errno(errno, "bind mount of %s failed: %m",
m->path);
goto fail;
}
basepath = dirname_malloc(m->path);
if (!basepath) {
r = -ENOMEM;
goto fail;
}
if (mount(root, basepath, NULL, MS_MOVE, NULL) < 0) {
r = log_error_errno(errno, "bind mount of %s failed: %m",
basepath);
goto fail;
}
rmdir(temporary_mount);
return 0;
fail:
if (busnode) {
umount(busnode);
unlink(busnode);
}
umount(root);
rmdir(root);
rmdir(temporary_mount);
return r;
}
static int apply_mount(
BindMount *m,
const char *tmp_dir,
@ -379,9 +306,6 @@ static int apply_mount(
case PRIVATE_DEV:
return mount_dev(m);
case PRIVATE_BUS_ENDPOINT:
return mount_kdbus(m);
default:
assert_not_reached("Unknown mode");
}
@ -422,7 +346,6 @@ int setup_namespace(
char** inaccessible_dirs,
const char* tmp_dir,
const char* var_tmp_dir,
const char* bus_endpoint_path,
bool private_dev,
ProtectHome protect_home,
ProtectSystem protect_system,
@ -438,7 +361,7 @@ int setup_namespace(
if (unshare(CLONE_NEWNS) < 0)
return -errno;
n = !!tmp_dir + !!var_tmp_dir + !!bus_endpoint_path +
n = !!tmp_dir + !!var_tmp_dir +
strv_length(read_write_dirs) +
strv_length(read_only_dirs) +
strv_length(inaccessible_dirs) +
@ -479,12 +402,6 @@ int setup_namespace(
m++;
}
if (bus_endpoint_path) {
m->path = prefix_roota(root_directory, bus_endpoint_path);
m->mode = PRIVATE_BUS_ENDPOINT;
m++;
}
if (protect_home != PROTECT_HOME_NO) {
const char *home_dir, *run_user_dir, *root_dir;

View file

@ -45,7 +45,6 @@ int setup_namespace(const char *chroot,
char **inaccessible_dirs,
const char *tmp_dir,
const char *var_tmp_dir,
const char *endpoint_path,
bool private_dev,
ProtectHome protect_home,
ProtectSystem protect_system,

View file

@ -113,7 +113,6 @@ static void service_init(Unit *u) {
s->runtime_max_usec = USEC_INFINITY;
s->type = _SERVICE_TYPE_INVALID;
s->socket_fd = -1;
s->bus_endpoint_fd = -1;
s->stdin_fd = s->stdout_fd = s->stderr_fd = -1;
s->guess_main_pid = true;
@ -321,7 +320,6 @@ static void service_done(Unit *u) {
s->bus_name_owner = mfree(s->bus_name_owner);
s->bus_endpoint_fd = safe_close(s->bus_endpoint_fd);
service_close_socket_fd(s);
service_connection_unref(s);
@ -1157,7 +1155,6 @@ static int service_spawn(
pid_t *_pid) {
_cleanup_strv_free_ char **argv = NULL, **final_env = NULL, **our_env = NULL, **fd_names = NULL;
_cleanup_free_ char *bus_endpoint_path = NULL;
_cleanup_free_ int *fds = NULL;
unsigned n_fds = 0, n_env = 0;
const char *path;
@ -1167,7 +1164,6 @@ static int service_spawn(
.apply_permissions = apply_permissions,
.apply_chroot = apply_chroot,
.apply_tty_stdin = apply_tty_stdin,
.bus_endpoint_fd = -1,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
@ -1267,18 +1263,6 @@ static int service_spawn(
} else
path = UNIT(s)->cgroup_path;
if (s->exec_context.bus_endpoint) {
r = bus_kernel_create_endpoint(UNIT(s)->manager->running_as == MANAGER_SYSTEM ? "system" : "user",
UNIT(s)->id, &bus_endpoint_path);
if (r < 0)
return r;
/* Pass the fd to the exec_params so that the child process can upload the policy.
* Keep a reference to the fd in the service, so the endpoint is kept alive as long
* as the service is running. */
exec_params.bus_endpoint_fd = s->bus_endpoint_fd = r;
}
exec_params.argv = argv;
exec_params.fds = fds;
exec_params.fd_names = fd_names;
@ -1290,7 +1274,6 @@ static int service_spawn(
exec_params.cgroup_delegate = s->cgroup_context.delegate;
exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
exec_params.watchdog_usec = s->watchdog_usec;
exec_params.bus_endpoint_path = bus_endpoint_path;
exec_params.selinux_context_net = s->socket_fd_selinux_context_net;
if (s->type == SERVICE_IDLE)
exec_params.idle_pipe = UNIT(s)->manager->idle_pipe;
@ -2124,9 +2107,6 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
return r;
r = unit_serialize_item_fd(u, f, fds, "socket-fd", s->socket_fd);
if (r < 0)
return r;
r = unit_serialize_item_fd(u, f, fds, "endpoint-fd", s->bus_endpoint_fd);
if (r < 0)
return r;
@ -2263,15 +2243,6 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
asynchronous_close(s->socket_fd);
s->socket_fd = fdset_remove(fds, fd);
}
} else if (streq(key, "endpoint-fd")) {
int fd;
if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
log_unit_debug(u, "Failed to parse endpoint-fd value: %s", value);
else {
safe_close(s->bus_endpoint_fd);
s->bus_endpoint_fd = fdset_remove(fds, fd);
}
} else if (streq(key, "fd-store-fd")) {
const char *fdv;
size_t pf;

View file

@ -150,8 +150,6 @@ struct Service {
int socket_fd;
bool socket_fd_selinux_context_net;
int bus_endpoint_fd;
bool permissions_start_only;
bool root_directory_start_only;
bool remain_after_exit;

View file

@ -1527,7 +1527,6 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
.apply_permissions = true,
.apply_chroot = true,
.apply_tty_stdin = true,
.bus_endpoint_fd = -1,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,

View file

@ -609,7 +609,6 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
.apply_permissions = true,
.apply_chroot = true,
.apply_tty_stdin = true,
.bus_endpoint_fd = -1,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,

View file

@ -1693,50 +1693,6 @@ int bus_kernel_open_bus_fd(const char *bus, char **path) {
return fd;
}
int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) {
_cleanup_free_ char *path = NULL;
struct kdbus_cmd *make;
struct kdbus_item *n;
const char *name;
int fd;
fd = bus_kernel_open_bus_fd(bus_name, &path);
if (fd < 0)
return fd;
make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd, items)) +
ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + strlen(ep_name) + 1),
8);
make->size = ALIGN8(offsetof(struct kdbus_cmd, items));
make->flags = KDBUS_MAKE_ACCESS_WORLD;
n = make->items;
sprintf(n->str, UID_FMT "-%s", getuid(), ep_name);
n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
n->type = KDBUS_ITEM_MAKE_NAME;
make->size += ALIGN8(n->size);
name = n->str;
if (ioctl(fd, KDBUS_CMD_ENDPOINT_MAKE, make) < 0) {
safe_close(fd);
return -errno;
}
if (ep_path) {
char *p;
p = strjoin(dirname(path), "/", name, NULL);
if (!p) {
safe_close(fd);
return -ENOMEM;
}
*ep_path = p;
}
return fd;
}
int bus_kernel_try_close(sd_bus *bus) {
struct kdbus_cmd byebye = { .size = sizeof(byebye) };

View file

@ -68,7 +68,6 @@ int main(int argc, char *argv[]) {
(char **) inaccessible,
tmp_dir,
var_tmp_dir,
NULL,
true,
PROTECT_HOME_NO,
PROTECT_SYSTEM_NO,