Skip to content

Commit

Permalink
add handlers for transcoding normalized file info, detect buffer over…
Browse files Browse the repository at this point in the history
…flow on reply encoding
  • Loading branch information
bdodge committed Jan 19, 2025
1 parent bdaef47 commit 14286e4
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 2 deletions.
11 changes: 9 additions & 2 deletions include/libsmb2-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ extern "C" {
#include <gssapi/gssapi.h>
#include <gssapi/gssapi_ext.h>
#endif /* __APPLE__ */
#endif /* HAVE_LIBKRB5 */
#endif /* HAVE_LIBKRB5 */

#define MIN(a,b) (((a)<(b))?(a):(b))

Expand Down Expand Up @@ -341,7 +341,7 @@ struct smb2dir {
int index;
};


#define smb2_is_server(ctx) ((ctx)->owning_server != NULL)

void smb2_set_nterror(struct smb2_context *smb2, int nterror,
Expand Down Expand Up @@ -554,6 +554,13 @@ int smb2_encode_file_network_open_info(struct smb2_context *smb2,
struct smb2_file_network_open_info *fs,
struct smb2_iovec *vec);

int smb2_decode_file_normalized_name_info(struct smb2_context *smb2,
void *memctx,
struct smb2_file_name_info *fs,
struct smb2_iovec *vec);
int smb2_encode_file_normalized_name_info(struct smb2_context *smb2,
struct smb2_file_name_info *fs,
struct smb2_iovec *vec);
int smb2_decode_security_descriptor(struct smb2_context *smb2,
void *memctx,
struct smb2_security_descriptor *sd,
Expand Down
8 changes: 8 additions & 0 deletions include/smb2/smb2.h
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,14 @@ struct smb2_file_position_info {
uint64_t current_byte_offset;
};

/*
* FILE_NAME_INFORMATION
*/
struct smb2_file_name_info {
uint32_t file_name_length;
const uint8_t *name;
};

/*
* FILE_ALL_INFORMATION.
*/
Expand Down
16 changes: 16 additions & 0 deletions lib/smb2-cmd-query-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ smb2_encode_query_info_reply(struct smb2_context *smb2,
(struct smb2_file_network_open_info *)rep->output_buffer, iov);
break;
case SMB2_FILE_NORMALIZED_NAME_INFORMATION:
created_output_buffer_length =
smb2_encode_file_normalized_name_info(smb2,
(struct smb2_file_name_info *)rep->output_buffer, iov);
break;
case SMB2_FILE_PIPE_INFORMATION:
break;
Expand Down Expand Up @@ -300,6 +303,11 @@ smb2_encode_query_info_reply(struct smb2_context *smb2,
req->info_type, req->file_info_class);
}
} else {
if (created_output_buffer_length > req->output_buffer_length) {
/* truncate output buffer to what request can handle in return */
created_output_buffer_length = req->output_buffer_length;
smb2_set_pdu_status(smb2, pdu, SMB2_STATUS_BUFFER_OVERFLOW);
}
iov->len = PAD_TO_64BIT(created_output_buffer_length);
rep->output_buffer_length = created_output_buffer_length;
}
Expand Down Expand Up @@ -472,6 +480,14 @@ int smb2_process_query_info_variable(struct smb2_context *smb2,
}
break;
case SMB2_FILE_NORMALIZED_NAME_INFORMATION:
ptr = smb2_alloc_init(smb2,
sizeof(struct smb2_file_name_info));
if (smb2_decode_file_normalized_name_info(smb2, ptr, ptr, &vec)) {
smb2_set_error(smb2, "could not decode file "
"normalized name info. %s",
smb2_get_error(smb2));
return -1;
}
break;
case SMB2_FILE_PIPE_INFORMATION:
break;
Expand Down
71 changes: 71 additions & 0 deletions lib/smb2-data-file-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,74 @@ smb2_encode_file_network_open_info(struct smb2_context *smb2,
return 52;
}


int
smb2_decode_file_normalized_name_info(struct smb2_context *smb2,
void *memctx,
struct smb2_file_name_info *fs,
struct smb2_iovec *vec)
{
struct smb2_iovec v _U_;
uint32_t name_len;
const char *name;

if (vec->len < 40) {
return -1;
}

v.buf = &vec->buf[0];
v.len = 4;
smb2_get_uint32(vec, 0, &name_len);

fs->file_name_length = name_len / 2;

if (name_len > 0) {
if (vec->len < (name_len + 4)) {
return -1;
}
name = smb2_utf16_to_utf8((uint16_t *)&vec->buf[4], name_len / 2);
fs->name = smb2_alloc_data(smb2, memctx, strlen(name) + 1);
if (fs->name == NULL) {
free(discard_const(name));
return -1;
}
strcpy(discard_const(fs->name), name);
free(discard_const(name));
} else {
fs->name = NULL;
}
return 0;
}

int
smb2_encode_file_normalized_name_info(struct smb2_context *smb2,
struct smb2_file_name_info *fs,
struct smb2_iovec *vec)
{
struct smb2_utf16 *name = NULL;
int name_len;

if (vec->len < 4) {
return -1;
}

if (fs->name) {
name = smb2_utf8_to_utf16((const char*)fs->name);
if (name) {
name_len = 2 * name->len;
if (vec->len < name_len + 4) {
return -1;
}
smb2_set_uint32(vec, 0, name_len);
memcpy((uint16_t *)&vec->buf[4], name->val, name_len);
free(name);
return 4 + name_len;
} else {
return -1;
}
} else {
smb2_set_uint32(vec, 0, 0);
return 4;
}
}

0 comments on commit 14286e4

Please sign in to comment.