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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ GTAGS
TAGS
tags
*~
compile_commands.json
.cache/
6 changes: 5 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,11 @@ dnl Update flags
dnl Sets CFLAGS to force optimization and debugging options, which isn't quite kosher
dnl
AM_CPPFLAGS="-D_GNU_SOURCE -I\$(top_srcdir)/src -DLTFS_CONFIG_FILE='\"${sysconfdir}/ltfs.conf\"' -DLTFS_BASE_DIR='\"${prefix}\"'"
AM_CFLAGS="-Wall -Wsign-compare -fsigned-char ${FUSE_MODULE_CFLAGS} ${UUID_MODULE_CFLAGS} ${LIBXML2_MODULE_CFLAGS} ${ICU_MODULE_CFLAGS} ${SNMP_ENABLE} ${SNMP_MODULE_CFLAGS}"
dnl -Wno-unused-parameter: callback signatures (FUSE operations, plugin ops)
dnl must keep parameters they do not use.
dnl -Wno-missing-field-initializers: designated initializers of operation and
dnl option tables intentionally leave the remaining members zeroed.
AM_CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wsign-compare -fsigned-char ${FUSE_MODULE_CFLAGS} ${UUID_MODULE_CFLAGS} ${LIBXML2_MODULE_CFLAGS} ${ICU_MODULE_CFLAGS} ${SNMP_ENABLE} ${SNMP_MODULE_CFLAGS}"

