From a50046ab69c073fa8b1d84c2bb25e7f2c177a89d Mon Sep 17 00:00:00 2001 From: Alex Markuze Date: Mon, 7 Apr 2025 11:49:37 +0000 Subject: [PATCH] adding des code --- include/linux/ceph/ceph_san_des.h | 22 ++++ include/linux/ceph/ceph_san_logger.h | 1 + net/ceph/Makefile | 2 +- net/ceph/ceph_san_des.c | 162 +++++++++++++++++++++++++++ 4 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 include/linux/ceph/ceph_san_des.h create mode 100644 net/ceph/ceph_san_des.c diff --git a/include/linux/ceph/ceph_san_des.h b/include/linux/ceph/ceph_san_des.h new file mode 100644 index 000000000000..eb9d75957f66 --- /dev/null +++ b/include/linux/ceph/ceph_san_des.h @@ -0,0 +1,22 @@ +#ifndef CEPH_SAN_DES_H +#define CEPH_SAN_DES_H + +#include /* For size_t */ + +/** + * Reconstructs a formatted string from a buffer containing serialized values. + * The function uses the format string to determine the types and number of values + * to extract from the buffer. + * + * @param fmt Format string containing % specifiers + * @param buffer Buffer containing serialized values + * @param nr_args Number of arguments to process + * @param size Size of the buffer in bytes + * @param out Buffer to store the reconstructed string + * @param out_size Size of the output buffer + * @return Number of bytes written to out buffer, or -1 on error + */ +int ceph_san_des_reconstruct(const char *fmt, const void *buffer, size_t nr_args, + size_t size, char *out, size_t out_size); + +#endif /* CEPH_SAN_DES_H */ diff --git a/include/linux/ceph/ceph_san_logger.h b/include/linux/ceph/ceph_san_logger.h index 957805fabd7c..0b377119abb9 100644 --- a/include/linux/ceph/ceph_san_logger.h +++ b/include/linux/ceph/ceph_san_logger.h @@ -8,6 +8,7 @@ #include #include #include +#include /* Maximum length of a log entry buffer */ #define CEPH_SAN_LOG_MAX_LEN 256 diff --git a/net/ceph/Makefile b/net/ceph/Makefile index c0766fd8b2cd..be61857dafcb 100644 --- a/net/ceph/Makefile +++ b/net/ceph/Makefile @@ -10,7 +10,7 @@ libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \ striper.o \ debugfs.o \ - ceph_san_pagefrag.o ceph_san_batch.o ceph_san_logger.o \ + ceph_san_pagefrag.o ceph_san_batch.o ceph_san_logger.o ceph_san_des.o \ auth.o auth_none.o \ crypto.o armor.o \ auth_x.o \ diff --git a/net/ceph/ceph_san_des.c b/net/ceph/ceph_san_des.c new file mode 100644 index 000000000000..b37ae7c849c5 --- /dev/null +++ b/net/ceph/ceph_san_des.c @@ -0,0 +1,162 @@ +#include +#include /* For strchr, strlen */ +#include /* For isdigit */ +#include /* For size_t */ +#include /* For snprintf */ + +static int parse_format_specifier(const char **fmt, char *spec) { + const char *p = *fmt; + char *s = spec; + + /* Skip the '%' */ + if (*p != '%') return -1; + *s++ = *p++; + + /* Skip flags */ + while (*p && (*p == '-' || *p == '+' || *p == ' ' || *p == '#' || *p == '0')) { + *s++ = *p++; + } + + /* Skip field width */ + while (*p && isdigit(*p)) { + *s++ = *p++; + } + + /* Skip precision */ + if (*p == '.') { + *s++ = *p++; + while (*p && isdigit(*p)) { + *s++ = *p++; + } + } + + /* Get length modifier */ + if (*p == 'h' || *p == 'l' || *p == 'L' || *p == 'j' || *p == 'z' || *p == 't') { + *s++ = *p++; + if ((*p == 'h' || *p == 'l') && *(p-1) == *p) { + *s++ = *p++; + } + } + + /* Get conversion specifier */ + if (*p && strchr("diouxXeEfFgGaAcspn%", *p)) { + *s++ = *p++; + } else { + return -1; + } + + *s = '\0'; + *fmt = p; + return 0; +} + +int ceph_san_des_reconstruct(const char *fmt, const void *buffer, size_t nr_args, + size_t size, char *out, size_t out_size) { + const unsigned char *buf = buffer; + const char *p = fmt; + char spec[32]; + size_t offset = 0; + size_t out_offset = 0; + size_t arg_count = 0; + + if (!fmt || !buffer || !out || !out_size) { + return -1; + } + //printf("Starting reconstruction with buffer at %p, size %zu, nr_args %zu, out_size %zu\n", + // buffer, size, nr_args, out_size); + while (*p && out_offset < out_size - 1) { + if (*p != '%') { + out[out_offset++] = *p++; + continue; + } + + if (parse_format_specifier(&p, spec) < 0) { + return -1; + } + + if (arg_count >= nr_args) { + return -1; + } + + /* Check buffer overflow */ + if (offset >= size) { + return -1; + } + + //printf("Processing specifier '%s' at offset %zu\n", spec, offset); + + /* Handle different format specifiers */ + switch (spec[strlen(spec)-1]) { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': { + long long val; + const void *ptr = buf + offset; + if (strchr(spec, 'l')) { + val = *(const long long*)ptr; + offset += sizeof(long long); + } else { + val = *(const int*)ptr; + offset += sizeof(int); + } + //printf("Read integer value: %lld at address %p (offset %zu)\n", val, ptr, offset); + out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val); + break; + } + + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + case 'a': + case 'A': { + double val = *(const double*)(buf + offset); + offset += sizeof(double); + //printf("Read double value: %f at offset %zu\n", val, offset - sizeof(double)); + out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val); + break; + } + + case 'c': { + char val = *(const char*)(buf + offset); + offset += sizeof(char); + //printf("Read char value: %c at offset %zu\n", val, offset - sizeof(char)); + out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val); + break; + } + + case 's': { + const char *val = *(const char**)(buf + offset); + offset += sizeof(const char*); + //printf("Read string pointer: %p at offset %zu\n", val, offset - sizeof(const char*)); + out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val); + break; + } + + case 'p': { + const void *val = *(const void**)(buf + offset); + offset += sizeof(const void*); + //printf("Read pointer value: %p at offset %zu\n", val, offset - sizeof(const void*)); + out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val); + break; + } + + case '%': { + out[out_offset++] = '%'; + break; + } + + default: + return -1; + } + + arg_count++; + } + + out[out_offset] = '\0'; + return out_offset; +} -- 2.47.3