Add support for tipc_send()
* Supports sending memfds in addition to data from an iovec * Also add a basic test called send-fd Bug: 117221195 Test: Run send-fd with corresponding Trusty application. Change-Id: I562d2ff744938c868323a016659ca1332f6a576b
This commit is contained in:
parent
e4424ff422
commit
e251fa32fd
5 changed files with 188 additions and 52 deletions
77
trusty/libtrusty/include/trusty/ipc.h
Normal file
77
trusty/libtrusty/include/trusty/ipc.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _UAPI_LINUX_TRUSTY_IPC_H_
|
||||
#define _UAPI_LINUX_TRUSTY_IPC_H_
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uio.h>
|
||||
|
||||
/**
|
||||
* enum transfer_kind - How to send an fd to Trusty
|
||||
* @TRUSTY_SHARE: Memory will be accessible by Linux and Trusty. On ARM it will
|
||||
* be mapped as nonsecure. Suitable for shared memory. The paired
|
||||
* fd must be a "memfd".
|
||||
* @TRUSTY_LEND: Memory will be accessible only to Trusty. On ARM it will be
|
||||
* transitioned to "Secure" memory if Trusty is in TrustZone.
|
||||
* This transfer kind is suitable for donating video buffers or
|
||||
* other similar resources. The paired fd may need to come from a
|
||||
* platform-specific allocator for memory that may be
|
||||
* transitioned to "Secure".
|
||||
*
|
||||
* Describes how the user would like the resource in question to be sent to
|
||||
* Trusty. Options may be valid only for certain kinds of fds.
|
||||
*/
|
||||
enum transfer_kind {
|
||||
TRUSTY_SHARE = 0,
|
||||
TRUSTY_LEND = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct trusty_shm - Describes a transfer of memory to Trusty
|
||||
* @fd: The fd to transfer
|
||||
* @transfer: How to transfer it - see &enum transfer_kind
|
||||
*/
|
||||
struct trusty_shm {
|
||||
__s32 fd;
|
||||
__u32 transfer;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tipc_send_msg_req - Request struct for @TIPC_IOC_SEND_MSG
|
||||
* @iov: Pointer to an array of &struct iovec describing data to be sent
|
||||
* @shm: Pointer to an array of &struct trusty_shm describing any file
|
||||
* descriptors to be transferred.
|
||||
* @iov_cnt: Number of elements in the @iov array
|
||||
* @shm_cnt: Number of elements in the @shm array
|
||||
*/
|
||||
struct tipc_send_msg_req {
|
||||
__u64 iov;
|
||||
__u64 shm;
|
||||
__u64 iov_cnt;
|
||||
__u64 shm_cnt;
|
||||
};
|
||||
|
||||
#define TIPC_IOC_MAGIC 'r'
|
||||
#define TIPC_IOC_CONNECT _IOW(TIPC_IOC_MAGIC, 0x80, char*)
|
||||
#define TIPC_IOC_SEND_MSG _IOW(TIPC_IOC_MAGIC, 0x81, struct tipc_send_msg_req)
|
||||
|
||||
#if defined(CONFIG_COMPAT)
|
||||
#define TIPC_IOC_CONNECT_COMPAT _IOW(TIPC_IOC_MAGIC, 0x80, compat_uptr_t)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -21,7 +21,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/uio.h>
|
||||
#include <trusty/ipc.h>
|
||||
|
||||
int tipc_connect(const char *dev_name, const char *srv_name);
|
||||
ssize_t tipc_send(int fd, const struct iovec* iov, int iovcnt, struct trusty_shm* shm, int shmcnt);
|
||||
int tipc_close(int fd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#define __USE_GNU
|
||||
#include <sys/mman.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <trusty/tipc.h>
|
||||
|
|
@ -39,6 +41,7 @@ static const char *closer1_name = "com.android.ipc-unittest.srv.closer1";
|
|||
static const char *closer2_name = "com.android.ipc-unittest.srv.closer2";
|
||||
static const char *closer3_name = "com.android.ipc-unittest.srv.closer3";
|
||||
static const char *main_ctrl_name = "com.android.ipc-unittest.ctrl";
|
||||
static const char* receiver_name = "com.android.trusty.memref.receiver";
|
||||
|
||||
static const char *_sopts = "hsvD:t:r:m:b:";
|
||||
static const struct option _lopts[] = {
|
||||
|
|
@ -66,25 +69,25 @@ static const char *usage =
|
|||
"\n"
|
||||
;
|
||||
|
||||
static const char *usage_long =
|
||||
"\n"
|
||||
"The following tests are available:\n"
|
||||
" connect - connect to datasink service\n"
|
||||
" connect_foo - connect to non existing service\n"
|
||||
" burst_write - send messages to datasink service\n"
|
||||
" echo - send/receive messages to echo service\n"
|
||||
" select - test select call\n"
|
||||
" blocked_read - test blocked read\n"
|
||||
" closer1 - connection closed by remote (test1)\n"
|
||||
" closer2 - connection closed by remote (test2)\n"
|
||||
" closer3 - connection closed by remote (test3)\n"
|
||||
" ta2ta-ipc - execute TA to TA unittest\n"
|
||||
" dev-uuid - print device uuid\n"
|
||||
" ta-access - test ta-access flags\n"
|
||||
" writev - writev test\n"
|
||||
" readv - readv test\n"
|
||||
"\n"
|
||||
;
|
||||
static const char* usage_long =
|
||||
"\n"
|
||||
"The following tests are available:\n"
|
||||
" connect - connect to datasink service\n"
|
||||
" connect_foo - connect to non existing service\n"
|
||||
" burst_write - send messages to datasink service\n"
|
||||
" echo - send/receive messages to echo service\n"
|
||||
" select - test select call\n"
|
||||
" blocked_read - test blocked read\n"
|
||||
" closer1 - connection closed by remote (test1)\n"
|
||||
" closer2 - connection closed by remote (test2)\n"
|
||||
" closer3 - connection closed by remote (test3)\n"
|
||||
" ta2ta-ipc - execute TA to TA unittest\n"
|
||||
" dev-uuid - print device uuid\n"
|
||||
" ta-access - test ta-access flags\n"
|
||||
" writev - writev test\n"
|
||||
" readv - readv test\n"
|
||||
" send-fd - transmit memfd to trusty, use as shm\n"
|
||||
"\n";
|
||||
|
||||
static uint opt_repeat = 1;
|
||||
static uint opt_msgsize = 32;
|
||||
|
|
@ -885,6 +888,66 @@ static int readv_test(uint repeat, uint msgsz, bool var)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int send_fd_test(void) {
|
||||
int ret;
|
||||
int memfd = -1;
|
||||
int fd = -1;
|
||||
volatile char* buf = MAP_FAILED;
|
||||
|
||||
fd = tipc_connect(dev_name, receiver_name);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Failed to connect to test support TA - is it missing?\n");
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memfd = memfd_create("tipc-send-fd", 0);
|
||||
if (memfd < 0) {
|
||||
fprintf(stderr, "Failed to create memfd: %s\n", strerror(errno));
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ftruncate(memfd, PAGE_SIZE) < 0) {
|
||||
fprintf(stderr, "Failed to resize memfd: %s\n", strerror(errno));
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
buf = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0);
|
||||
if (buf == MAP_FAILED) {
|
||||
fprintf(stderr, "Failed to map memfd: %s\n", strerror(errno));
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
strcpy((char*)buf, "From NS");
|
||||
|
||||
struct trusty_shm shm = {
|
||||
.fd = memfd,
|
||||
.transfer = TRUSTY_SHARE,
|
||||
};
|
||||
|
||||
ssize_t rc = tipc_send(fd, NULL, 0, &shm, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "tipc_send failed\n");
|
||||
ret = rc;
|
||||
goto cleanup;
|
||||
}
|
||||
char c;
|
||||
read(fd, &c, 1);
|
||||
tipc_close(fd);
|
||||
|
||||
ret = strcmp("Hello from Trusty!", (const char*)buf) ? (-1) : 0;
|
||||
|
||||
cleanup:
|
||||
if (buf != MAP_FAILED) {
|
||||
munmap((char*)buf, PAGE_SIZE);
|
||||
}
|
||||
close(memfd);
|
||||
tipc_close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
|
@ -933,10 +996,12 @@ int main(int argc, char **argv)
|
|||
rc = writev_test(opt_repeat, opt_msgsize, opt_variable);
|
||||
} else if (strcmp(test_name, "readv") == 0) {
|
||||
rc = readv_test(opt_repeat, opt_msgsize, opt_variable);
|
||||
} else {
|
||||
fprintf(stderr, "Unrecognized test name '%s'\n", test_name);
|
||||
print_usage_and_exit(argv[0], EXIT_FAILURE, true);
|
||||
}
|
||||
} else if (strcmp(test_name, "send-fd") == 0) {
|
||||
rc = send_fd_test();
|
||||
} else {
|
||||
fprintf(stderr, "Unrecognized test name '%s'\n", test_name);
|
||||
print_usage_and_exit(argv[0], EXIT_FAILURE, true);
|
||||
}
|
||||
|
||||
return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _TIPC_IOCTL_H
|
||||
#define _TIPC_IOCTL_H
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define TIPC_IOC_MAGIC 'r'
|
||||
#define TIPC_IOC_CONNECT _IOW(TIPC_IOC_MAGIC, 0x80, char *)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include <log/log.h>
|
||||
|
||||
#include "tipc_ioctl.h"
|
||||
#include <trusty/ipc.h>
|
||||
|
||||
int tipc_connect(const char *dev_name, const char *srv_name)
|
||||
{
|
||||
|
|
@ -55,6 +55,22 @@ int tipc_connect(const char *dev_name, const char *srv_name)
|
|||
return fd;
|
||||
}
|
||||
|
||||
ssize_t tipc_send(int fd, const struct iovec* iov, int iovcnt, struct trusty_shm* shms,
|
||||
int shmcnt) {
|
||||
struct tipc_send_msg_req req;
|
||||
req.iov = (__u64)iov;
|
||||
req.iov_cnt = (__u64)iovcnt;
|
||||
req.shm = (__u64)shms;
|
||||
req.shm_cnt = (__u64)shmcnt;
|
||||
|
||||
int rc = ioctl(fd, TIPC_IOC_SEND_MSG, &req);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: failed to send message (err=%d)\n", __func__, rc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void tipc_close(int fd)
|
||||
{
|
||||
close(fd);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue