summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus/kdbus.h
blob: 4604eb32b78fb4e34cb7a03db019f82da3a94e6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
/*
 * Copyright (C) 2013 Kay Sievers
 * Copyright (C) 2013 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 * Copyright (C) 2013 Linux Foundation
 * Copyright (C) 2013 Lennart Poettering
 * Copyright (C) 2013 Daniel Mack <daniel@zonque.org>
 *
 * kdbus 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.
 */

#ifndef _KDBUS_H_
#define _KDBUS_H_

#ifndef __KERNEL__
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/types.h>
#endif

#define KDBUS_IOC_MAGIC			0x95
#define KDBUS_SRC_ID_KERNEL		(0)
#define KDBUS_DST_ID_WELL_KNOWN_NAME	(0)
#define KDBUS_MATCH_SRC_ID_ANY		(~0ULL)
#define KDBUS_DST_ID_BROADCAST		(~0ULL)

/* Common first elements in a structure which are used to iterate over
 * a list of elements. */
#define KDBUS_PART_HEADER \
	struct {							\
		__u64 size;						\
		__u64 type;						\
	}

/* Message sent from kernel to userspace, when the owner or starter of
 * a well-known name changes */
struct kdbus_manager_msg_name_change {
	__u64 old_id;
	__u64 new_id;
	__u64 flags;			/* 0 or (possibly?) KDBUS_NAME_IN_QUEUE */
	char name[0];
};

struct kdbus_manager_msg_id_change {
	__u64 id;
	__u64 flags;			/* The kernel flags field from KDBUS_HELLO */
};

struct kdbus_creds {
	__u64 uid;
	__u64 gid;
	__u64 pid;
	__u64 tid;

	/* The starttime of the process PID. This is useful to detect
	PID overruns from the client side. i.e. if you use the PID to
	look something up in /proc/$PID/ you can afterwards check the
	starttime field of it to ensure you didn't run into a PID
	ovretun. */
	__u64 starttime;
};

struct kdbus_audit {
	__u64 sessionid;
	__u64 loginuid;
};

struct kdbus_timestamp {
	__u64 monotonic_ns;
	__u64 realtime_ns;
};

struct kdbus_vec {
	__u64 size;
	union {
		__u64 address;
		__u64 offset;
	};
};

struct kdbus_memfd {
	__u64 size;
	int fd;
	__u32 __pad;
};

/* Message Item Types */
enum {
	_KDBUS_MSG_NULL,

	/* Filled in by userspace */
	KDBUS_MSG_PAYLOAD_VEC,		/* .data_vec, reference to memory area */
	KDBUS_MSG_PAYLOAD_OFF,		/* .data_vec, reference to memory area */
	KDBUS_MSG_PAYLOAD_MEMFD,	/* file descriptor of a special data file */
	KDBUS_MSG_FDS,			/* .data_fds of file descriptors */
	KDBUS_MSG_BLOOM,		/* for broadcasts, carries bloom filter blob in .data */
	KDBUS_MSG_DST_NAME,		/* destination's well-known name, in .str */
	KDBUS_MSG_PRIORITY,		/* queue priority for message */

	/* Filled in by kernelspace */
	KDBUS_MSG_SRC_NAMES	= 0x400,/* NUL separated string list with well-known names of source */
	KDBUS_MSG_TIMESTAMP,		/* .timestamp */
	KDBUS_MSG_SRC_CREDS,		/* .creds */
	KDBUS_MSG_SRC_PID_COMM,		/* optional, in .str */
	KDBUS_MSG_SRC_TID_COMM,		/* optional, in .str */
	KDBUS_MSG_SRC_EXE,		/* optional, in .str */
	KDBUS_MSG_SRC_CMDLINE,		/* optional, in .str (a chain of NUL str) */
	KDBUS_MSG_SRC_CGROUP,		/* optional, in .str */
	KDBUS_MSG_SRC_CAPS,		/* caps data blob, in .data */
	KDBUS_MSG_SRC_SECLABEL,		/* NUL terminated string, in .str */
	KDBUS_MSG_SRC_AUDIT,		/* .audit */

	/* Special messages from kernel, consisting of one and only one of these data blocks */
	KDBUS_MSG_NAME_ADD	= 0x800,/* .name_change */
	KDBUS_MSG_NAME_REMOVE,		/* .name_change */
	KDBUS_MSG_NAME_CHANGE,		/* .name_change */
	KDBUS_MSG_ID_ADD,		/* .id_change */
	KDBUS_MSG_ID_REMOVE,		/* .id_change */
	KDBUS_MSG_REPLY_TIMEOUT,	/* empty, but .reply_cookie in .kdbus_msg is filled in */
	KDBUS_MSG_REPLY_DEAD,		/* dito */
};

