From 2a41f009d6686af4e4c4cf506add7fb27374b4f4 Mon Sep 17 00:00:00 2001 From: XV02 Date: Tue, 3 Mar 2026 12:24:10 -0500 Subject: [PATCH 1/3] update: Memory leaks in strdup and asprintf functions and derivates (Partial) --- src/libltfs/fs.c | 6 +++- src/libltfs/index_criteria.c | 20 ++++++++++++ src/libltfs/ltfs_internal.c | 10 ++++++ src/libltfs/tape.c | 14 ++++++++ src/libltfs/xml_writer_libltfs.c | 32 ++++++++++++------- src/tape_drivers/freebsd/cam/cam_tc.c | 6 ++++ src/tape_drivers/generic/file/filedebug_tc.c | 10 ++++-- .../linux/lin_tape/lin_tape_ibmtape.c | 4 +++ src/utils/ltfsck.c | 4 +++ src/utils/mkltfs.c | 15 ++++++++- 10 files changed, 106 insertions(+), 15 deletions(-) diff --git a/src/libltfs/fs.c b/src/libltfs/fs.c index a685a678..2c16f2e8 100644 --- a/src/libltfs/fs.c +++ b/src/libltfs/fs.c @@ -93,7 +93,11 @@ static char* generate_hash_key_name(const char *src_str, int *rc) free(uchar_name); #else key_name = arch_strdup(src_str); - *rc = 0; + if (!key_name) { + *rc = -LTFS_NO_MEMORY; + } else { + *rc = 0; + } #endif return key_name; diff --git a/src/libltfs/index_criteria.c b/src/libltfs/index_criteria.c index 5fdca63b..191c62b2 100644 --- a/src/libltfs/index_criteria.c +++ b/src/libltfs/index_criteria.c @@ -309,16 +309,31 @@ int index_criteria_parse_name(const char *criteria, size_t len, struct index_cri *delim = '\0'; rule_ptr->percent_encode = fs_is_percent_encode_required(rule); rule_ptr->name = arch_strdup(rule); + if (!rule_ptr->name) { + ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__); + arch_safe_free(rulebuf); + return -LTFS_NO_MEMORY; + } rule_ptr++; rule = delim+1; } else if (*delim == '/') { *delim = '\0'; rule_ptr->percent_encode = fs_is_percent_encode_required(rule); rule_ptr->name = arch_strdup(rule); + if (!rule_ptr->name) { + ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__); + arch_safe_free(rulebuf); + return -LTFS_NO_MEMORY; + } rule_ptr++; } else if (*(delim+1) == '\0') { rule_ptr->percent_encode = fs_is_percent_encode_required(rule); rule_ptr->name = arch_strdup(rule); + if (!rule_ptr->name) { + ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__); + arch_safe_free(rulebuf); + return -LTFS_NO_MEMORY; + } rule_ptr++; } } @@ -326,6 +341,11 @@ int index_criteria_parse_name(const char *criteria, size_t len, struct index_cri if (ic->glob_patterns == rule_ptr) { rule_ptr->percent_encode = fs_is_percent_encode_required(rule); rule_ptr->name = arch_strdup(rule); + if (!rule_ptr->name) { + ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__); + arch_safe_free(rulebuf); + return -LTFS_NO_MEMORY; + } } /* Validate rules */ diff --git a/src/libltfs/ltfs_internal.c b/src/libltfs/ltfs_internal.c index 6059a0fc..be546397 100644 --- a/src/libltfs/ltfs_internal.c +++ b/src/libltfs/ltfs_internal.c @@ -1298,6 +1298,11 @@ int ltfs_split_symlink(struct ltfs_volume *vol) /* check lost_and_found directory and make if it doesn't exist */ int pathsize = asprintf( &lfdir, "/%s", LTFS_LOSTANDFOUND_DIR ); + if (pathsize < 0) { + ltfsmsg(LTFS_ERR, 10001E, "_ltfs_recover_symlink: lfdir"); + return -LTFS_NO_MEMORY; + } + ret = fs_path_lookup(lfdir, 0, &workd, vol->index); if ( ret==-LTFS_NO_DENTRY ) { ret = ltfs_fsops_create( lfdir, true, false, false, &workd, vol); @@ -1313,6 +1318,11 @@ int ltfs_split_symlink(struct ltfs_volume *vol) } ret = ltfs_fsops_close( workd, true, true, use_iosche, vol); path=arch_strdup(lfdir); + if (!path) { + ltfsmsg(LTFS_ERR, 10001E, "_ltfs_recover_symlink: path"); + free(lfdir); + return -LTFS_NO_MEMORY; + } /* loop for conflicted files */ for( i=0; i<(vol->index->symerr_count); i++ ){ diff --git a/src/libltfs/tape.c b/src/libltfs/tape.c index 839470db..35ea1030 100644 --- a/src/libltfs/tape.c +++ b/src/libltfs/tape.c @@ -1915,13 +1915,27 @@ int tape_get_media_pool_info(struct ltfs_volume *vol, char **media_name, char ** if (is_add_info) { if (add_start !=0) { name = strndup(vol->t_attr->media_pool, add_start); + if (!name) { + ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__); + return -LTFS_NO_MEMORY; + } } info = arch_strdup(&(vol->t_attr->media_pool[add_start+1])); + if (!info) { + ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__); + if (name) + free(name); + return -LTFS_NO_MEMORY; + } len = strlen(info); info[len-1] = '\0'; } else { name = arch_strdup(vol->t_attr->media_pool); + if (!name) { + ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__); + return -LTFS_NO_MEMORY; + } } if (name) diff --git a/src/libltfs/xml_writer_libltfs.c b/src/libltfs/xml_writer_libltfs.c index 7b1ae2be..7530d53a 100644 --- a/src/libltfs/xml_writer_libltfs.c +++ b/src/libltfs/xml_writer_libltfs.c @@ -784,20 +784,30 @@ int xml_schema_to_file(const char *filename, const char *creator, return -1; } - if (reason) - asprintf(&alt_creator, "%s - %s", creator , reason); - else + if (reason) { + ret = asprintf(&alt_creator, "%s - %s", creator , reason); + if (ret < 0) { + ltfsmsg(LTFS_ERR, 10001E, "xml_schema_to_file: alt_creator"); + xmlFreeTextWriter(writer); + return -LTFS_NO_MEMORY; + } + } else { alt_creator = arch_strdup(creator); + if (!alt_creator) { + ltfsmsg(LTFS_ERR, 10001E, "xml_schema_to_file: alt_creator"); + xmlFreeTextWriter(writer); + return -LTFS_NO_MEMORY; + } + } - if (alt_creator) { - ret = _xml_write_schema(writer, alt_creator, idx); - if (ret < 0) - ltfsmsg(LTFS_ERR, 17052E, ret, filename); - else - _commit_offset_caches(filename, idx); + ret = _xml_write_schema(writer, alt_creator, idx); + if (ret < 0) + ltfsmsg(LTFS_ERR, 17052E, ret, filename); + else + _commit_offset_caches(filename, idx); - xmlFreeTextWriter(writer); - free(alt_creator); + xmlFreeTextWriter(writer); + free(alt_creator); } else { ltfsmsg(LTFS_ERR, 10001E, "xml_schema_to_file: alt creator string"); xmlFreeTextWriter(writer); diff --git a/src/tape_drivers/freebsd/cam/cam_tc.c b/src/tape_drivers/freebsd/cam/cam_tc.c index 377af2ed..576ae1b3 100644 --- a/src/tape_drivers/freebsd/cam/cam_tc.c +++ b/src/tape_drivers/freebsd/cam/cam_tc.c @@ -2403,6 +2403,7 @@ int camtape_set_default(void *device) */ if (ioctl(softc->fd_sa, MTIOCPARAMSET, &sili_param) == -1) { msg = strdup("Error returned from MTIOCPARAMSET ioctl to set the SILI bit"); + /* If strdup fails, msg is NULL; camtape_process_errors handles NULL gracefully */ rc = -EDEV_DRIVER_ERROR; camtape_process_errors(device, rc, msg, "set default parameter", true); goto bailout; @@ -2437,6 +2438,7 @@ int camtape_set_default(void *device) eot_model = 1; if (ioctl(softc->fd_sa, MTIOCSETEOTMODEL, &eot_model) == -1) { msg = strdup("Error returned from MTIOCSETEOTMODEL ioctl to set the EOT model to 1FM"); + /* If strdup fails, msg is NULL; camtape_process_errors handles NULL gracefully */ rc = -EDEV_DRIVER_ERROR; camtape_process_errors(device, rc, msg, "set default parameter", true); goto bailout; @@ -3946,6 +3948,7 @@ int camtape_set_lbp(void *device, bool enable) entry = mt_status_entry_find(&mtinfo, tmpname); if (entry == NULL) { msg = strdup("Cannot find sa(4) protection.protection_supported parameter"); + /* If strdup fails, msg is NULL; camtape_process_errors handles NULL gracefully */ rc = -EDEV_INVALID_ARG; camtape_process_errors(device, rc, msg, "get lbp", true); goto bailout; @@ -3965,6 +3968,7 @@ int camtape_set_lbp(void *device, bool enable) prot_entry = mt_status_entry_find(&mtinfo, MT_PROTECTION_NAME); if (prot_entry == NULL) { msg = strdup("Cannot find sa(4) protection node!"); + /* If strdup fails, msg is NULL; camtape_process_errors handles NULL gracefully */ rc = -EDEV_INVALID_ARG; camtape_process_errors(device, rc, msg, "get lbp", true); goto bailout; @@ -3998,6 +4002,7 @@ int camtape_set_lbp(void *device, bool enable) entry = mt_entry_find(prot_entry, __DECONST(char *, protect_list[i].name)); if (entry == NULL) { msg = strdup("Cannot find all protection information entries"); + /* If strdup fails, msg is NULL; camtape_process_errors handles NULL gracefully */ rc = -EDEV_INVALID_ARG; camtape_process_errors(device, rc, msg, "get lbp", true); goto bailout; @@ -4020,6 +4025,7 @@ int camtape_set_lbp(void *device, bool enable) snprintf(tmpstr, sizeof(tmpstr), "Error returned from MTIOCSETLIST ioctl to set " "protection parameters: %s", strerror(errno)); msg = strdup(tmpstr); + /* If strdup fails, msg is NULL; camtape_process_errors handles NULL gracefully */ rc = -errno; camtape_process_errors(device, rc, msg, "get lbp", true); goto bailout; diff --git a/src/tape_drivers/generic/file/filedebug_tc.c b/src/tape_drivers/generic/file/filedebug_tc.c index 615517f0..a7a54c89 100644 --- a/src/tape_drivers/generic/file/filedebug_tc.c +++ b/src/tape_drivers/generic/file/filedebug_tc.c @@ -502,8 +502,13 @@ int filedebug_open(const char *name, void **handle) } /* Run on file mode */ - if (devname == NULL) + if (devname == NULL) { devname = arch_strdup(name); + if (!devname) { + ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__); + return -EDEV_NO_MEMORY; + } + } ltfsmsg(LTFS_INFO, 30001I, devname); arch_open(&(state->fd), devname, O_RDWR | O_BINARY, SHARE_FLAG_DENYWR, PERMISSION_READWRITE); @@ -2744,8 +2749,9 @@ int filedebug_get_device_list(struct tc_drive_info *buf, int count) if (buf && deventries < count) { tmp = arch_strdup(entry->d_name); - if (! *tmp) { + if (! tmp) { ltfsmsg(LTFS_ERR, 10001E, "filedebug_get_device_list"); + closedir(dp); return -ENOMEM; } diff --git a/src/tape_drivers/linux/lin_tape/lin_tape_ibmtape.c b/src/tape_drivers/linux/lin_tape/lin_tape_ibmtape.c index f8c1448c..fa1fe925 100644 --- a/src/tape_drivers/linux/lin_tape/lin_tape_ibmtape.c +++ b/src/tape_drivers/linux/lin_tape/lin_tape_ibmtape.c @@ -1018,6 +1018,10 @@ int lin_tape_ibmtape_open(const char *devname, void **handle) if (!ret) { /* Specified file is existed. Use it as a device file name */ devfile = strdup(devname); + if (!devfile) { + ltfsmsg(LTFS_ERR, 10001E, __FUNCTION__); + return -LTFS_NO_MEMORY; + } } else { /* Search device by serial number (Assume devname has a drive serial) */ devs = lin_tape_ibmtape_get_device_list(NULL, 0); diff --git a/src/utils/ltfsck.c b/src/utils/ltfsck.c index fb1e4250..697fe068 100644 --- a/src/utils/ltfsck.c +++ b/src/utils/ltfsck.c @@ -304,6 +304,10 @@ int main(int argc, char **argv) break; if (c == 'i') { config_file = arch_strdup(optarg); + if (!config_file) { + ltfsmsg(LTFS_ERR, 10001E, "ltfsck: config_file"); + return LTFSCK_OPERATIONAL_ERROR; + } break; } } diff --git a/src/utils/mkltfs.c b/src/utils/mkltfs.c index 9ad02890..cfaa74a1 100644 --- a/src/utils/mkltfs.c +++ b/src/utils/mkltfs.c @@ -159,10 +159,19 @@ void show_usage(char *appname, struct config_file *config, bool full) if (default_backend && plugin_load(&backend, "tape", default_backend, config) == 0) { devname = arch_strdup(ltfs_default_device_name(backend.ops)); plugin_unload(&backend); + if (!devname) { + ltfsmsg(LTFS_ERR, 10001E, "show_usage: devname"); + devname = strdup(""); /* Fallback for help text */ + } } - if (! devname) + if (! devname) { devname = arch_strdup(""); + if (!devname) { + ltfsmsg(LTFS_ERR, 10001E, "show_usage: devname fallback"); + devname = strdup(""); /* Last resort for help text */ + } + } fprintf(stderr, "\n"); ltfsresult(15400I, appname); /* Usage: %s */ @@ -283,6 +292,10 @@ int main(int argc, char **argv) break; if (c == 'i') { config_file = arch_strdup(optarg); + if (!config_file) { + ltfsmsg(LTFS_ERR, 10001E, "mkltfs: config_file"); + return MKLTFS_OPERATIONAL_ERROR; + } break; } } From 57cf068c9c2e616e1fd9f1d771091f22fda4b045 Mon Sep 17 00:00:00 2001 From: Gustavo Padilla Date: Wed, 4 Mar 2026 14:54:29 -0800 Subject: [PATCH 2/3] fix: 2 memory leaks --- src/libltfs/arch/ltfs_arch_ops.h | 33 +++----- src/libltfs/fs.c | 15 ++-- src/libltfs/ltfs_fsops.c | 7 +- src/libltfs/ltfslogging.c | 2 +- src/libltfs/tape.c | 141 ++++++++++++++++++++----------- src/libltfs/xml.h | 24 ++++-- src/libltfs/xml_reader_libltfs.c | 28 +++--- src/libltfs/xml_writer_libltfs.c | 9 +- src/tape_drivers/ibm_tape.c | 2 +- src/utils/mkltfs.c | 4 +- 10 files changed, 150 insertions(+), 115 deletions(-) diff --git a/src/libltfs/arch/ltfs_arch_ops.h b/src/libltfs/arch/ltfs_arch_ops.h index 781b57d3..86a1b909 100644 --- a/src/libltfs/arch/ltfs_arch_ops.h +++ b/src/libltfs/arch/ltfs_arch_ops.h @@ -74,16 +74,6 @@ extern "C" { } \ }while(0) -static inline void arch_strcpy_limited(char *dest, const char *src, int count) - { - int i; - for (i = 0; i < (count) && (src)[i] != '\0'; i++) - (dest)[i] = (src)[i]; - if (i < (count)) - (dest)[i] = '\0'; - } - - #ifdef _MSC_VER #include @@ -114,8 +104,6 @@ static inline void arch_strcpy_limited(char *dest, const char *src, int count) #define arch_fopen(file, mode, file_ptr) fopen_s(&(file_ptr), file, mode) - #define arch_ctime(buf, time_ptr) ctime_s(buf, sizeof(buf), time_ptr) - #define arch_getenv(buf, name) do { size_t len; _dupenv_s(&(buf), &(len), name); } while (0) #define arch_strtok(str, delm, ctxt) strtok_s((str), (delm), &(ctxt)) @@ -165,15 +153,13 @@ static inline void arch_strcpy_limited(char *dest, const char *src, int count) #define arch_fopen(file, mode, file_ptr) do {file_ptr = fopen(file, mode);}while(0) - #define arch_ctime(buf ,time_ptr) do { buf = ctime(time_ptr); } while (0) - #define arch_getenv(buf ,name) do { buf = getenv(name); } while (0) - #define arch_strcpy(dest, unused, src) ({if(unused || !unused) {strcpy(dest, src);}}) + #define arch_strcpy(dest, unused, src) ((void)(unused), strcpy(dest, src)) - #define arch_strncpy(dest, src, unused, cnt) strncpy(dest, src, cnt) + #define arch_strncpy(dest, src, destSize, cnt) strncpy(dest, src, (cnt)) - #define arch_strcat(dest, unused, src)( {if(unused || !unused){ strcat(dest, src);}}) + #define arch_strcat(dest, unused, src) ((void)(unused), strcat(dest, src)) #define arch_strtok(str, delim, unused) ((void)(unused), strtok(str, delim)) @@ -198,14 +184,15 @@ static inline void arch_strcpy_limited(char *dest, const char *src, int count) #endif /* _MSC_VER */ - /* These needs to be declared at the end to avoid redefinition and to avoid code replication */ - #define arch_vsprintf_auto( buffer, fmt, ...) arch_vsprintf(buffer,sizeof(buffer),fmt,__VA_ARGS__) - + /* + These needs to be declared at the end to avoid redefinition and to avoid code replication + When using them, dest or buffer needs to be a fixed size array since it will calculate it + with the sizeof. + */ + #define arch_strcpy_auto(dest, src) arch_strcpy(dest, sizeof(dest), src); - #define arch_strncpy_auto(dest, src, destSize) arch_strncpy(dest, src, destSize, destSize); - - #define arch_strcat_auto(dest,src) arch_strcat(dest, sizeof(dest), src); + #define arch_strncpy_auto(dest, src, count) arch_strncpy(dest, src, sizeof(dest), count); #define arch_sprintf_auto(buffer, fmt, ...) arch_sprintf(buffer,sizeof(buffer),fmt, __VA_ARGS__) diff --git a/src/libltfs/fs.c b/src/libltfs/fs.c index 2c16f2e8..790438d5 100644 --- a/src/libltfs/fs.c +++ b/src/libltfs/fs.c @@ -77,8 +77,6 @@ int fs_hash_sort_by_uid(struct name_list *a, struct name_list *b) static char* generate_hash_key_name(const char *src_str, int *rc) { char *key_name = NULL; - key_name = malloc(sizeof(char*)); - if (key_name == NULL) return NULL; #ifdef mingw_PLATFORM UChar *uchar_name; @@ -89,15 +87,16 @@ static char* generate_hash_key_name(const char *src_str, int *rc) if (*rc != 0) { key_name = NULL; - } else - free(uchar_name); + } else{ + arch_safe_free(uchar_name); + } #else key_name = arch_strdup(src_str); - if (!key_name) { - *rc = -LTFS_NO_MEMORY; - } else { + if (key_name){ *rc = 0; - } + }else{ + *rc = -LTFS_NO_MEMORY; + } #endif return key_name; diff --git a/src/libltfs/ltfs_fsops.c b/src/libltfs/ltfs_fsops.c index c213a9d5..be3b2641 100644 --- a/src/libltfs/ltfs_fsops.c +++ b/src/libltfs/ltfs_fsops.c @@ -2020,12 +2020,14 @@ int ltfs_fsops_target_absolute_path(const char* link, const char* target, char* len=strlen(link); int work_buf_len = len + len2 + 1; work_buf = malloc(work_buf_len); + memset(work_buf, '\0', work_buf_len); if (!work_buf) { ltfsmsg(LTFS_ERR, 10001E, "ltfs_fsops_target_absolute_path: work_buf"); return -LTFS_NO_MEMORY; } int target_buf_len = len2 + 1; target_buf = malloc(target_buf_len); + memset(target_buf, '\0', target_buf_len); if (!target_buf) { free(work_buf); ltfsmsg(LTFS_ERR, 10001E, "ltfs_fsops_target_absolute_path: target_buf"); @@ -2063,13 +2065,14 @@ 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) + 1); /* "/aaa/ccc\0" */ + arch_strncpy(work_buf+len+1, token, work_buf_len, strlen(token)); /* "/aaa/ccc\0" */ len = strlen(work_buf); } token = next_token; } work_buf[len] = '/'; /* put '/ 'as "/aaa/ccc/" */ - arch_strncpy(work_buf+len+1, token, work_buf_len, strlen(token)+1); /* "/aaa/ccc/target.txt\0" */ + if(token) + arch_strncpy(work_buf+len+1, token, work_buf_len, strlen(token)); /* "/aaa/ccc/target.txt\0" */ if (size < strlen(work_buf) + 1) { free(work_buf); diff --git a/src/libltfs/ltfslogging.c b/src/libltfs/ltfslogging.c index e686c68c..5f1a7ebe 100644 --- a/src/libltfs/ltfslogging.c +++ b/src/libltfs/ltfslogging.c @@ -396,7 +396,7 @@ int ltfsmsg_internal(bool print_id, int level, char **msg_out, const char *_id, goto internal_error; if (idlen > 1 && _id[0] == '"' && _id[idlen - 1] == '"') { - arch_strcpy_limited(id, _id + 1, idlen - 2); + arch_strncpy_auto(id, _id + 1, idlen - 2); id[idlen - 2] = '\0'; } else { diff --git a/src/libltfs/tape.c b/src/libltfs/tape.c index 35ea1030..49b59454 100644 --- a/src/libltfs/tape.c +++ b/src/libltfs/tape.c @@ -1782,7 +1782,7 @@ 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) */ - arch_strcpy_auto((char *)coh_data + 32, "LTFS"); + arch_strcpy((char *)coh_data + 32,5, "LTFS"); memcpy(coh_data + 37, coh->uuid, 37); /* Version field @@ -3075,86 +3075,128 @@ void set_tape_attribute(struct ltfs_volume *vol, struct tape_attr *t_attr) * @param set attribute type * @return 0 positive : success, negative : cannot set value to Cartridge Memory */ -int tape_set_attribute_to_cm(struct device_data *dev, struct tape_attr *t_attr, int type) +int tape_set_attribute_to_cm(struct device_data* dev, + struct tape_attr* t_attr, + int type) { - int ret; int attr_size; uint8_t format; + unsigned char* attr_data = NULL; + unsigned char* data; + size_t len; CHECK_ARG_NULL(dev, -LTFS_NULL_ARG); CHECK_ARG_NULL(t_attr, -LTFS_NULL_ARG); - if ( type == TC_MAM_APP_VENDER ) { + switch (type) { + case TC_MAM_APP_VENDER: attr_size = TC_MAM_APP_VENDER_SIZE; format = ASCII_FORMAT; - } else if ( type == TC_MAM_APP_NAME) { + break; + case TC_MAM_APP_NAME: attr_size = TC_MAM_APP_NAME_SIZE; format = ASCII_FORMAT; - } else if ( type== TC_MAM_APP_VERSION ) { + break; + case TC_MAM_APP_VERSION: attr_size = TC_MAM_APP_VERSION_SIZE; format = ASCII_FORMAT; - } else if ( type == TC_MAM_USER_MEDIUM_LABEL ) { + break; + case TC_MAM_USER_MEDIUM_LABEL: attr_size = TC_MAM_USER_MEDIUM_LABEL_SIZE; format = TEXT_FORMAT; - } else if ( type == TC_MAM_TEXT_LOCALIZATION_IDENTIFIER ) { + break; + case TC_MAM_TEXT_LOCALIZATION_IDENTIFIER: attr_size = TC_MAM_TEXT_LOCALIZATION_IDENTIFIER_SIZE; format = BINARY_FORMAT; - } else if ( type == TC_MAM_BARCODE ) { + break; + case TC_MAM_BARCODE: attr_size = TC_MAM_BARCODE_SIZE; format = ASCII_FORMAT; - } else if ( type == TC_MAM_APP_FORMAT_VERSION ) { + break; + case TC_MAM_APP_FORMAT_VERSION: attr_size = TC_MAM_APP_FORMAT_VERSION_SIZE; format = ASCII_FORMAT; - } else if ( type == TC_MAM_LOCKED_MAM ) { + break; + case TC_MAM_LOCKED_MAM: attr_size = TC_MAM_LOCKED_MAM_SIZE; format = BINARY_FORMAT; - } else if ( type == TC_MAM_MEDIA_POOL ) { + break; + case TC_MAM_MEDIA_POOL: attr_size = TC_MAM_MEDIA_POOL_SIZE; format = TEXT_FORMAT; - } else { + break; + default: ltfsmsg(LTFS_WARN, 17204W, type, "tape_set_attribute_to_cm"); return -1; } - unsigned char *attr_data = NULL; - attr_data = (unsigned char*)malloc(sizeof(unsigned char*)*(attr_size +TC_MAM_PAGE_HEADER_SIZE)); - if (attr_data == NULL) return -LTFS_NO_MEMORY; - ltfs_u16tobe(attr_data, type); /* set attribute type */ + attr_data = calloc(1, attr_size + TC_MAM_PAGE_HEADER_SIZE); + if (!attr_data) + return -LTFS_NO_MEMORY; + + ltfs_u16tobe(attr_data, type); /* set attribute type */ attr_data[2] = format; /* set data format type */ ltfs_u16tobe(attr_data + 3, attr_size); /* set data size */ + data = attr_data + TC_MAM_PAGE_HEADER_SIZE; + /* set attribute data */ - if ( type == TC_MAM_APP_VENDER ) { - arch_strncpy((char *)attr_data + 5, t_attr->vender, attr_size+ TC_MAM_PAGE_HEADER_SIZE , attr_size); - } else if ( type == TC_MAM_APP_NAME ) { - arch_strncpy((char *)attr_data + 5, t_attr->app_name, attr_size + TC_MAM_PAGE_HEADER_SIZE, attr_size); - } else if ( type == TC_MAM_APP_VERSION ) { - arch_strncpy((char *)attr_data + 5, t_attr->app_ver, attr_size + TC_MAM_PAGE_HEADER_SIZE, attr_size); - } else if ( type == TC_MAM_USER_MEDIUM_LABEL ) { - arch_strncpy((char *)attr_data + 5, t_attr->medium_label, attr_size + TC_MAM_PAGE_HEADER_SIZE, attr_size); - } else if ( type == TC_MAM_TEXT_LOCALIZATION_IDENTIFIER ) { - attr_data[5] = t_attr->tli; - } else if ( type == TC_MAM_BARCODE ) { - arch_strncpy((char *)attr_data + 5, t_attr->barcode, attr_size + TC_MAM_PAGE_HEADER_SIZE, attr_size); - } else if ( type == TC_MAM_APP_FORMAT_VERSION ) { - arch_strncpy((char *)attr_data + 5, t_attr->app_format_ver, attr_size + TC_MAM_PAGE_HEADER_SIZE, attr_size); - } else if ( type == TC_MAM_LOCKED_MAM ) { - attr_data[5] = t_attr->vollock; - } else if ( type == TC_MAM_MEDIA_POOL) { - arch_strncpy((char *)attr_data + 5, t_attr->media_pool, attr_size + TC_MAM_PAGE_HEADER_SIZE, attr_size); + switch (type) { + case TC_MAM_APP_VENDER: + len = strnlen(t_attr->vender, attr_size); + memcpy(data, t_attr->vender, len); + break; + + case TC_MAM_APP_NAME: + len = strnlen(t_attr->app_name, attr_size); + memcpy(data, t_attr->app_name, len); + break; + + case TC_MAM_APP_VERSION: + len = strnlen(t_attr->app_ver, attr_size); + memcpy(data, t_attr->app_ver, len); + break; + + case TC_MAM_USER_MEDIUM_LABEL: + len = strnlen(t_attr->medium_label, attr_size); + memcpy(data, t_attr->medium_label, len); + break; + + case TC_MAM_TEXT_LOCALIZATION_IDENTIFIER: + data[0] = t_attr->tli; + break; + + case TC_MAM_BARCODE: + len = strnlen(t_attr->barcode, attr_size); + memcpy(data, t_attr->barcode, len); + break; + + case TC_MAM_APP_FORMAT_VERSION: + len = strnlen(t_attr->app_format_ver, attr_size); + memcpy(data, t_attr->app_format_ver, len); + break; + + case TC_MAM_LOCKED_MAM: + data[0] = t_attr->vollock; + break; + + case TC_MAM_MEDIA_POOL: + len = strnlen(t_attr->media_pool, attr_size); + memcpy(data, t_attr->media_pool, len); + break; } ret = dev->backend->write_attribute(dev->backend_data, - 0, /* partition */ - attr_data, - (attr_size + TC_MAM_PAGE_HEADER_SIZE)); + 0, /* partition */ + attr_data, + attr_size + TC_MAM_PAGE_HEADER_SIZE); if (ret < 0) ltfsmsg(LTFS_ERR, 17205E, type, "tape_set_attribute_to_cm"); + free(attr_data); return ret; - } /** @@ -3232,12 +3274,13 @@ int tape_get_attribute_from_cm(struct device_data *dev, struct tape_attr *t_attr { int ret; int attr_len; + unsigned char* attr_data = NULL; CHECK_ARG_NULL(dev, -LTFS_NULL_ARG); CHECK_ARG_NULL(t_attr, -LTFS_NULL_ARG); switch (type) { - case TC_MAM_APP_VENDER: + case TC_MAM_APP_VENDER: attr_len = TC_MAM_APP_VENDER_SIZE; break; case TC_MAM_APP_NAME: @@ -3270,14 +3313,14 @@ int tape_get_attribute_from_cm(struct device_data *dev, struct tape_attr *t_attr break; } - unsigned char *attr_data = NULL; - attr_data = malloc(sizeof(char*) * (attr_len + TC_MAM_PAGE_HEADER_SIZE)); - if (attr_data == NULL) return -LTFS_NO_MEMORY; + int attr_size = sizeof(char) * (attr_len + TC_MAM_PAGE_HEADER_SIZE); + attr_data = (unsigned char*)malloc(attr_size); + if (!attr_data) return -LTFS_NO_MEMORY; ret = dev->backend->read_attribute(dev->backend_data, - 0, /* partition */ - type, - attr_data, - sizeof(attr_data)); + 0, /* partition */ + type, + attr_data, + attr_size); if (ret == 0) { uint16_t id = ltfs_betou16(attr_data); @@ -3486,10 +3529,10 @@ int update_tape_attribute(struct ltfs_volume *vol, const char *new_value, int ty if (ret < 0) { if ( type == TC_MAM_USER_MEDIUM_LABEL ) { memset(vol->t_attr->medium_label, '\0', TC_MAM_USER_MEDIUM_LABEL_SIZE + 1); - arch_strncpy_auto(vol->t_attr->medium_label, pre_attr, strlen(pre_attr)); + arch_strcpy_auto(vol->t_attr->medium_label, pre_attr); } else if (type == TC_MAM_BARCODE) { memset(vol->t_attr->barcode, '\0', TC_MAM_BARCODE_SIZE + 1); - arch_strncpy_auto(vol->t_attr->barcode, pre_attr, strlen(pre_attr)); + arch_strcpy_auto(vol->t_attr->barcode, pre_attr); } } diff --git a/src/libltfs/xml.h b/src/libltfs/xml.h index 3bd1d6a4..b2350a05 100644 --- a/src/libltfs/xml.h +++ b/src/libltfs/xml.h @@ -115,7 +115,7 @@ int xml_format_time(struct ltfs_timespec t, char** out); /* standard parser variables */ #define declare_parser(toptag) \ const char *name, *parent_tag = (toptag); \ - int i, type, empty, ret; + int i, type, empty, ret = 0; #define declare_parser_vars_noloop(toptag) \ const char *name, *value, *parent_tag = (toptag); \ @@ -139,12 +139,22 @@ int xml_format_time(struct ltfs_timespec t, char** out); int type; /* generate required/optional tag tracking arrays for the parser */ -#define declare_tracking_arrays(num_req, num_opt) \ - const int ntags_req = (num_req), ntags_opt = (num_opt); \ - bool *have_required_tags = ntags_req > 0 ? (bool*)calloc(ntags_req, sizeof(bool)) : NULL; \ - bool *have_optional_tags = ntags_opt > 0 ? (bool*)calloc(ntags_opt, sizeof(bool)) : NULL; \ - if(! have_optional_tags) (void)(have_optional_tags); \ - if(! have_required_tags) (void)(have_required_tags); +#define declare_tracking_arrays(num_req, num_opt) \ + const int ntags_req = (num_req), ntags_opt = (num_opt); \ + bool have_required_tags[num_req], have_optional_tags[num_opt]; \ + memset(have_required_tags, 0, sizeof(have_required_tags)); \ + memset(have_optional_tags, 0, sizeof(have_optional_tags)); + +#define declare_tracking_arrays_no_opt(num_req) \ + const int ntags_req = (num_req), ntags_opt = (0); \ + bool have_required_tags[num_req]; \ + bool *have_optional_tags = NULL; \ + memset(have_required_tags, 0, sizeof(have_required_tags)); + +#define declare_tracking_arrays_no_tags() \ + const int ntags_req = (0), ntags_opt = (0); \ + bool *have_required_tags = NULL; \ + bool *have_optional_tags = NULL; /* grab the next tag inside the given tag. It breaks if the end of the given tag is detected. diff --git a/src/libltfs/xml_reader_libltfs.c b/src/libltfs/xml_reader_libltfs.c index c28f1d44..54b92d77 100644 --- a/src/libltfs/xml_reader_libltfs.c +++ b/src/libltfs/xml_reader_libltfs.c @@ -165,7 +165,7 @@ static int decode_entry_name(char **new_name, const char *name) static int _xml_parse_nametype(xmlTextReaderPtr reader, struct ltfs_name *n, bool target) { const char name[] = "nametype", *value; - char *decoded_name, *encoded_name, *encode; + char* decoded_name = NULL, * encoded_name = NULL, * encode = NULL; int empty, ret = -1; encode = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "percentencoded"); @@ -213,7 +213,7 @@ static int _xml_parse_nametype(xmlTextReaderPtr reader, struct ltfs_name *n, boo static int _xml_parse_nametype_allow_zero_length(xmlTextReaderPtr reader, struct ltfs_name *n, bool target) { const char name[] = "nametype", *value; - char *decoded_name, *encoded_name, *encode; + char *decoded_name=NULL, *encoded_name=NULL, *encode=NULL; int empty, ret = -1; encode = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "percentencoded"); @@ -378,7 +378,7 @@ static int _xml_parser_init(xmlTextReaderPtr reader, const char *top_name, int * static int _xml_parse_label_location(xmlTextReaderPtr reader, struct ltfs_label *label) { declare_parser_vars("location"); - declare_tracking_arrays(1, 0); + declare_tracking_arrays_no_opt(1); while (true) { get_next_tag(); @@ -407,7 +407,7 @@ static int _xml_parse_label_location(xmlTextReaderPtr reader, struct ltfs_label static int _xml_parse_partition_map(xmlTextReaderPtr reader, struct ltfs_label *label) { declare_parser_vars("partitions"); - declare_tracking_arrays(2, 0); + declare_tracking_arrays_no_opt(2); while (true) { get_next_tag(); @@ -443,7 +443,7 @@ static int _xml_parse_label(xmlTextReaderPtr reader, struct ltfs_label *label) { unsigned long long value_int; declare_parser_vars("ltfslabel"); - declare_tracking_arrays(7, 0); + declare_tracking_arrays_no_opt(7); /* start the parser: find top-level "label" tag, check version and encoding */ ret = _xml_parser_init(reader, parent_tag, &label->version, @@ -540,7 +540,7 @@ static int _xml_parse_ip_criteria(xmlTextReaderPtr reader, struct ltfs_index *id unsigned long long value_int; int num_patterns = 0; declare_parser_vars("indexpartitioncriteria"); - declare_tracking_arrays(1, 0); + declare_tracking_arrays_no_opt(1); /* clear the glob pattern list first */ index_criteria_free(&idx->original_criteria); @@ -601,7 +601,7 @@ static int _xml_parse_ip_criteria(xmlTextReaderPtr reader, struct ltfs_index *id static int _xml_parse_policy(xmlTextReaderPtr reader, struct ltfs_index *idx) { declare_parser("dataplacementpolicy"); - declare_tracking_arrays(1, 0); + declare_tracking_arrays_no_opt(1); /* parse the contents of the policy tag */ while (true) { @@ -630,7 +630,7 @@ static int _xml_parse_one_extent(xmlTextReaderPtr reader, int idx_version, struc unsigned long long value_int; struct extent_info *xt, *xt_last; declare_parser_vars("extent"); - declare_tracking_arrays(5, 0); + declare_tracking_arrays_no_opt(5); xt = calloc(1, sizeof(struct extent_info)); if (!xt) { @@ -747,7 +747,7 @@ static int _xml_parse_one_extent(xmlTextReaderPtr reader, int idx_version, struc static int _xml_parse_extents(xmlTextReaderPtr reader, int idx_version, struct dentry *d) { declare_parser("extentinfo"); - declare_tracking_arrays(0, 0); + declare_tracking_arrays_no_tags(); while (true) { get_next_tag(); @@ -774,7 +774,7 @@ static int _xml_parse_one_xattr(xmlTextReaderPtr reader, struct dentry *d) char *xattr_type; struct xattr_info *xattr = NULL; declare_parser_vars("xattr"); - declare_tracking_arrays(2, 0); + declare_tracking_arrays_no_opt(2); xattr = calloc(1, sizeof(struct xattr_info)); if (! xattr) { @@ -871,7 +871,7 @@ static int _xml_parse_one_xattr(xmlTextReaderPtr reader, struct dentry *d) static int _xml_parse_xattrs(xmlTextReaderPtr reader, struct dentry *d) { declare_parser("extendedattributes"); - declare_tracking_arrays(0, 0); + declare_tracking_arrays_no_tags(); while (true) { get_next_tag(); @@ -904,7 +904,7 @@ static int _xml_parse_tapepos(xmlTextReaderPtr reader, const char *tag, struct t { unsigned long long value_int; declare_parser_vars(tag); - declare_tracking_arrays(2, 0); + declare_tracking_arrays_no_opt(2); while (true) { get_next_tag(); @@ -1192,7 +1192,7 @@ static int _xml_parse_dir_contents(xmlTextReaderPtr reader, struct dentry *dir, struct name_list *list = NULL, *entry_name = NULL; CHECK_ARG_NULL(dir, -LTFS_NULL_ARG); declare_parser("contents"); - declare_tracking_arrays(0, 0); + declare_tracking_arrays_no_tags(); errno = 0; @@ -1669,7 +1669,7 @@ static int _xml_parse_schema(xmlTextReaderPtr reader, struct ltfs_index *idx, st static int _xml_parse_symlink_target(xmlTextReaderPtr reader, int idx_version, struct dentry *d) { declare_parser_vars_symlinknode("symlink"); - declare_tracking_arrays(1, 0); + declare_tracking_arrays_no_opt(1); while (true) { get_next_tag(); diff --git a/src/libltfs/xml_writer_libltfs.c b/src/libltfs/xml_writer_libltfs.c index 7530d53a..8bcdd06d 100644 --- a/src/libltfs/xml_writer_libltfs.c +++ b/src/libltfs/xml_writer_libltfs.c @@ -794,12 +794,11 @@ int xml_schema_to_file(const char *filename, const char *creator, } else { alt_creator = arch_strdup(creator); if (!alt_creator) { - ltfsmsg(LTFS_ERR, 10001E, "xml_schema_to_file: alt_creator"); + ltfsmsg(LTFS_ERR, 10001E, "xml_schema_to_file: alt_creator string"); xmlFreeTextWriter(writer); return -LTFS_NO_MEMORY; } } - ret = _xml_write_schema(writer, alt_creator, idx); if (ret < 0) ltfsmsg(LTFS_ERR, 17052E, ret, filename); @@ -808,12 +807,6 @@ int xml_schema_to_file(const char *filename, const char *creator, xmlFreeTextWriter(writer); free(alt_creator); - } else { - ltfsmsg(LTFS_ERR, 10001E, "xml_schema_to_file: alt creator string"); - xmlFreeTextWriter(writer); - return -1; - } - return ret; } diff --git a/src/tape_drivers/ibm_tape.c b/src/tape_drivers/ibm_tape.c index 9ff64dc8..21c12e1d 100644 --- a/src/tape_drivers/ibm_tape.c +++ b/src/tape_drivers/ibm_tape.c @@ -1283,7 +1283,7 @@ int ibm_tape_genkey(unsigned char *key) #ifdef mingw_PLATFORM memset(key, 0x00, KEYLEN); *key = KEY_PREFIX_HOST; - arch_strncpy_auto(key + 1, "WINLTFS", KEYLEN - 1); + arch_strncpy(key + 1, "WNLTFS", KEYLEN - 1,KEYLEN-2); #else unsigned char host[KEYLEN]; diff --git a/src/utils/mkltfs.c b/src/utils/mkltfs.c index cfaa74a1..fb43b2ad 100644 --- a/src/utils/mkltfs.c +++ b/src/utils/mkltfs.c @@ -161,7 +161,7 @@ void show_usage(char *appname, struct config_file *config, bool full) plugin_unload(&backend); if (!devname) { ltfsmsg(LTFS_ERR, 10001E, "show_usage: devname"); - devname = strdup(""); /* Fallback for help text */ + devname = arch_strdup(""); /* Fallback for help text */ } } @@ -169,7 +169,7 @@ void show_usage(char *appname, struct config_file *config, bool full) devname = arch_strdup(""); if (!devname) { ltfsmsg(LTFS_ERR, 10001E, "show_usage: devname fallback"); - devname = strdup(""); /* Last resort for help text */ + devname = arch_strdup(""); /* Last resort for help text */ } } From 94ac328a1b508d3b07649a1dc0f31e7d588b3af8 Mon Sep 17 00:00:00 2001 From: Gustavo Padilla Date: Wed, 4 Mar 2026 15:31:06 -0800 Subject: [PATCH 3/3] fix: unused variables and ctime --- src/libltfs/arch/ltfs_arch_ops.h | 8 ++++++-- src/libltfs/xml.h | 9 ++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libltfs/arch/ltfs_arch_ops.h b/src/libltfs/arch/ltfs_arch_ops.h index 86a1b909..f9f8bfbd 100644 --- a/src/libltfs/arch/ltfs_arch_ops.h +++ b/src/libltfs/arch/ltfs_arch_ops.h @@ -106,14 +106,16 @@ extern "C" { #define arch_getenv(buf, name) do { size_t len; _dupenv_s(&(buf), &(len), name); } while (0) - #define arch_strtok(str, delm, ctxt) strtok_s((str), (delm), &(ctxt)) - #define arch_strcpy(dest, size, src) strcpy_s((dest), (size), (src)) #define arch_strncpy(dest, src, size, cnt) strncpy_s((dest), (size), (src), (cnt)) #define arch_strcat(dest, size, src) strcat_s((dest), (size), (src)) + #define arch_strtok(str, delm, ctxt) strtok_s((str), (delm), &(ctxt)) + + #define arch_ctime(buf, time_ptr) ctime_s(buf, sizeof(buf), time_ptr) + #define arch_unlink _unlink #define arch_write _write @@ -163,6 +165,8 @@ extern "C" { #define arch_strtok(str, delim, unused) ((void)(unused), strtok(str, delim)) + #define arch_ctime(buf ,time_ptr) do { buf = ctime(time_ptr); } while (0) + #define arch_unlink unlink #define arch_write write diff --git a/src/libltfs/xml.h b/src/libltfs/xml.h index b2350a05..5bb967fe 100644 --- a/src/libltfs/xml.h +++ b/src/libltfs/xml.h @@ -143,18 +143,21 @@ int xml_format_time(struct ltfs_timespec t, char** out); const int ntags_req = (num_req), ntags_opt = (num_opt); \ bool have_required_tags[num_req], have_optional_tags[num_opt]; \ memset(have_required_tags, 0, sizeof(have_required_tags)); \ - memset(have_optional_tags, 0, sizeof(have_optional_tags)); + memset(have_optional_tags, 0, sizeof(have_optional_tags)); \ + (void)ntags_opt #define declare_tracking_arrays_no_opt(num_req) \ const int ntags_req = (num_req), ntags_opt = (0); \ bool have_required_tags[num_req]; \ bool *have_optional_tags = NULL; \ - memset(have_required_tags, 0, sizeof(have_required_tags)); + memset(have_required_tags, 0, sizeof(have_required_tags)); \ + (void)ntags_req; (void)ntags_opt; (void)have_optional_tags #define declare_tracking_arrays_no_tags() \ const int ntags_req = (0), ntags_opt = (0); \ bool *have_required_tags = NULL; \ - bool *have_optional_tags = NULL; + bool *have_optional_tags = NULL; \ + (void)ntags_req; (void)ntags_opt; (void)have_required_tags; (void)have_optional_tags /* grab the next tag inside the given tag. It breaks if the end of the given tag is detected.