#include "strv.h"
#include "time-util.h"
#include "cgroup-util.h"
+#include "memfd-util.h"
#include "sd-bus.h"
#include "bus-message.h"
if (part->mapped > 0)
assert_se(munmap(part->data, part->mapped) == 0);
- close_nointr_nofail(part->memfd);
+ safe_close(part->memfd);
}
} else if (part->munmap_this)
message_reset_parts(m);
- if (m->free_kdbus)
- free(m->kdbus);
-
if (m->release_kdbus) {
- uint64_t off;
+ struct kdbus_cmd_free cmd_free;
- off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
- ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
+ cmd_free.flags = 0;
+ cmd_free.offset = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
+ (void) ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &cmd_free);
}
- if (m->bus)
- sd_bus_unref(m->bus);
+ if (m->free_kdbus)
+ free(m->kdbus);
+
+ sd_bus_unref(m->bus);
if (m->free_fds) {
close_many(m->fds, m->n_fds);
struct bus_header *h;
size_t a, label_sz;
+ assert(bus);
assert(buffer || length <= 0);
assert(fds || n_fds <= 0);
assert(ret);
m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
}
- if (bus)
- m->bus = sd_bus_ref(bus);
-
+ m->bus = sd_bus_ref(bus);
*ret = m;
+
return 0;
}
static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
sd_bus_message *m;
+ assert(bus);
+
m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
if (!m)
return NULL;
m->header->version = bus ? bus->message_version : 1;
m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
-
- if (bus)
- m->bus = sd_bus_ref(bus);
+ m->bus = sd_bus_ref(bus);
return m;
}
sd_bus_message *t;
int r;
- assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
+ assert_return(bus, -ENOTCONN);
+ assert_return(bus->state != BUS_UNSET, -ENOTCONN);
assert_return(object_path_is_valid(path), -EINVAL);
assert_return(interface_name_is_valid(interface), -EINVAL);
assert_return(member_name_is_valid(member), -EINVAL);
sd_bus_message *t;
int r;
- assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
+ assert_return(bus, -ENOTCONN);
+ assert_return(bus->state != BUS_UNSET, -ENOTCONN);
assert_return(!destination || service_name_is_valid(destination), -EINVAL);
assert_return(object_path_is_valid(path), -EINVAL);
assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
assert_return(call, -EINVAL);
assert_return(call->sealed, -EPERM);
assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
- assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
+ assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
assert_return(m, -EINVAL);
t = message_new(call->bus, type);
sd_bus_message *t;
int r;
+ assert(bus);
assert(sd_bus_error_is_set(e));
assert(m);
assert(m->n_ref > 0);
m->n_ref--;
- if (m->n_ref <= 0)
- message_free(m);
+ if (m->n_ref > 0)
+ return NULL;
+ message_free(m);
return NULL;
}
return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
}
+_public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
+ assert_return(m, -EINVAL);
+
+ return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
+ (m->header->flags & BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION);
+}
+
_public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
assert_return(m, NULL);
return 0;
}
+_public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) {
+ assert_return(m, -EINVAL);
+ assert_return(!m->sealed, -EPERM);
+
+ if (b)
+ m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
+ else
+ m->header->flags &= ~BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
+
+ return 0;
+}
+
static struct bus_container *message_get_container(sd_bus_message *m) {
assert(m);
uint64_t new_allocated;
new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
- r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &new_allocated);
+ r = memfd_set_size(part->memfd, new_allocated);
if (r < 0) {
m->poisoned = true;
- return -errno;
+ return r;
}
part->allocated = new_allocated;
f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
if (!f) {
m->poisoned = true;
- close_nointr_nofail(copy);
+ safe_close(copy);
return -ENOMEM;
}
_public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
char type,
- sd_memfd *memfd) {
+ int memfd) {
_cleanup_close_ int copy_fd = -1;
struct bus_body_part *part;
ssize_t align, sz;
if (!m)
return -EINVAL;
- if (!memfd)
+ if (memfd < 0)
return -EINVAL;
if (m->sealed)
return -EPERM;
if (m->poisoned)
return -ESTALE;
- r = sd_memfd_set_sealed(memfd, true);
+ r = memfd_set_sealed(memfd);
if (r < 0)
return r;
- copy_fd = sd_memfd_dup_fd(memfd);
+ copy_fd = dup(memfd);
if (copy_fd < 0)
return copy_fd;
- r = sd_memfd_get_size(memfd, &size);
+ r = memfd_get_size(memfd, &size);
if (r < 0)
return r;
return sd_bus_message_close_container(m);
}
-_public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
+_public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd) {
_cleanup_close_ int copy_fd = -1;
struct bus_body_part *part;
struct bus_container *c;
int r;
assert_return(m, -EINVAL);
- assert_return(memfd, -EINVAL);
+ assert_return(memfd >= 0, -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(!m->poisoned, -ESTALE);
- r = sd_memfd_set_sealed(memfd, true);
+ r = memfd_set_sealed(memfd);
if (r < 0)
return r;
- copy_fd = sd_memfd_dup_fd(memfd);
+ copy_fd = dup(memfd);
if (copy_fd < 0)
return copy_fd;
- r = sd_memfd_get_size(memfd, &size);
+ r = memfd_get_size(memfd, &size);
if (r < 0)
return r;
/* If this is something we can send as memfd, then let's seal
the memfd now. Note that we can send memfds as payload only
for directed messages, and not for broadcasts. */
- if (m->destination && m->bus && m->bus->use_memfd) {
+ if (m->destination && m->bus->use_memfd) {
MESSAGE_FOREACH_PART(part, i, m)
if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
uint64_t sz;
/* Then, sync up real memfd size */
sz = part->size;
- if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &sz) < 0)
- return -errno;
+ r = memfd_set_size(part->memfd, sz);
+ if (r < 0)
+ return r;
/* Finally, try to seal */
- if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
+ if (memfd_set_sealed(part->memfd) >= 0)
part->sealed = true;
}
}
psz = PAGE_ALIGN(part->size);
if (part->memfd >= 0)
- p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
+ p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, 0);
else if (part->is_zero)
p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
else
* in a single stackframe. We hence implement our own
* home-grown stack in an array. */
- n_array = (unsigned) -1; /* lenght of current array entries */
+ n_array = (unsigned) -1; /* length of current array entries */
n_struct = strlen(types); /* length of current struct contents signature */
for (;;) {
size_t ri;
int r;
uint32_t unix_fds = 0;
+ bool unix_fds_set = false;
void *offsets = NULL;
unsigned n_offsets = 0;
size_t sz = 0;
r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
- if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
+ if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
m->creds.unique_name = (char*) m->sender;
m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
}
}
case BUS_MESSAGE_HEADER_UNIX_FDS:
- if (unix_fds != 0)
+ if (unix_fds_set)
return -EBADMSG;
if (!streq(signature, "u"))
if (r < 0)
return -EBADMSG;
- if (unix_fds == 0)
- return -EBADMSG;
-
+ unix_fds_set = true;
break;
default:
}
_public_ int sd_bus_message_get_errno(sd_bus_message *m) {
- assert_return(m, -EINVAL);
+ assert_return(m, EINVAL);
if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
return 0;