/**
 * struct  kdbus_item - chain of data blocks
 *
 * size: overall data record size
 * type: kdbus_item type of data
 */
struct kdbus_item {
	KDBUS_PART_HEADER;
	union {
		/* inline data */
		__u8 data[0];
		__u32 data32[0];
		__u64 data64[0];
		char str[0];

		/* connection */
		__u64 id;

		/* data vector */
		struct kdbus_vec vec;

		/* process credentials and properties*/
		struct kdbus_creds creds;
		struct kdbus_audit audit;
		struct kdbus_timestamp timestamp;

		/* specific fields */
		struct kdbus_memfd memfd;
		int fds[0];
		struct kdbus_manager_msg_name_change name_change;
		struct kdbus_manager_msg_id_change id_change;
	};
};

enum {
	KDBUS_MSG_FLAGS_EXPECT_REPLY	= 1 << 0,
	KDBUS_MSG_FLAGS_NO_AUTO_START	= 1 << 1,
};

enum {
	KDBUS_PAYLOAD_KERNEL,
	KDBUS_PAYLOAD_DBUS1	= 0x4442757356657231ULL, /* 'DBusVer1' */
	KDBUS_PAYLOAD_GVARIANT	= 0x4756617269616e74ULL, /* 'GVariant' */
};

/**
 * struct kdbus_msg
 *
 * set by userspace:
 * dst_id: destination id
 * flags: KDBUS_MSG_FLAGS_*
 * items: data records
 *
 * set by kernel:
 * src_id: who sent the message
 */
struct kdbus_msg {
	__u64 size;
	__u64 flags;
	__u64 dst_id;			/* connection, 0 == name in data, ~0 broadcast */
	__u64 src_id;			/* connection, 0 == kernel */
	__u64 payload_type;		/* 'DBusVer1', 'GVariant', ... */
	__u64 cookie;			/* userspace-supplied cookie */
	union {
		__u64 cookie_reply;	/* cookie we reply to */
		__u64 timeout_ns;	/* timespan to wait for reply */
	};
	struct kdbus_item items[0];
};

enum {
	_KDBUS_POLICY_NULL,
	KDBUS_POLICY_NAME,
	KDBUS_POLICY_ACCESS,
};

enum {
	_KDBUS_POLICY_ACCESS_NULL,
	KDBUS_POLICY_ACCESS_USER,
	KDBUS_POLICY_ACCESS_GROUP,
	KDBUS_POLICY_ACCESS_WORLD,
};

enum {
	KDBUS_POLICY_RECV		= 1 <<  2,
	KDBUS_POLICY_SEND		= 1 <<  1,
	KDBUS_POLICY_OWN		= 1 <<  0,
};

struct kdbus_policy_access {
	__u64 type;		/* USER, GROUP, WORLD */
	__u64 bits;		/* RECV, SEND, OWN */
	__u64 id;		/* uid, gid, 0 */
};

//FIXME: convert access to access[]
struct kdbus_policy {
	KDBUS_PART_HEADER;
	union {
		char name[0];
		struct kdbus_policy_access access;
	};
};

/* A series of KDBUS_POLICY_NAME, plus one or more KDBUS_POLICY_ACCESS */
struct kdbus_cmd_policy {
	__u64 size;
	struct kdbus_policy policies[0];
};

/* Flags for struct kdbus_cmd_hello */
enum {
	KDBUS_HELLO_STARTER		=  1 <<  0,
	KDBUS_HELLO_ACCEPT_FD		=  1 <<  1,

	/* The following have an effect on directed messages only --
	 * not for broadcasts */
	KDBUS_HELLO_ATTACH_COMM		=  1 << 10,
	KDBUS_HELLO_ATTACH_EXE		=  1 << 11,
	KDBUS_HELLO_ATTACH_CMDLINE	=  1 << 12,
	KDBUS_HELLO_ATTACH_CGROUP	=  1 << 13,
	KDBUS_HELLO_ATTACH_CAPS		=  1 << 14,
	KDBUS_HELLO_ATTACH_SECLABEL	=  1 << 15,
	KDBUS_HELLO_ATTACH_AUDIT	=  1 << 16,
};

struct kdbus_cmd_hello {
	__u64 size;

