Skip to content

Commit a4152e3

Browse files
committed
kdbus: when uploading bus name policy, resolve users/groups out-of-process
It's not safe invoking NSS from PID 1, hence fork off worker processes that upload the policy into the kernel for busnames.
1 parent 5331194 commit a4152e3

File tree

11 files changed

+530
-149
lines changed

11 files changed

+530
-149
lines changed

src/core/busname.c

Lines changed: 378 additions & 33 deletions
Large diffs are not rendered by default.

src/core/busname.h

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ typedef struct BusNamePolicy BusNamePolicy;
2828

2929
typedef enum BusNameState {
3030
BUSNAME_DEAD,
31+
BUSNAME_MAKING,
3132
BUSNAME_REGISTERED,
3233
BUSNAME_LISTENING,
3334
BUSNAME_RUNNING,
35+
BUSNAME_SIGTERM,
36+
BUSNAME_SIGKILL,
3437
BUSNAME_FAILED,
3538
_BUSNAME_STATE_MAX,
3639
_BUSNAME_STATE_INVALID = -1
@@ -39,34 +42,18 @@ typedef enum BusNameState {
3942
typedef enum BusNameResult {
4043
BUSNAME_SUCCESS,
4144
BUSNAME_FAILURE_RESOURCES,
45+
BUSNAME_FAILURE_TIMEOUT,
46+
BUSNAME_FAILURE_EXIT_CODE,
47+
BUSNAME_FAILURE_SIGNAL,
48+
BUSNAME_FAILURE_CORE_DUMP,
4249
BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT,
4350
_BUSNAME_RESULT_MAX,
4451
_BUSNAME_RESULT_INVALID = -1
4552
} BusNameResult;
4653

47-
struct BusName {
48-
Unit meta;
49-
50-
char *name;
51-
int starter_fd;
52-
53-
bool activating;
54-
bool accept_fd;
55-
56-
UnitRef service;
57-
58-
BusNameState state, deserialized_state;
59-
BusNameResult result;
60-
61-
sd_event_source *event_source;
62-
63-
LIST_HEAD(BusNamePolicy, policy);
64-
};
65-
6654
typedef enum BusNamePolicyType {
6755
BUSNAME_POLICY_TYPE_USER,
6856
BUSNAME_POLICY_TYPE_GROUP,
69-
BUSNAME_POLICY_TYPE_WORLD,
7057
_BUSNAME_POLICY_TYPE_MAX,
7158
_BUSNAME_POLICY_TYPE_INVALID = -1
7259
} BusNamePolicyType;
@@ -83,14 +70,36 @@ struct BusNamePolicy {
8370
BusNamePolicyType type;
8471
BusNamePolicyAccess access;
8572

86-
union {
87-
uid_t uid;
88-
gid_t gid;
89-
};
73+
char *name;
9074

9175
LIST_FIELDS(BusNamePolicy, policy);
9276
};
9377

78+
struct BusName {
79+
Unit meta;
80+
81+
char *name;
82+
int starter_fd;
83+
84+
bool activating;
85+
bool accept_fd;
86+
87+
UnitRef service;
88+
89+
BusNameState state, deserialized_state;
90+
BusNameResult result;
91+
92+
usec_t timeout_usec;
93+
94+
sd_event_source *starter_event_source;
95+
sd_event_source *timer_event_source;
96+
97+
pid_t control_pid;
98+
99+
LIST_HEAD(BusNamePolicy, policy);
100+
BusNamePolicyAccess policy_world;
101+
};
102+
94103
extern const UnitVTable busname_vtable;
95104

96105
const char* busname_state_to_string(BusNameState i) _const_;

src/core/dbus-busname.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, busname_result, BusName
3030
const sd_bus_vtable bus_busname_vtable[] = {
3131
SD_BUS_VTABLE_START(0),
3232
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(BusName, name), SD_BUS_VTABLE_PROPERTY_CONST),
33+
SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(BusName, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
34+
SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(BusName, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
3335
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(BusName, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
3436
SD_BUS_PROPERTY("Activating", "b", bus_property_get_bool, offsetof(BusName, activating), SD_BUS_VTABLE_PROPERTY_CONST),
3537
SD_BUS_PROPERTY("AcceptFileDescriptors", "b", bus_property_get_bool, offsetof(BusName, accept_fd), SD_BUS_VTABLE_PROPERTY_CONST),

src/core/load-fragment-gperf.gperf.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ BusName.Activating, config_parse_bool, 0,
263263
BusName.Service, config_parse_busname_service, 0, 0
264264
BusName.AllowUser, config_parse_bus_policy, 0, 0
265265
BusName.AllowGroup, config_parse_bus_policy, 0, 0
266-
BusName.AllowWorld, config_parse_bus_policy, 0, 0
266+
BusName.AllowWorld, config_parse_bus_policy_world, 0, offsetof(BusName, policy_world)
267267
BusName.SELinuxContext, config_parse_exec_selinux_context, 0, 0
268268
BusName.AcceptFileDescriptors, config_parse_bool, 0, offsetof(BusName, accept_fd)
269269
m4_dnl

src/core/load-fragment.c

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,8 @@ int config_parse_busname_service(
16561656
return 0;
16571657
}
16581658

1659+
DEFINE_CONFIG_PARSE_ENUM(config_parse_bus_policy_world, busname_policy_access, BusNamePolicyAccess, "Failed to parse bus name policy access");
1660+
16591661
int config_parse_bus_policy(
16601662
const char *unit,
16611663
const char *filename,
@@ -1672,7 +1674,6 @@ int config_parse_bus_policy(
16721674
_cleanup_free_ char *id_str = NULL;
16731675
BusName *busname = data;
16741676
char *access_str;
1675-
int r;
16761677

16771678
assert(filename);
16781679
assert(lvalue);
@@ -1687,52 +1688,32 @@ int config_parse_bus_policy(
16871688
p->type = BUSNAME_POLICY_TYPE_USER;
16881689
else if (streq(lvalue, "AllowGroup"))
16891690
p->type = BUSNAME_POLICY_TYPE_GROUP;
1690-
else if (streq(lvalue, "AllowWorld"))
1691-
p->type = BUSNAME_POLICY_TYPE_WORLD;
16921691
else
16931692
assert_not_reached("Unknown lvalue");
16941693

16951694
id_str = strdup(rvalue);
16961695
if (!id_str)
16971696
return log_oom();
16981697

1699-
if (p->type != BUSNAME_POLICY_TYPE_WORLD) {
1700-
access_str = strchr(id_str, ' ');
1701-
if (!access_str) {
1702-
log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid busname policy value '%s'", rvalue);
1703-
return 0;
1704-
}
1705-
1706-
*access_str = '\0';
1707-
access_str++;
1708-
1709-
if (p->type == BUSNAME_POLICY_TYPE_USER) {
1710-
const char *user = id_str;
1711-
1712-
r = get_user_creds(&user, &p->uid, NULL, NULL, NULL);
1713-
if (r < 0) {
1714-
log_syntax(unit, LOG_ERR, filename, line, r, "Unable to parse uid from '%s'", id_str);
1715-
return 0;
1716-
}
1717-
} else {
1718-
const char *group = id_str;
1719-
1720-
r = get_group_creds(&group, &p->gid);
1721-
if (r < 0) {
1722-
log_syntax(unit, LOG_ERR, filename, line, -errno, "Unable to parse gid from '%s'", id_str);
1723-
return 0;
1724-
}
1725-
}
1726-
} else {
1727-
access_str = id_str;
1698+
access_str = strpbrk(id_str, WHITESPACE);
1699+
if (!access_str) {
1700+
log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid busname policy value '%s'", rvalue);
1701+
return 0;
17281702
}
17291703

1704+
*access_str = '\0';
1705+
access_str++;
1706+
access_str += strspn(access_str, WHITESPACE);
1707+
17301708
p->access = busname_policy_access_from_string(access_str);
17311709
if (p->access < 0) {
17321710
log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid busname policy access type '%s'", access_str);
17331711
return 0;
17341712
}
17351713

1714+
p->name = id_str;
1715+
id_str = NULL;
1716+
17361717
LIST_PREPEND(policy, busname->policy, p);
17371718
p = NULL;
17381719

src/core/load-fragment.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ int config_parse_socket_service(const char *unit, const char *filename, unsigned
6666
int config_parse_service_sockets(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);
6767
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);
6868
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);
69+
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);
6970
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);
7071
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);
7172
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);

src/core/socket.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,11 +1173,12 @@ static void socket_unwatch_fds(Socket *s) {
11731173
if (p->fd < 0)
11741174
continue;
11751175

1176-
if (p->event_source) {
1177-
r = sd_event_source_set_enabled(p->event_source, SD_EVENT_OFF);
1178-
if (r < 0)
1179-
log_debug_unit(UNIT(s)->id, "Failed to disable event source.");
1180-
}
1176+
if (!p->event_source)
1177+
continue;
1178+
1179+
r = sd_event_source_set_enabled(p->event_source, SD_EVENT_OFF);
1180+
if (r < 0)
1181+
log_debug_unit(UNIT(s)->id, "Failed to disable event source.");
11811182
}
11821183
}
11831184

@@ -1843,6 +1844,7 @@ static int socket_start(Unit *u) {
18431844
SOCKET_FINAL_SIGKILL))
18441845
return -EAGAIN;
18451846

1847+
/* Already on it! */
18461848
if (IN_SET(s->state,
18471849
SOCKET_START_PRE,
18481850
SOCKET_START_CHOWN,
@@ -1871,8 +1873,7 @@ static int socket_start(Unit *u) {
18711873

18721874
#ifdef HAVE_SYSV_COMPAT
18731875
if (service->is_sysv) {
1874-
log_error_unit(u->id,
1875-
"Using SysV services for socket activation is not supported. Refusing.");
1876+
log_error_unit(u->id, "Using SysV services for socket activation is not supported. Refusing.");
18761877
return -ENOENT;
18771878
}
18781879
#endif
@@ -2282,7 +2283,7 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
22822283
else if (code == CLD_DUMPED)
22832284
f = SOCKET_FAILURE_CORE_DUMP;
22842285
else
2285-
assert_not_reached("Unknown code");
2286+
assert_not_reached("Unknown sigchld code");
22862287

22872288
if (s->control_command) {
22882289
exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);

0 commit comments

Comments
 (0)