static void mfd_fail_new(const char *name, unsigned int flags) { int r; r = sys_memfd_create(name, flags); if (r >= 0) { printf("memfd_create(\"%s\", %u) succeeded, but failure expected\n", name, flags); close(r); abort(); } }
void check_mfd_fail_new(const char *filename, const int lineno, const char *name, int flags) { int fd; fd = sys_memfd_create(name, flags); if (fd >= 0) { safe_close(filename, lineno, NULL, fd); tst_brk_(filename, lineno, TFAIL, "memfd_create(%s, %d) succeeded unexpectedly", name, flags); } tst_res_(filename, lineno, TPASS | TERRNO, "memfd_create(%s, %d) failed as expected", name, flags); }
int mfd_flags_available(const char *filename, const int lineno, unsigned int flags) { TEST(sys_memfd_create("dummy_call", flags)); if (TEST_RETURN < 0) { if (TEST_ERRNO != EINVAL) { tst_brk_(filename, lineno, TBROK | TTERRNO, "memfd_create() failed"); } return 0; } SAFE_CLOSE(TEST_RETURN); return 1; }
int check_mfd_new(const char *filename, const int lineno, const char *name, loff_t sz, int flags) { int fd; fd = sys_memfd_create(name, flags); if (fd < 0) { tst_brk_(filename, lineno, TBROK | TERRNO, "memfd_create(%s, %d) failed", name, flags); } tst_res_(filename, lineno, TPASS, "memfd_create(%s, %d) succeeded", name, flags); check_ftruncate(filename, lineno, fd, sz); return fd; }
static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags) { int r, fd; fd = sys_memfd_create(name, flags); if (fd < 0) { printf("memfd_create(\"%s\", %u) failed: %m\n", name, flags); abort(); } r = ftruncate(fd, sz); if (r < 0) { printf("ftruncate(%llu) failed: %m\n", (unsigned long long)sz); abort(); } return fd; }
int get_shmem_fd(int pid, VmaEntry *vi) { struct shmem_info *si; void *addr = MAP_FAILED; int f = -1; int flags; si = find_shmem_by_id(vi->shmid); pr_info("Search for 0x%016"PRIx64" shmem 0x%"PRIx64" %p/%d\n", vi->start, vi->shmid, si, si ? si->pid : -1); if (!si) { pr_err("Can't find my shmem 0x%016"PRIx64"\n", vi->start); return -1; } if (si->pid != pid) return shmem_wait_and_open(pid, si); if (si->fd != -1) return dup(si->fd); flags = MAP_SHARED; if (kdat.has_memfd) { f = sys_memfd_create("", 0); if (f < 0) { pr_perror("Unable to create memfd"); goto err; } if (ftruncate(f, si->size)) { pr_perror("Unable to truncate memfd"); goto err; } flags |= MAP_FILE; } else flags |= MAP_ANONYMOUS; /* * The following hack solves problems: * vi->pgoff may be not zero in a target process. * This mapping may be mapped more then once. * The restorer doesn't have snprintf. * Here is a good place to restore content */ addr = mmap(NULL, si->size, PROT_WRITE | PROT_READ, flags, f, 0); if (addr == MAP_FAILED) { pr_err("Can't mmap shmid=0x%"PRIx64" size=%ld\n", vi->shmid, si->size); goto err; } if (restore_shmem_content(addr, si) < 0) { pr_err("Can't restore shmem content\n"); goto err; } if (f == -1) { f = open_proc_rw(getpid(), "map_files/%lx-%lx", (unsigned long) addr, (unsigned long) addr + si->size); if (f < 0) goto err; } munmap(addr, si->size); si->fd = f; /* Send signal to slaves, that they can open fd for this shmem */ futex_inc_and_wake(&si->lock); /* * All other regions in this process will duplicate * the file descriptor, so we don't wait them. */ futex_wait_until(&si->lock, si->count - si->self_count + 1); return f; err: if (addr != MAP_FAILED) munmap(addr, si->size); close_safe(&f); return -1; }
int kdbus_msg_send(const struct kdbus_conn *conn, const char *name, uint64_t cookie, uint64_t flags, uint64_t timeout, int64_t priority, uint64_t dst_id) { struct kdbus_msg *msg; const char ref1[1024 * 128 + 3] = "0123456789_0"; const char ref2[] = "0123456789_1"; struct kdbus_item *item; uint64_t size; int memfd = -1; int ret; size = sizeof(struct kdbus_msg); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); if (dst_id == KDBUS_DST_ID_BROADCAST) size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64; else { memfd = sys_memfd_create("my-name-is-nice", 1024 * 1024); if (memfd < 0) { kdbus_printf("failed to create memfd: %m\n"); return memfd; } if (write(memfd, "kdbus memfd 1234567", 19) != 19) { ret = -errno; kdbus_printf("writing to memfd failed: %m\n"); return ret; } ret = sys_memfd_seal_set(memfd); if (ret < 0) { ret = -errno; kdbus_printf("memfd sealing failed: %m\n"); return ret; } size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd)); } if (name) size += KDBUS_ITEM_SIZE(strlen(name) + 1); msg = malloc(size); if (!msg) { ret = -errno; kdbus_printf("unable to malloc()!?\n"); return ret; } memset(msg, 0, size); msg->flags = flags; msg->timeout_ns = timeout; msg->priority = priority; msg->size = size; msg->src_id = conn->id; msg->dst_id = name ? 0 : dst_id; msg->cookie = cookie; msg->payload_type = KDBUS_PAYLOAD_DBUS; item = msg->items; if (name) { item->type = KDBUS_ITEM_DST_NAME; item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; strcpy(item->str, name); item = KDBUS_ITEM_NEXT(item); } item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uintptr_t)&ref1; item->vec.size = sizeof(ref1); item = KDBUS_ITEM_NEXT(item); /* data padding for ref1 */ item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uintptr_t)NULL; item->vec.size = KDBUS_ALIGN8(sizeof(ref1)) - sizeof(ref1); item = KDBUS_ITEM_NEXT(item); item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uintptr_t)&ref2; item->vec.size = sizeof(ref2); item = KDBUS_ITEM_NEXT(item); if (dst_id == KDBUS_DST_ID_BROADCAST) { item->type = KDBUS_ITEM_BLOOM_FILTER; item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64; item->bloom_filter.generation = 0; } else { item->type = KDBUS_ITEM_PAYLOAD_MEMFD; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd); item->memfd.size = 16; item->memfd.fd = memfd; } item = KDBUS_ITEM_NEXT(item); ret = ioctl(conn->fd, KDBUS_CMD_MSG_SEND, msg); if (ret < 0) { ret = -errno; kdbus_printf("error sending message: %d (%m)\n", ret); return ret; } if (memfd >= 0) close(memfd); if (flags & KDBUS_MSG_FLAGS_SYNC_REPLY) { struct kdbus_msg *reply; kdbus_printf("SYNC REPLY @offset %llu:\n", msg->offset_reply); reply = (struct kdbus_msg *)(conn->buf + msg->offset_reply); kdbus_msg_dump(conn, reply); ret = kdbus_free(conn, msg->offset_reply); if (ret < 0) return ret; } free(msg); return 0; }