/* * Copyright (c) 2016, Linaro Limited * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include "prof.h" #ifndef __aligned #define __aligned(x) __attribute__((__aligned__(x))) #endif #include TEEC_Result prof_process(size_t num_params, struct tee_ioctl_param *params, const char *prefix) { char vers[5] = ""; char path[255] = { 0 }; size_t bufsize = 0; TEEC_UUID *u = NULL; int fd = -1; void *buf = NULL; int flags = 0; int id = 0; int st = 0; int n = 0; if (num_params != 3 || (params[0].attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT || (params[1].attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT || (params[2].attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT) return TEEC_ERROR_BAD_PARAMETERS; id = params[0].a; if (MEMREF_SIZE(params + 1) != sizeof(TEEC_UUID)) return TEEC_ERROR_BAD_PARAMETERS; u = tee_supp_param_to_va(params + 1); if (!u) return TEEC_ERROR_BAD_PARAMETERS; buf = tee_supp_param_to_va(params + 2); if (!buf) return TEEC_ERROR_BAD_PARAMETERS; bufsize = MEMREF_SIZE(params + 2); if (id < 0 || id > 100) return TEEC_ERROR_BAD_PARAMETERS; flags = O_APPEND | O_WRONLY; if (!id) { /* id == 0 means create file */ flags |= O_CREAT | O_EXCL; id = 1; } for (;;) { if (id > 1) { /* * id == 1 is file 0 (no suffix), id == 2 is file .1 * etc. */ if (id > 100) id = 100; /* Avoid GCC truncation warning */ snprintf(vers, sizeof(vers), ".%d", id - 1); } n = snprintf(path, sizeof(path), "/tmp/%s" "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" "%s.out", prefix, u->timeLow, u->timeMid, u->timeHiAndVersion, u->clockSeqAndNode[0], u->clockSeqAndNode[1], u->clockSeqAndNode[2], u->clockSeqAndNode[3], u->clockSeqAndNode[4], u->clockSeqAndNode[5], u->clockSeqAndNode[6], u->clockSeqAndNode[7], vers); if ((n < 0) || (n >= (int)sizeof(path))) break; fd = open(path, flags, 0644); if (fd >= 0) { do { st = write(fd, buf, bufsize); } while (st < 0 && errno == EINTR); close(fd); if (st < 0 || st != (int)bufsize) break; params[0].a = id; goto success; } if (errno != EEXIST) break; if (id++ == 100) break; } /* An error occurred */ return TEEC_ERROR_GENERIC; success: return TEEC_SUCCESS; }