Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/trusty/trusty/user/base/lib/secure_fb/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 9 kB image not shown  

Quelle  secure_fb.c

  Sprache: C
 

/*
 * Copyright 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.
 */


#define TLOG_TAG "secure_fb_ipc"

#include <lib/secure_fb/secure_fb.h>

#include <assert.h>
#include <inttypes.h>
#include <lib/tipc/tipc.h>
#include <lk/compiler.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <trusty_ipc.h>
#include <trusty_log.h>
#include <uapi/err.h>

struct secure_fb_session {
    handle_t chan;
    size_t next_fb;
    size_t num_fbs;
    struct secure_fb_desc fbs[SECURE_FB_MAX_FBS];
};

static struct secure_fb_session* new_secure_fb_session(void) {
    struct secure_fb_session* s = calloc(1sizeof(*s));
    if (s == NULL) {
        return NULL;
    }

    s->chan = INVALID_IPC_HANDLE;
    return s;
}

static void free_secure_fb_session(struct secure_fb_session* s) {
    for (size_t i = 0; i < SECURE_FB_MAX_FBS; ++i) {
        uint8_t** buffer = &s->fbs[i].fb_info.buffer;
        if (*buffer) {
            int rc = munmap(*buffer, s->fbs[i].fb_info.size);
            if (rc != NO_ERROR) {
                TLOGW("munmap() failed: %d\n", rc);
            }
            *buffer = NULL;
        }
    }
    free(s);
}

static struct secure_fb_session* new_connected_session(uint32_t idx) {
    char port_name[SECURE_FB_MAX_PORT_NAME_SIZE] = {0};
    struct secure_fb_session* s;
    int rc;

    if (idx >= SECURE_FB_MAX_INST) {
        TLOGE("Invalid index %" PRIu32 "\n", idx);
        return NULL;
    }

    int n = snprintf(port_name, sizeof(port_name), "%s.%d", SECURE_FB_PORT_NAME,
                     idx);
    if (n != SECURE_FB_MAX_PORT_NAME_SIZE - 1) {
        TLOGE("Failed to create port name\n");
        return NULL;
    }

    s = new_secure_fb_session();
    if (s == NULL) {
        TLOGE("Failed to create session\n");
        return NULL;
    }

    rc = tipc_connect(&s->chan, port_name);
    if (rc != NO_ERROR) {
        TLOGE("Failed to connect to \"%s_%d\" (%d)\n", SECURE_FB_PORT_NAME, idx,
              rc);
        free_secure_fb_session(s);
        return NULL;
    }

    return s;
}

static void free_connected_session(struct secure_fb_session* s) {
    if (s->chan != INVALID_IPC_HANDLE) {
        close(s->chan);
    }
    free_secure_fb_session(s);
}

static int await_resp(handle_t chan, struct ipc_msg* msg) {
    int rc;
    uevent_t event;

    rc = wait(chan, &event, INFINITE_TIME);
    if (rc < 0) {
        TLOGE("Failed to wait for response (%d)\n", rc);
        return rc;
    }

    ipc_msg_info_t msg_info;
    rc = get_msg(chan, &msg_info);
    if (rc != 0) {
        TLOGE("Failed to get_msg (%d)\n", rc);
        return rc;
    }

    rc = read_msg(chan, msg_info.id, 0, msg);
    put_msg(chan, msg_info.id);
    return rc;
}

static int mmap_fbs(struct secure_fb_desc* fbs,
                    size_t num_fbs,
                    handle_t* handles) {
    struct secure_fb_desc* fb;

    for (size_t i = 0; i < num_fbs; i++) {
        fb = &fbs[i];
        fb->fb_info.buffer =
                mmap(NULL, fb->fb_info.size, PROT_READ | PROT_WRITE, 0,
                     handles[fb->handle_index], fb->offset);
        if (fb->fb_info.buffer == MAP_FAILED) {
            goto err;
        }
    }
    return NO_ERROR;

err:
    for (size_t i = 0; i < num_fbs; i++) {
        fb = &fbs[i];
        if (fb->fb_info.buffer) {
            int rc = munmap(fb->fb_info.buffer, fb->fb_info.size);
            if (rc != NO_ERROR) {
                TLOGW("munmap() failed: %d\n", rc);
            }
        }
        memset(fb, 0sizeof(*fb));
    }
    return ERR_BAD_HANDLE;
}

static int handle_get_fbs_resp(struct secure_fb_session* s) {
    int rc;
    struct secure_fb_resp hdr;
    struct secure_fb_get_fbs_resp args;
    struct secure_fb_desc fbs[SECURE_FB_MAX_FBS];
    size_t fbs_len;
    handle_t handles[SECURE_FB_MAX_FBS] = {[0 ... SECURE_FB_MAX_FBS - 1] =
                                                   INVALID_IPC_HANDLE};
    struct iovec iovs[] = {
            {
                    .iov_base = &hdr,
                    .iov_len = sizeof(hdr),
            },
            {
                    .iov_base = &args,
                    .iov_len = sizeof(args),
            },
            {
                    .iov_base = fbs,
                    .iov_len = sizeof(fbs),
            },
    };
    struct ipc_msg msg = {
            .num_iov = countof(iovs),
            .iov = iovs,
            .num_handles = SECURE_FB_MAX_FBS,
            .handles = handles,
    };

    rc = await_resp(s->chan, &msg);
    if (rc < 0) {
        return rc;
    }

    if (rc < (int)(sizeof(hdr) + sizeof(args))) {
        return ERR_BAD_LEN;
    }

    fbs_len = sizeof(fbs[0]) * args.num_fbs;

    if (rc != (int)(sizeof(hdr) + sizeof(args) + fbs_len)) {
        if (rc >= 0) {
            return ERR_BAD_LEN;
        }
        return rc;
    }

    if (hdr.cmd != (SECURE_FB_CMD_GET_FBS | SECURE_FB_CMD_RESP_BIT)) {
        return ERR_CMD_UNKNOWN;
    }

    if (hdr.status != SECURE_FB_ERROR_OK) {
        TLOGE("Failed SECURE_FB_CMD_DISPLAY_FB request (%d)\n", hdr.status);
        return ERR_GENERIC;
    }

    rc = mmap_fbs(fbs, args.num_fbs, handles);
    /* Close all received handles. We don't need to keep them around. */
    for (size_t i = 0; i < SECURE_FB_MAX_FBS; ++i) {
        if (handles[i] != INVALID_IPC_HANDLE) {
            close(handles[i]);
        }
    }

    if (rc != NO_ERROR) {
        TLOGE("Failed to mmap() framebuffers (%d)\n", hdr.status);
        return rc;
    }

    for (size_t i = 0; i < (size_t)args.num_fbs; ++i) {
        s->fbs[i] = fbs[i];
    }
    s->num_fbs = args.num_fbs;
    s->next_fb = 0;
    return NO_ERROR;
}