	/* userspace → kernel, kernel → userspace */
	__u64 conn_flags;	/* userspace specifies its
				 * capabilities and more, kernel
				 * returns its capabilites and
				 * more. Kernel might refuse client's
				 * capabilities by returning an error
				 * from KDBUS_HELLO */

	/* kernel → userspace */
	__u64 bus_flags;	/* this is .flags copied verbatim from
				 * from original KDBUS_CMD_BUS_MAKE
				 * ioctl. It's intended to be useful
				 * to do negotiation of features of
				 * the payload that is transfreted. */
	__u64 id;		/* id assigned to this connection */
	__u64 bloom_size;	/* The bloom filter size chosen by the
				 * bus owner */
	__u64 pool_size;	/* maximum size of pool buffer */
	struct kdbus_item items[0];
};

/* Flags for kdbus_cmd_{bus,ep,ns}_make */
enum {
	KDBUS_MAKE_ACCESS_GROUP		= 1 <<  0,
	KDBUS_MAKE_ACCESS_WORLD		= 1 <<  1,
	KDBUS_MAKE_POLICY_OPEN		= 1 <<  2,
};

/* Items to append to kdbus_cmd_{bus,ep,ns}_make */
enum {
	_KDBUS_MAKE_NULL,
	KDBUS_MAKE_NAME,
	KDBUS_MAKE_CGROUP,	/* the cgroup hierarchy ID for which to attach
				 * cgroup membership paths to messages.
				 * FIXME: remove, use *the* hierarchy */
	KDBUS_MAKE_CRED,	/* allow translator services which connect
				 * to the bus on behalf of somebody else,
				 * allow specifiying the credentials of the
				 * client to connect on behalf on. Needs
				 * privileges */
};

struct kdbus_cmd_bus_make {
	__u64 size;
	__u64 flags;		/* userspace → kernel, kernel → userspace
				 * When creating a bus feature
				 * kernel negotiation. */
	__u64 bus_flags;	/* userspace → kernel
				 * When a bus is created this value is
				 * copied verbatim into the bus
				 * structure and returned from
				 * KDBUS_CMD_HELLO, later */
	__u64 bloom_size;	/* size of the bloom filter for this bus */
	struct kdbus_item items[0];
};

struct kdbus_cmd_ep_make {
	__u64 size;
	__u64 flags;		/* userspace → kernel, kernel → userspace
				 * When creating an entry point
				 * feature kernel negotiation done the
				 * same way as for
				 * KDBUS_CMD_BUS_MAKE. Unused for
				 * now. */
	struct kdbus_item items[0];
};

struct kdbus_cmd_ns_make {
	__u64 size;
	__u64 flags;		/* userspace → kernel, kernel → userspace
				 * When creating an entry point
				 * feature kernel negotiation done the
				 * same way as for
				 * KDBUS_CMD_BUS_MAKE. Unused for
				 * now. */
	struct kdbus_item items[0];
};

enum {
	/* userspace → kernel */
	KDBUS_NAME_REPLACE_EXISTING		= 1 <<  0,
	KDBUS_NAME_QUEUE			= 1 <<  1,
	KDBUS_NAME_ALLOW_REPLACEMENT		= 1 <<  2,

	/* kernel → userspace */
	KDBUS_NAME_IN_QUEUE			= 1 << 16,
};

/* We allow (de)regestration of names of other peers */
struct kdbus_cmd_name {
	__u64 size;
	__u64 flags;
	__u64 id;
	__u64 conn_flags;
	char name[0];
};

struct kdbus_cmd_names {
	__u64 size;
	struct kdbus_cmd_name names[0];
};

enum {
	_KDBUS_NAME_INFO_ITEM_NULL,
	KDBUS_NAME_INFO_ITEM_NAME,	/* userspace → kernel */
	KDBUS_NAME_INFO_ITEM_SECLABEL,	/* kernel → userspace */
	KDBUS_NAME_INFO_ITEM_AUDIT,	/* kernel → userspace */
};

struct kdbus_cmd_name_info {
	__u64 size;			/* overall size of info */
	__u64 flags;
	__u64 id;			/* either ID, or 0 and _ITEM_NAME follows */
	struct kdbus_creds creds;
	struct kdbus_item items[0];	/* list of item records */
};

