Index: netatalk-2.0.3/libatalk/dsi/dsi_opensess.c =================================================================== --- netatalk-2.0.3.orig/libatalk/dsi/dsi_opensess.c 2018-12-18 12:50:13.779890014 +0100 +++ netatalk-2.0.3/libatalk/dsi/dsi_opensess.c 2018-12-18 14:34:12.128900016 +0100 @@ -14,24 +14,44 @@ #include #include +#include +#include /* OpenSession. set up the connection */ void dsi_opensession(DSI *dsi) { - u_int32_t i = 0; /* this serves double duty. it must be 4-bytes long */ + size_t i = 0; + uint32_t servquant; + uint8_t cmd; + size_t option_len; /* parse options */ - while (i < dsi->cmdlen) { - switch (dsi->commands[i++]) { + while (i + 1 < dsi->cmdlen) { + cmd = dsi->commands[i++]; + option_len = dsi->commands[i++]; + + if (i + option_len > dsi->cmdlen) { + LOG(log_error, logtype_default, "option %u too large: %zu", + cmd, option_len); + exit(EXITERR_CLNT); + } + + switch (cmd) { case DSIOPT_ATTNQUANT: - memcpy(&dsi->attn_quantum, dsi->commands + i + 1, dsi->commands[i]); + if (option_len != sizeof(dsi->attn_quantum)) { + LOG(log_error, logtype_default, "option %u bad length: %zu", + cmd, option_len); + exit(EXITERR_CLNT); + } + memcpy(&dsi->attn_quantum, &dsi->commands[i], option_len); dsi->attn_quantum = ntohl(dsi->attn_quantum); case DSIOPT_SERVQUANT: /* just ignore these */ default: - i += dsi->commands[i] + 1; /* forward past length tag + length */ break; } + + i += option_len; } /* let the client know the server quantum. we don't use the @@ -39,13 +59,13 @@ void dsi_opensession(DSI *dsi) dsi->header.dsi_flags = DSIFL_REPLY; dsi->header.dsi_code = 0; /* dsi->header.dsi_command = DSIFUNC_OPEN;*/ - dsi->cmdlen = 2 + sizeof(i); /* length of data. dsi_send uses it. */ + dsi->cmdlen = 2 + sizeof(uint32_t); /* length of data. dsi_send uses it. */ dsi->commands[0] = DSIOPT_SERVQUANT; - dsi->commands[1] = sizeof(i); - i = htonl(( dsi->server_quantum < DSI_SERVQUANT_MIN || + dsi->commands[1] = sizeof(servquant); + servquant = htonl(( dsi->server_quantum < DSI_SERVQUANT_MIN || dsi->server_quantum > DSI_SERVQUANT_MAX ) ? DSI_SERVQUANT_DEF : dsi->server_quantum); - memcpy(dsi->commands + 2, &i, sizeof(i)); + memcpy(dsi->commands + 2, &servquant, sizeof(servquant)); dsi_send(dsi); }