static int get_fbs(struct secure_fb_session* s) {
    int rc;
    struct secure_fb_req req;

    assert(s->chan != INVALID_IPC_HANDLE);

    req.cmd = SECURE_FB_CMD_GET_FBS;
    rc = tipc_send1(s->chan, &req, sizeof(req));
    if (rc != (int)sizeof(req)) {
        TLOGE("Failed to send SECURE_FB_CMD_GET_FBS request (%d)\n", rc);
        if (rc >= 0) {
            rc = ERR_BAD_LEN;
        }
        return rc;
    }

    return handle_get_fbs_resp(s);
}

static int handle_display_fb_resp(handle_t chan) {
    int rc;
    struct uevent evt;
    struct secure_fb_resp hdr;

    rc = wait(chan, &evt, INFINITE_TIME);
    if (rc != NO_ERROR) {
        TLOGE("Error waiting for response (%d)\n", rc);
        return rc;
    }

    rc = tipc_recv1(chan, sizeof(hdr), &hdr, sizeof(hdr));
    if (rc < 0) {
        TLOGE("Failed to receive SECURE_FB_CMD_DISPLAY_FB response (%d)\n", rc);
        return rc;
    }

    if (hdr.cmd != (SECURE_FB_CMD_DISPLAY_FB | SECURE_FB_CMD_RESP_BIT)) {
        return ERR_CMD_UNKNOWN;
    }

    if (hdr.status != SECURE_FB_ERROR_OK) {
        TLOGE("Failed SECURE_FB_CMD_DISPLAY_FB (%d)\n", hdr.status);
        return ERR_GENERIC;
    }

    return NO_ERROR;
}

static int display_fb(handle_t chan, uint32_t buffer_id) {
    int rc;
    struct secure_fb_req hdr;
    struct secure_fb_display_fb_req args;

    hdr.cmd = SECURE_FB_CMD_DISPLAY_FB;
    args.buffer_id = buffer_id;

    rc = tipc_send2(chan, &hdr, sizeof(hdr), &args, sizeof(args));
    if (rc != (int)(sizeof(hdr) + sizeof(args))) {
        TLOGE("Failed to send SECURE_FB_CMD_DISPLAY_FB request (%d)\n", rc);
        return rc;
    }

    return handle_display_fb_resp(chan);
}

secure_fb_error secure_fb_open(secure_fb_handle_t* session,
                               struct secure_fb_info* fb_info,
                               uint32_t idx) {
    int rc;
    struct secure_fb_session* s;

    if (!session) {
        return TTUI_ERROR_UNEXPECTED_NULL_PTR;
    }

    s = new_connected_session(idx);
    if (s == NULL) {
        return TTUI_ERROR_NO_SERVICE;
    }

    rc = get_fbs(s);
    if (rc != NO_ERROR) {
        free_connected_session(s);
        return TTUI_ERROR_MEMORY_ALLOCATION_FAILED;
    }

    *fb_info = s->fbs[s->next_fb].fb_info;
    *session = (secure_fb_handle_t)s;
    return TTUI_ERROR_OK;
}

secure_fb_error secure_fb_display_next(secure_fb_handle_t session,
                                       struct secure_fb_info* fb_info) {
    int rc;
    uint32_t buffer_id;
    struct secure_fb_session* s = (struct secure_fb_session*)session;

    if (!fb_info || !s) {
        return TTUI_ERROR_UNEXPECTED_NULL_PTR;
    }

    buffer_id = s->fbs[s->next_fb].buffer_id;
    rc = display_fb(s->chan, buffer_id);
    if (rc != NO_ERROR) {
        return TTUI_ERROR_NO_FRAMEBUFFER;
    }

    s->next_fb = (s->next_fb + 1) % s->num_fbs;
    *fb_info = s->fbs[s->next_fb].fb_info;
    return TTUI_ERROR_OK;
}

void secure_fb_close(secure_fb_handle_t session) {
    int rc;
    struct secure_fb_req req;
    struct secure_fb_session* s = (struct secure_fb_session*)session;

    if (!s || s->chan == INVALID_IPC_HANDLE) {
        return;
    }

    req.cmd = SECURE_FB_CMD_RELEASE;
    rc = tipc_send1(s->chan, &req, sizeof(req));
    if (rc != (int)sizeof(req)) {
        TLOGE("Failed to send SECURE_FB_CMD_RELEASE request (%d)\n", rc);
    }

    free_connected_session(s);
}

Messung V0.5 in Prozent
C=98 H=95 G=96

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.