Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ option(BUILD_GPFS_LISTENER "Build GP File system Listener" TRUE)
option(USE_GLIB "Use GLIB functions" FALSE)
# Use pkg-config for discovering install target directory
option(CFG_USE_PKGCONFIG "Use pkg-config for discovering install target directory for systemd and udev files." OFF)
# Build GPT listener
option(BUILD_GPT_LISTENER "Build GPT Listener" TRUE)
# Build RPMB listener
option(BUILD_RPMB_LISTENER "Build RPMB Listener" TRUE)

include(GNUInstallDirs)

Expand Down Expand Up @@ -60,3 +64,11 @@ endif()
if(BUILD_FS_LISTENER OR BUILD_GPFS_LISTENER)
add_subdirectory(listeners/libfsservice)
endif()

if(BUILD_GPT_LISTENER)
add_subdirectory(listeners/libgptservice)
endif()

if(BUILD_RPMB_LISTENER)
add_subdirectory(listeners/librpmbservice)
endif()
43 changes: 43 additions & 0 deletions listeners/libgptservice/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
project(libgptservice
VERSION 1.0.0
LANGUAGES C
)

add_compile_options(
-Wstrict-prototypes -Wmissing-prototypes -Wbad-function-cast
)

# Source files
set(SRC
../listenercbo/src/CListenerCBO.c
../listenercbo/src/memscpy.h
gpt_service.c
gpt_msg.h
gpt_logging.c
)

add_library(gptservice SHARED ${SRC})

# Library version
set_target_properties(gptservice PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
)

# Add dependency on listenercbo for MINK IPC headers
add_dependencies(gptservice listenercbo_MINKHEADERS)

target_include_directories(gptservice
PRIVATE ../listenercbo/include
PRIVATE ../listenercbo/idl
PRIVATE ${CMAKE_SOURCE_DIR}/libminkadaptor/include
)

target_link_libraries(gptservice
PRIVATE minkadaptor
)