if test "x$use_fast" = "xyes"
then
Expand Down
7 changes: 5 additions & 2 deletions src/libltfs/arch/arch_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ void show_runtime_system_info(void)
ltfsmsg(LTFS_WARN, 17086W);
} else {
memset(kernel_version, 0, sizeof(kernel_version));
read(fd, kernel_version, sizeof(kernel_version));
/* Leave room for the terminator and the arch suffix appended below */
if (read(fd, kernel_version, sizeof(kernel_version) - 16) < 0)
strcpy(kernel_version, "(unknown)");
if((tmp = strchr(kernel_version, '\n')) != NULL)
*tmp = '\0';

Expand Down Expand Up @@ -118,7 +120,8 @@ void show_runtime_system_info(void)
} else {
if (fstat(fd, &stat_rel) != -1 && S_ISREG(stat_rel.st_mode)) {
memset(destribution, 0, sizeof(destribution));
read(fd, destribution, sizeof(destribution));
if (read(fd, destribution, sizeof(destribution) - 1) < 0)
strcpy(destribution, "(unknown)");
if((tmp = strchr(destribution, '\n')) != NULL)
*tmp = '\0';
ltfsmsg(LTFS_INFO, 17089I, destribution);
Expand Down
12 changes: 7 additions & 5 deletions src/libltfs/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,9 @@ uint64_t fs_allocate_uid(struct ltfs_index *idx)
int fs_dentry_lookup(struct dentry *dentry, char **name)
{
char **dentry_names = NULL, *tmp_name = NULL;
int i, names, namelen = 0, ret = 0;
int ret = 0;
ssize_t i;
size_t names, namelen = 0;
struct dentry *d, *parent;
const char *lookup_name;

Expand All @@ -447,7 +449,7 @@ int fs_dentry_lookup(struct dentry *dentry, char **name)

d = dentry;
parent = d->parent;
for (i=names-1; i>=0; --i) {
for (i = (ssize_t)names - 1; i >= 0; --i) {
if (parent)
acquireread_mrsw(&parent->contents_lock);

Expand Down Expand Up @@ -483,9 +485,9 @@ int fs_dentry_lookup(struct dentry *dentry, char **name)
goto out;
}

for (namelen=0, i=0; i<names; ++i) {
for (namelen=0, i=0; i < (ssize_t)names; ++i) {
arch_strcat(tmp_name,tmp_len, dentry_names[i]);
if (i > 0 && i < names-1)
if (i > 0 && i < (ssize_t)names-1)
arch_strcat(tmp_name, tmp_len, "/");
}

Expand All @@ -496,7 +498,7 @@ int fs_dentry_lookup(struct dentry *dentry, char **name)
if (ret != 0 && tmp_name)
free(tmp_name);
if (dentry_names) { /* BEAM: constant condition - dentry_names has always non-zero value here. */
while (--names >= 0)
while (names-- > 0)
if (dentry_names[names])
free(dentry_names[names]);
free(dentry_names);
Expand Down
6 changes: 4 additions & 2 deletions src/libltfs/ltfs_fsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -2067,14 +2067,16 @@ int ltfs_fsops_target_absolute_path(const char* link, const char* target, char*
len -= strlen(temp_buf); /* length of "/aaa" */
} else if (strcmp(token, "." )) { /* have directory name */
work_buf[len] = '/'; /* put '/ 'as "/aaa/" */
arch_strncpy(work_buf+len+1, token, work_buf_len, strlen(token)); /* "/aaa/ccc\0" */
memcpy(work_buf+len+1, token, strlen(token)); /* "/aaa/ccc\0" */
work_buf[len+1+strlen(token)] = '\0';
len = strlen(work_buf);
}
token = next_token;
}
work_buf[len] = '/'; /* put '/ 'as "/aaa/ccc/" */
if(token){
arch_strncpy(work_buf+len+1, token, work_buf_len, strlen(token)); /* "/aaa/ccc/target.txt\0" */
memcpy(work_buf+len+1, token, strlen(token)); /* "/aaa/ccc/target.txt\0" */
work_buf[len+1+strlen(token)] = '\0';
}
if (size < strlen(work_buf) + 1) {
free(work_buf);
Expand Down
32 changes: 21 additions & 11 deletions src/libltfs/ltfstrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,16 @@ struct ltfs_timespec start;
struct timer_info timerinfo;
bool trace_enable = true;

/* The trace dump is best-effort diagnostics; a write failure must not fail
* the operation that triggered the dump. glibc marks write() with
* warn_unused_result and a (void) cast does not silence it, so consume the
* result here and deliberately ignore it. */
static void _dump_write(int fd, const void *buf, size_t count)
{
ssize_t ignored = arch_write(fd, buf, count);
(void)ignored;
}

static int ltfs_request_trace_init(void)
{
int ret = 0;
Expand Down Expand Up @@ -576,7 +586,7 @@ int ltfs_dump(char *fname, const char *work_dir)
int ret = 0, num_args = 0, status;
char *path, *pid;
pid_t fork_pid;
const unsigned int max_arguments = 32;
enum { max_arguments = 32 };
const char *args[max_arguments];

if(!work_dir)
Expand Down Expand Up @@ -694,37 +704,37 @@ int ltfs_trace_dump(char *fname, const char *work_dir)
trc_header->header_size + req_header->header_size + fn_trc_header->header_size;

/* Write headers */
(void)arch_write(fd, trc_header, sizeof(struct trace_header));
(void)arch_write(fd, req_header, sizeof(struct request_header));
_dump_write(fd, trc_header, sizeof(struct trace_header));
_dump_write(fd, req_header, sizeof(struct request_header));

/* Write request trace data */
ltfs_mutex_lock(&req_trace->req_trace_lock);
(void)arch_write(fd, req_trace->entries, REQ_TRACE_SIZE);
_dump_write(fd, req_trace->entries, REQ_TRACE_SIZE);
ltfs_mutex_unlock(&req_trace->req_trace_lock);

/* Write function trace header */
(void)arch_write(fd, &fn_trc_header->header_size, sizeof(uint32_t));
(void)arch_write(fd, &fn_trc_header->num_of_fn_trace, sizeof(uint32_t));
_dump_write(fd, &fn_trc_header->header_size, sizeof(uint32_t));
_dump_write(fd, &fn_trc_header->num_of_fn_trace, sizeof(uint32_t));
for (unsigned int i=0; i<n; i++)
(void)arch_write(fd, &fn_trc_header->req_t_desc[i], sizeof(struct function_trace_descriptor));
(void)arch_write(fd, &fn_trc_header->crc, sizeof(uint32_t));
_dump_write(fd, &fn_trc_header->req_t_desc[i], sizeof(struct function_trace_descriptor));
_dump_write(fd, &fn_trc_header->crc, sizeof(uint32_t));
free(fn_trc_header->req_t_desc);
fn_trc_header->req_t_desc = NULL;

/* Write function trace data */
for (fsitem=fs_tr_list; fsitem != NULL; fsitem=fsitem->hh.next) {
acquireread_mrsw(&fsitem->fn_entry->trace_lock);
(void)arch_write(fd, fsitem->fn_entry->entries, FS_FN_TRACE_SIZE);
_dump_write(fd, fsitem->fn_entry->entries, FS_FN_TRACE_SIZE);
releaseread_mrsw(&fsitem->fn_entry->trace_lock);
}
for (admitem=admin_tr_list; admitem != NULL; admitem=admitem->hh.next) {
acquireread_mrsw(&admitem->fn_entry->trace_lock);
(void)arch_write(fd, admitem->fn_entry->entries, ADMIN_FN_TRACE_SIZE);
_dump_write(fd, admitem->fn_entry->entries, ADMIN_FN_TRACE_SIZE);
releaseread_mrsw(&admitem->fn_entry->trace_lock);
}
TAILQ_FOREACH (tailq_item, acomp, list) {
acquireread_mrsw(&tailq_item->fn_entry->trace_lock);
(void)arch_write(fd, tailq_item->fn_entry->entries, ADMIN_FN_TRACE_SIZE);
_dump_write(fd, tailq_item->fn_entry->entries, ADMIN_FN_TRACE_SIZE);
releaseread_mrsw(&tailq_item->fn_entry->trace_lock);
}
}
Expand Down
30 changes: 21 additions & 9 deletions src/libltfs/tape.c
Original file line number Diff line number Diff line change
Expand Up @@ -1782,8 +1782,9 @@ int tape_set_cart_coherency(struct device_data *dev, const tape_partition_t part
/* APPLICATION CLIENT SPECIFIC INFORMATION LENGTH */
coh_data[30] = 0; /* Size of APPLICATION CLIENT SPECIFIC INFORMATION (Byte 1) */
coh_data[31] = 43; /* Size of APPLICATION CLIENT SPECIFIC INFORMATION (Byte 0) */
/* Size of the buffer to insert 'LTFS' needs to be size of 5 for the 4 letters and the null terminator*/
arch_strncpy((char *)coh_data + 32,"LTFS", 5, 4);
/* Bytes 32-36 hold the "LTFS" signature; the reader checks all five
* bytes, so copy the terminator explicitly. */
memcpy(coh_data + 32, "LTFS", 5);
memcpy(coh_data + 37, coh->uuid, 37);
/*
Version field
Expand Down Expand Up @@ -2978,7 +2979,7 @@ void parse_vol(char *str, int start_len, int end_len)
*/
int u_get_truncate_size(const char *name, int name_len, int max_size)
{
int32_t size = 0, re_size;
int32_t size = 0, re_size = 0;
UChar32 c;
UErrorCode err = U_ZERO_ERROR;

Expand All @@ -3001,6 +3002,17 @@ int u_get_truncate_size(const char *name, int name_len, int max_size)
* @param Tape attribute
* @return 0: success, negative : cannot set correct value to tape_attr
*/
/* MAM attribute fields have fixed widths; truncation is intentional and
* parse_vol() pads and terminates afterwards. */
static void mam_field_copy(char *dest, size_t field_size, const char *src)
{
size_t n = strlen(src);

if (n > field_size)
n = field_size;
memcpy(dest, src, n);
}

void set_tape_attribute(struct ltfs_volume *vol, struct tape_attr *t_attr)
{
int len_volname = 0;
Expand All @@ -3016,16 +3028,16 @@ void set_tape_attribute(struct ltfs_volume *vol, struct tape_attr *t_attr)
}

/* APPLICATION VENDOR set */
arch_strncpy_auto(t_attr->vender, LTFS_VENDOR_NAME, TC_MAM_APP_VENDER_SIZE);
mam_field_copy(t_attr->vender, TC_MAM_APP_VENDER_SIZE, LTFS_VENDOR_NAME);
parse_vol(t_attr->vender, strlen(LTFS_VENDOR_NAME), TC_MAM_APP_VENDER_SIZE);

/* APPLICATION NAME set */
arch_strncpy_auto(t_attr->app_name, PACKAGE_NAME, TC_MAM_APP_NAME_SIZE);
mam_field_copy(t_attr->app_name, TC_MAM_APP_NAME_SIZE, PACKAGE_NAME);
parse_vol(t_attr->app_name, strlen(PACKAGE_NAME), TC_MAM_APP_NAME_SIZE);


/* APPLICATION VERSION set */
arch_strncpy_auto(t_attr->app_ver, PACKAGE_VERSION, TC_MAM_APP_VERSION_SIZE);
mam_field_copy(t_attr->app_ver, TC_MAM_APP_VERSION_SIZE, PACKAGE_VERSION);
parse_vol(t_attr->app_ver, strlen(PACKAGE_VERSION), TC_MAM_APP_VERSION_SIZE);

/* USER MEDIUM LABEL set */
Expand All @@ -3039,7 +3051,7 @@ void set_tape_attribute(struct ltfs_volume *vol, struct tape_attr *t_attr)
if (len_volname == -LTFS_ICU_ERROR)
len_volname = TC_MAM_USER_MEDIUM_LABEL_SIZE - 1;
}
arch_strncpy(t_attr->medium_label, vol->index->volume_name.name, sizeof(t_attr->medium_label), len_volname);
memcpy(t_attr->medium_label, vol->index->volume_name.name, len_volname);
}

/* TEXT LOCALIZATION IDENTIFIER set */
Expand All @@ -3049,15 +3061,15 @@ void set_tape_attribute(struct ltfs_volume *vol, struct tape_attr *t_attr)
if ( vol->label->barcode[0] ) {
if ( strlen(vol->label->barcode) > TC_MAM_BARCODE_SIZE)
ltfsmsg(LTFS_WARN, 17203W, "BARCODE", vol->label->barcode, TC_MAM_BARCODE_SIZE);
arch_strncpy_auto(t_attr->barcode, vol->label->barcode, TC_MAM_BARCODE_SIZE);
mam_field_copy(t_attr->barcode, TC_MAM_BARCODE_SIZE, vol->label->barcode);
parse_vol(t_attr->barcode, strlen(vol->label->barcode), TC_MAM_BARCODE_SIZE);
} else {
ltfsmsg(LTFS_WARN, 17230W);
parse_vol(t_attr->barcode, 0, TC_MAM_BARCODE_SIZE);
}

/* APPLICATION FORMAT VERSION set */
arch_strncpy_auto(t_attr->app_format_ver, LTFS_INDEX_VERSION_STR, TC_MAM_APP_FORMAT_VERSION_SIZE);
mam_field_copy(t_attr->app_format_ver, TC_MAM_APP_FORMAT_VERSION_SIZE, LTFS_INDEX_VERSION_STR);
parse_vol(t_attr->app_format_ver, strlen(LTFS_INDEX_VERSION_STR), TC_MAM_APP_FORMAT_VERSION_SIZE);

/* VOLUME LOCKED set */
Expand Down
11 changes: 11 additions & 0 deletions src/libltfs/tape_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,19 @@

#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <libltfs/ltfs_types.h>

/* Bounded, always-terminated string copy for the fixed-width identifier
* fields below; truncation of longer sources is intentional. */
static inline void ltfs_string_copy(char *dest, size_t dest_size, const char *src)
{
size_t n = strnlen(src, dest_size - 1);

memcpy(dest, src, n);
dest[n] = '\0';
}

#define VENDOR_ID_LENGTH (8)
#define PRODUCT_ID_LENGTH (16)
#define PRODUCT_REV_LENGTH (4)
Expand Down
8 changes: 5 additions & 3 deletions src/libltfs/xml_writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,15 @@ int xml_format_time(struct ltfs_timespec t, char** out)
return -1;
}

timebuf = calloc(31, sizeof(char));
/* 31 bytes fit a normalized time exactly; the extra room keeps the
* formatting safe for any field value. */
timebuf = calloc(64, sizeof(char));
if (!timebuf) {
ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__);
return -1;
}
arch_sprintf(timebuf, (31*sizeof(char)), "%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ", tm.tm_year + 1900, tm.tm_mon + 1,
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, t.tv_nsec);
snprintf(timebuf, 64, "%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ", tm.tm_year + 1900, tm.tm_mon + 1,
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (long)t.tv_nsec);
*out = timebuf;

return noramized;
Expand Down
3 changes: 2 additions & 1 deletion src/libltfs/xml_writer_libltfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,8 @@ int xml_schema_to_tape(char *reason, struct ltfs_volume *vol)
}

/* Generate the Index. */
asprintf(&creator, "%s - %s", vol->creator, reason);
if (asprintf(&creator, "%s - %s", vol->creator, reason) < 0)
creator = NULL;
if (creator) {
ret = _xml_write_schema(writer, creator, vol->index);
if (ret < 0) {
Expand Down
12 changes: 8 additions & 4 deletions src/tape_drivers/generic/itdtimg/itdtimg_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,10 @@ int itdtimage_read_attribute(void *vstate, const tape_partition_t part, const ui
return -EDEV_HARDWARE_ERROR;
}

fread(buf, 1, data2ReadFromFile, state->img_file);
if (fread(buf, 1, data2ReadFromFile, state->img_file) != data2ReadFromFile) {
ltfsmsg(LTFS_ERR, 31002E, (long long)attrLength, state->filename, offset);
return -EDEV_HARDWARE_ERROR;
}
return DEVICE_GOOD;
}

Expand Down Expand Up @@ -1370,9 +1373,10 @@ int itdtimage_get_device_list(struct tc_drive_info *buf, int count)

if (buf && deventries < count) {
snprintf(buf[deventries].name, TAPE_DEVNAME_LEN_MAX, "%s/%s", devdir, entry->d_name);
arch_strncpy_auto(buf[deventries].vendor, "DUMMY", TAPE_VENDOR_NAME_LEN_MAX);
arch_strncpy_auto(buf[deventries].model, "DUMMYDEV", TAPE_MODEL_NAME_LEN_MAX);
arch_strncpy_auto(buf[deventries].serial_number, &(entry->d_name[strlen(DRIVE_FILE_PREFIX)]), TAPE_SERIAL_LEN_MAX);
ltfs_string_copy(buf[deventries].vendor, TAPE_VENDOR_NAME_LEN_MAX + 1, "DUMMY");
ltfs_string_copy(buf[deventries].model, TAPE_MODEL_NAME_LEN_MAX + 1, "DUMMYDEV");
ltfs_string_copy(buf[deventries].serial_number, TAPE_SERIAL_LEN_MAX + 1,
&(entry->d_name[strlen(DRIVE_FILE_PREFIX)]));
ltfsmsg(LTFS_DEBUG, 31030D, buf[deventries].name, buf[deventries].vendor,
buf[deventries].model, buf[deventries].serial_number);
}
Expand Down
16 changes: 12 additions & 4 deletions src/tape_drivers/linux/sg/sg_scsi_tape.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,17 +464,25 @@ int sg_get_drive_identifier(struct sg_tape *device, scsi_device_identifier *id_d
return -EDEV_DEVICE_UNSUPPORTABLE;
}

strncpy(id_data->vendor_id, (char*)(&(inquiry_buf[8])), VENDOR_ID_LENGTH);
strncpy(id_data->product_id, (char*)(&(inquiry_buf[16])), PRODUCT_ID_LENGTH);
strncpy(id_data->product_rev, (char*)(&(inquiry_buf[32])), PRODUCT_REV_LENGTH);
/* Fixed-width INQUIRY fields; the memset above provides the terminators */
memcpy(id_data->vendor_id, &inquiry_buf[8], VENDOR_ID_LENGTH);
memcpy(id_data->product_id, &inquiry_buf[16], PRODUCT_ID_LENGTH);
memcpy(id_data->product_rev, &inquiry_buf[32], PRODUCT_REV_LENGTH);

ret = _inquiry_low(device, 0x80, inquiry_buf, MAX_INQ_LEN);
if( ret < 0 ) {
ltfsmsg(LTFS_INFO, 30206I, ret);
return ret;
}

strncpy(id_data->unit_serial, (char*)(&(inquiry_buf[4])), inquiry_buf[3]);
/* The serial length byte is device-controlled; clamp it to the field */
{
size_t serial_len = inquiry_buf[3];

if (serial_len > UNIT_SERIAL_LENGTH)
serial_len = UNIT_SERIAL_LENGTH;
memcpy(id_data->unit_serial, &inquiry_buf[4], serial_len);
}

return 0;
}
Loading