1 /*
2 * Copyright (c) 2016, Linaro Limited
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <errno.h>
29 #include <stdint.h>
30 #include <stdio.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <tee_client_api.h>
36 #include <tee_supplicant.h>
37 #include "prof.h"
38
39 #ifndef __aligned
40 #define __aligned(x) __attribute__((__aligned__(x)))
41 #endif
42 #include <linux/tee.h>
43
prof_process(size_t num_params,struct tee_ioctl_param * params,const char * prefix)44 TEEC_Result prof_process(size_t num_params, struct tee_ioctl_param *params,
45 const char *prefix)
46 {
47 char vers[5] = "";
48 char path[255] = { 0 };
49 size_t bufsize = 0;
50 TEEC_UUID *u = NULL;
51 int fd = -1;
52 void *buf = NULL;
53 int flags = 0;
54 int id = 0;
55 int st = 0;
56 int n = 0;
57
58 if (num_params != 3 ||
59 (params[0].attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) !=
60 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT ||
61 (params[1].attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) !=
62 TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT ||
63 (params[2].attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) !=
64 TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
65 return TEEC_ERROR_BAD_PARAMETERS;
66
67 id = params[0].a;
68
69 if (MEMREF_SIZE(params + 1) != sizeof(TEEC_UUID))
70 return TEEC_ERROR_BAD_PARAMETERS;
71
72 u = tee_supp_param_to_va(params + 1);
73 if (!u)
74 return TEEC_ERROR_BAD_PARAMETERS;
75
76 buf = tee_supp_param_to_va(params + 2);
77 if (!buf)
78 return TEEC_ERROR_BAD_PARAMETERS;
79
80 bufsize = MEMREF_SIZE(params + 2);
81
82 if (id < 0 || id > 100)
83 return TEEC_ERROR_BAD_PARAMETERS;
84
85 flags = O_APPEND | O_WRONLY;
86 if (!id) {
87 /* id == 0 means create file */
88 flags |= O_CREAT | O_EXCL;
89 id = 1;
90 }
91
92 for (;;) {
93 if (id > 1) {
94 /*
95 * id == 1 is file 0 (no suffix), id == 2 is file .1
96 * etc.
97 */
98 if (id > 100)
99 id = 100; /* Avoid GCC truncation warning */
100 snprintf(vers, sizeof(vers), ".%d", id - 1);
101 }
102 n = snprintf(path, sizeof(path),
103 "/tmp/%s"
104 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"
105 "%s.out",
106 prefix,
107 u->timeLow, u->timeMid, u->timeHiAndVersion,
108 u->clockSeqAndNode[0], u->clockSeqAndNode[1],
109 u->clockSeqAndNode[2], u->clockSeqAndNode[3],
110 u->clockSeqAndNode[4], u->clockSeqAndNode[5],
111 u->clockSeqAndNode[6], u->clockSeqAndNode[7],
112 vers);
113 if ((n < 0) || (n >= (int)sizeof(path)))
114 break;
115 fd = open(path, flags, 0644);
116 if (fd >= 0) {
117 do {
118 st = write(fd, buf, bufsize);
119 } while (st < 0 && errno == EINTR);
120 close(fd);
121 if (st < 0 || st != (int)bufsize)
122 break;
123 params[0].a = id;
124 goto success;
125 }
126 if (errno != EEXIST)
127 break;
128 if (id++ == 100)
129 break;
130 }
131
132 /* An error occurred */
133 return TEEC_ERROR_GENERIC;
134
135 success:
136 return TEEC_SUCCESS;
137 }
138