enum {
	_KDBUS_MATCH_NULL,
	KDBUS_MATCH_BLOOM,		/* Matches a mask blob against KDBUS_MSG_BLOOM */
	KDBUS_MATCH_SRC_NAME,		/* Matches a name string against KDBUS_MSG_SRC_NAMES */
	KDBUS_MATCH_NAME_ADD,		/* Matches a name string against KDBUS_MSG_NAME_ADD */
	KDBUS_MATCH_NAME_REMOVE,	/* Matches a name string against KDBUS_MSG_NAME_REMOVE */
	KDBUS_MATCH_NAME_CHANGE,	/* Matches a name string against KDBUS_MSG_NAME_CHANGE */
	KDBUS_MATCH_ID_ADD,		/* Matches an ID against KDBUS_MSG_ID_ADD */
	KDBUS_MATCH_ID_REMOVE,		/* Matches an ID against KDBUS_MSG_ID_REMOVE */
};

struct kdbus_cmd_match {
	__u64 size;
	__u64 id;	/* We allow registration/deregestration of matches for other peers */
	__u64 cookie;	/* userspace supplied cookie; when removing; kernel deletes everything with same cookie */
	__u64 src_id;	/* ~0: any. other: exact unique match */
	struct kdbus_item items[0];
};

struct kdbus_cmd_monitor {
	__u64 id;		/* We allow setting the monitor flag of other peers */
	unsigned int enable;	/* A boolean to enable/disable monitoring */
	__u32 __pad;
};

/* FD states:
 * control nodes: unset
 *   bus owner  (via KDBUS_CMD_BUS_MAKE)
 *   ns owner   (via KDBUS_CMD_NS_MAKE)
 *
 * ep nodes: unset
 *   connected  (via KDBUS_CMD_HELLO)
 *   starter    (via KDBUS_CMD_HELLO with KDBUS_CMD_HELLO_STARTER)
 *   ep owner   (via KDBUS_CMD_EP_MAKE)
 */
enum {
	/* kdbus control node commands: require unset state */
	KDBUS_CMD_BUS_MAKE =		_IOW(KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_bus_make),
	KDBUS_CMD_NS_MAKE =		_IOR(KDBUS_IOC_MAGIC, 0x10, struct kdbus_cmd_ns_make),

	/* kdbus ep node commands: require unset state */
	KDBUS_CMD_EP_MAKE =		_IOW(KDBUS_IOC_MAGIC, 0x20, struct kdbus_cmd_ep_make),
	KDBUS_CMD_HELLO =		_IOWR(KDBUS_IOC_MAGIC, 0x30, struct kdbus_cmd_hello),

	/* kdbus ep node commands: require connected state */
	KDBUS_CMD_MSG_SEND =		_IOW(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg),
	KDBUS_CMD_MSG_RECV =		_IOR(KDBUS_IOC_MAGIC, 0x41, __u64 *),
	KDBUS_CMD_MSG_RELEASE =		_IOW(KDBUS_IOC_MAGIC, 0x42, __u64 *),

	KDBUS_CMD_NAME_ACQUIRE =	_IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name),
	KDBUS_CMD_NAME_RELEASE =	_IOW(KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name),
	KDBUS_CMD_NAME_LIST =		_IOWR(KDBUS_IOC_MAGIC, 0x52, struct kdbus_cmd_names),
	KDBUS_CMD_NAME_QUERY =		_IOWR(KDBUS_IOC_MAGIC, 0x53, struct kdbus_cmd_name_info),

	KDBUS_CMD_MATCH_ADD =		_IOW(KDBUS_IOC_MAGIC, 0x60, struct kdbus_cmd_match),
	KDBUS_CMD_MATCH_REMOVE =	_IOW(KDBUS_IOC_MAGIC, 0x61, struct kdbus_cmd_match),
	KDBUS_CMD_MONITOR =		_IOW(KDBUS_IOC_MAGIC, 0x62, struct kdbus_cmd_monitor),

	/* kdbus ep node commands: require ep owner state */
	KDBUS_CMD_EP_POLICY_SET =	_IOW(KDBUS_IOC_MAGIC, 0x70, struct kdbus_cmd_policy),

	/* kdbus memfd commands: */
	KDBUS_CMD_MEMFD_NEW =		_IOR(KDBUS_IOC_MAGIC, 0x80, int *),
	KDBUS_CMD_MEMFD_SIZE_GET =	_IOR(KDBUS_IOC_MAGIC, 0x81, __u64 *),
	KDBUS_CMD_MEMFD_SIZE_SET =	_IOW(KDBUS_IOC_MAGIC, 0x82, __u64 *),
	KDBUS_CMD_MEMFD_SEAL_GET =	_IOR(KDBUS_IOC_MAGIC, 0x83, int *),
	KDBUS_CMD_MEMFD_SEAL_SET =	_IO(KDBUS_IOC_MAGIC, 0x84),
};
#endif