# Install the shared library
install(TARGETS gptservice
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
211 changes: 211 additions & 0 deletions listeners/libgptservice/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# GPT Service for MINK IPC Framework

## Overview

The GPT (GUID Partition Table) service is a secure listener service for the MINK IPC framework that provides GPT partition management capabilities to QTEE (Qualcomm Trusted Execution Environment) applications. This service allows trusted applications to securely read, verify, and manage GPT partition tables on storage devices.

## Features

The GPT service provides the following capabilities:

### Core GPT Operations
- **Read GPT Header**: Read and parse GPT header information from storage devices
- **Write GPT Header**: Write updated GPT header information (with proper validation)
- **Read Partition Table**: Read the complete partition table entries
- **Get Partition Info**: Retrieve detailed information about specific partitions
- **Verify Integrity**: Validate GPT header and partition table integrity using CRC32 checksums
- **Get Disk Info**: Retrieve disk geometry and basic information

### Security Features
- Runs in the secure QTEE environment through MINK IPC
- Validates GPT signatures and checksums
- Provides secure access to partition information
- Supports both primary and backup GPT verification

## Architecture

```
┌─────────────────┐ MINK IPC ┌─────────────────┐
│ QTEE App │◄──────────────►│ GPT Service │
│ │ │ (REE Listener) │
└─────────────────┘ └─────────────────┘
┌─────────────────┐
│ Block Device │
│ (/dev/sdX) │
└─────────────────┘
```

## Message Protocol

The service uses a command-response protocol with the following message types:

### Commands
- `TZ_GPT_MSG_CMD_GPT_READ_HEADER` - Read GPT header
- `TZ_GPT_MSG_CMD_GPT_WRITE_HEADER` - Write GPT header
- `TZ_GPT_MSG_CMD_GPT_READ_PARTITION_TABLE` - Read partition table
- `TZ_GPT_MSG_CMD_GPT_GET_PARTITION_INFO` - Get partition information
- `TZ_GPT_MSG_CMD_GPT_VERIFY_INTEGRITY` - Verify GPT integrity
- `TZ_GPT_MSG_CMD_GPT_GET_DISK_INFO` - Get disk information
- `TZ_GPT_MSG_CMD_GPT_END` - End service session

### Data Structures

#### GPT Header (`tz_gpt_header_t`)
Contains standard GPT header fields including:
- GPT signature ("EFI PART")
- Revision and header size
- Current and backup LBA locations
- Usable LBA range
- Disk GUID
- Partition table location and size

#### Partition Entry (`tz_gpt_partition_entry_t`)
Standard GPT partition entry with:
- Partition type GUID
- Unique partition GUID
- Starting and ending LBA
- Partition attributes
- Partition name (UTF-16)

#### Partition Info (`tz_gpt_partition_info_t`)
Simplified partition information for userspace:
- Partition name (UTF-8)
- Type and unique GUIDs
- LBA range and size in bytes
- Attributes and index

## Building

The GPT service is built as part of the MINK IPC framework:

```bash
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=CMakeToolchain.txt -DBUILD_GPT_LISTENER=ON
cmake --build . --target install --config Release
```

### Dependencies

#### zlib (for CRC32 calculations)
- **Ubuntu/Debian**: `sudo apt-get install zlib1g-dev`
- **Fedora/RHEL**: `sudo yum install zlib-devel`
- **Source**: https://github.com/madler/zlib
- **Cross-compile**: Available in most cross-compilation toolchains (e.g., Yocto SDK)

#### uuid (for GUID operations)
- **Ubuntu/Debian**: `sudo apt-get install uuid-dev`
- **Fedora/RHEL**: `sudo yum install libuuid-devel`
- **Source**: Part of util-linux: https://github.com/util-linux/util-linux
- **Cross-compile**: Available in most cross-compilation toolchains (e.g., Yocto SDK)

#### For Yocto/OpenEmbedded builds:
Add to your recipe's `DEPENDS`:
```
DEPENDS += "zlib util-linux"
```

### Block Device Requirements

The GPT service operates on standard Linux block devices that contain GPT partition tables:

#### Supported Block Devices:
- **eMMC devices**: `/dev/mmcblk0`, `/dev/mmcblk1`, etc.
- **UFS devices**: `/dev/sda`, `/dev/sdb`, etc. (via SCSI/UFS subsystem)
- **NVMe devices**: `/dev/nvme0n1`, etc.

#### Device Access:
- The service requires read access to the block device
- Write operations (if enabled) require write permissions
- Typically requires root or appropriate udev rules for access

#### Kernel Requirements:
- Block device support must be enabled in the kernel
- For eMMC: `CONFIG_MMC_BLOCK`
- For UFS: `CONFIG_SCSI_UFSHCD`
- GPT partition support: `CONFIG_PARTITION_ADVANCED` and `CONFIG_EFI_PARTITION`

#### Example Device Paths:
- **Qualcomm platforms with eMMC**: `/dev/mmcblk0` (main storage)
- **Qualcomm platforms with UFS**: `/dev/sda` or `/dev/disk/by-partlabel/...`

The service validates device paths and checks for GPT signatures before performing operations.

## Usage

### Service Registration
The GPT service is automatically registered with the QTEE supplicant when `BUILD_GPT_LISTENER` is enabled. The service listens on service ID `0xc` with a 20KB buffer.

### Integration with QTEE Applications
QTEE applications can use the GPT service through the MINK IPC framework:

```c
// Example: Get partition information
tz_gpt_get_partition_info_req_t req;
tz_gpt_get_partition_info_rsp_t rsp;

req.cmd_id = TZ_GPT_MSG_CMD_GPT_GET_PARTITION_INFO;
strncpy(req.device_path, "/dev/mmcblk0", sizeof(req.device_path) - 1);
strncpy(req.partition_name, "system", sizeof(req.partition_name) - 1);

// Send request through MINK IPC
// ... (MINK IPC call)

if (rsp.ret == 0) {
printf("Partition %s: %lu bytes\n",
rsp.partition_info.name,
rsp.partition_info.size_bytes);
}
```

## Security Considerations

### Access Control
- The service runs in the REE (Rich Execution Environment) but is accessed only through the secure QTEE
- QTEE applications must have appropriate permissions to access the GPT service
- Device paths are validated to prevent unauthorized access

### Data Integrity
- All GPT operations include CRC32 validation
- Both primary and backup GPT structures are verified
- Invalid or corrupted GPT data is rejected

### Error Handling
- Comprehensive error checking for all disk operations
- Proper cleanup of file descriptors and memory
- Detailed error reporting through return codes

## Limitations

- Read-only operations are prioritized for security
- Write operations require additional validation
- Limited to GPT-formatted disks (no MBR support)
- Requires appropriate permissions for block device access

## Testing

Testing of the GPT listener service should be performed using a Trusted Application (TA) that invokes the service through QTEE. This ensures proper end-to-end validation of the MINK IPC communication path and service functionality.

## Files

- `gpt_msg.h` - Message protocol definitions
- `gpt_service.c` - Main service implementation
- `gpt_logging.c/h` - Logging utilities
- `CMakeLists.txt` - Build configuration
- `README.md` - This documentation

## Future Enhancements

Potential future improvements include:
- Partition creation and deletion support
- Partition resizing capabilities
- Advanced backup and restore operations
- Support for encrypted partition metadata
- Integration with secure boot verification

## License

Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
SPDX-License-Identifier: BSD-3-Clause-Clear
87 changes: 87 additions & 0 deletions listeners/libgptservice/gpt_logging.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// SPDX-License-Identifier: BSD-3-Clause

/*
* GPT Logging Implementation - Production-Ready Syslog-based Logging
*/

#define _GNU_SOURCE /* For vsyslog */

#include <stdarg.h>
#include <string.h>
#include <stdbool.h>

#include "gpt_logging.h"

/* Global log level - defaults to INFO for production */
gpt_log_level_t g_gpt_log_level = GPT_LOG_LEVEL_INFO;

/* Logging state */
static bool g_log_initialized = false;

void gpt_log_init(const char *ident)
{
if (g_log_initialized) {
return;
}

/* Initialize syslog */
openlog(ident ? ident : "gpt_service", LOG_PID | LOG_CONS, LOG_DAEMON);

g_log_initialized = true;

/* Log initialization message */
syslog(LOG_INFO, "GPT logging initialized");
}

void gpt_log_cleanup(void)
{
if (!g_log_initialized) {
return;
}

syslog(LOG_INFO, "GPT logging cleanup");
closelog();
g_log_initialized = false;
}

void gpt_log(gpt_log_level_t level, const char *format, ...)
{
va_list args;

/* Check if we should log this level */
if (level > g_gpt_log_level) {
return;
}

/* Initialize logging if not done yet */
if (!g_log_initialized) {
gpt_log_init(NULL);
}

/* Log to syslog */
va_start(args, format);
vsyslog(level, format, args);
va_end(args);
}

void gpt_set_log_level(gpt_log_level_t level)
{
/* Validate log level */
if (level != LOG_ERR && level != LOG_WARNING &&
level != LOG_INFO && level != LOG_DEBUG) {
return;
}

g_gpt_log_level = level;

/* Set syslog mask to filter messages */
setlogmask(LOG_UPTO(level));

syslog(LOG_INFO, "GPT log level set to: %d", level);
}

gpt_log_level_t gpt_get_log_level(void)
{
return g_gpt_log_level;
}
Loading
Loading