Commit c258137adcc6182a50effb2dd1d77c54ac0798a0

Authored by Michael Heimpold
Committed by Stéphane Raimbault
1 parent a002b389

Handle out-of-memory conditions more gracefully

Current code could dereference NULL pointer in case an inner
malloc fails. Check for this and exit gracefully.

Signed-off-by: Michael Heimpold <mhei@heimpold.de>
doc/modbus_new_rtu.txt
... ... @@ -53,6 +53,10 @@ ERRORS
53 53 *EINVAL*::
54 54 An invalid argument was given.
55 55  
  56 +*ENOMEM*::
  57 +Out of memory. Possibly, the application hits its memory limit and/or whole
  58 +system is running out of memory.
  59 +
56 60  
57 61 EXAMPLE
58 62 -------
... ...
doc/modbus_new_tcp.txt
... ... @@ -39,6 +39,10 @@ ERRORS
39 39 *EINVAL*::
40 40 An invalid IP address was given.
41 41  
  42 +*ENOMEM*::
  43 +Out of memory. Possibly, the application hits its memory limit and/or whole
  44 +system is running out of memory.
  45 +
42 46  
43 47 EXAMPLE
44 48 -------
... ...
doc/modbus_new_tcp_pi.txt
... ... @@ -40,6 +40,10 @@ ERRORS
40 40 The node string is empty or has been truncated. The service string is empty or
41 41 has been truncated.
42 42  
  43 +*ENOMEM*::
  44 +Out of memory. Possibly, the application hits its memory limit and/or whole
  45 +system is running out of memory.
  46 +
43 47  
44 48 EXAMPLE
45 49 -------
... ...
src/modbus-rtu.c
... ... @@ -1180,8 +1180,11 @@ static int _modbus_rtu_select(modbus_t *ctx, fd_set *rset,
1180 1180 }
1181 1181  
1182 1182 static void _modbus_rtu_free(modbus_t *ctx) {
1183   - free(((modbus_rtu_t*)ctx->backend_data)->device);
1184   - free(ctx->backend_data);
  1183 + if (ctx->backend_data) {
  1184 + free(((modbus_rtu_t *)ctx->backend_data)->device);
  1185 + free(ctx->backend_data);
  1186 + }
  1187 +
1185 1188 free(ctx);
1186 1189 }
1187 1190  
... ... @@ -1229,14 +1232,27 @@ modbus_t* modbus_new_rtu(const char *device,
1229 1232 }
1230 1233  
1231 1234 ctx = (modbus_t *)malloc(sizeof(modbus_t));
  1235 + if (ctx == NULL) {
  1236 + return NULL;
  1237 + }
  1238 +
1232 1239 _modbus_init_common(ctx);
1233 1240 ctx->backend = &_modbus_rtu_backend;
1234 1241 ctx->backend_data = (modbus_rtu_t *)malloc(sizeof(modbus_rtu_t));
  1242 + if (ctx->backend_data == NULL) {
  1243 + modbus_free(ctx);
  1244 + errno = ENOMEM;
  1245 + return NULL;
  1246 + }
1235 1247 ctx_rtu = (modbus_rtu_t *)ctx->backend_data;
1236   - ctx_rtu->device = NULL;
1237 1248  
1238 1249 /* Device name and \0 */
1239 1250 ctx_rtu->device = (char *)malloc((strlen(device) + 1) * sizeof(char));
  1251 + if (ctx_rtu->device == NULL) {
  1252 + modbus_free(ctx);
  1253 + errno = ENOMEM;
  1254 + return NULL;
  1255 + }
1240 1256 strcpy(ctx_rtu->device, device);
1241 1257  
1242 1258 ctx_rtu->baud = baud;
... ...
src/modbus-tcp.c
... ... @@ -799,6 +799,9 @@ modbus_t* modbus_new_tcp(const char *ip, int port)
799 799 #endif
800 800  
801 801 ctx = (modbus_t *)malloc(sizeof(modbus_t));
  802 + if (ctx == NULL) {
  803 + return NULL;
  804 + }
802 805 _modbus_init_common(ctx);
803 806  
804 807 /* Could be changed after to reach a remote serial Modbus device */
... ... @@ -807,6 +810,11 @@ modbus_t* modbus_new_tcp(const char *ip, int port)
807 810 ctx->backend = &_modbus_tcp_backend;
808 811  
809 812 ctx->backend_data = (modbus_tcp_t *)malloc(sizeof(modbus_tcp_t));
  813 + if (ctx->backend_data == NULL) {
  814 + modbus_free(ctx);
  815 + errno = ENOMEM;
  816 + return NULL;
  817 + }
810 818 ctx_tcp = (modbus_tcp_t *)ctx->backend_data;
811 819  
812 820 if (ip != NULL) {
... ... @@ -843,6 +851,9 @@ modbus_t* modbus_new_tcp_pi(const char *node, const char *service)
843 851 size_t ret_size;
844 852  
845 853 ctx = (modbus_t *)malloc(sizeof(modbus_t));
  854 + if (ctx == NULL) {
  855 + return NULL;
  856 + }
846 857 _modbus_init_common(ctx);
847 858  
848 859 /* Could be changed after to reach a remote serial Modbus device */
... ... @@ -851,6 +862,11 @@ modbus_t* modbus_new_tcp_pi(const char *node, const char *service)
851 862 ctx->backend = &_modbus_tcp_pi_backend;
852 863  
853 864 ctx->backend_data = (modbus_tcp_pi_t *)malloc(sizeof(modbus_tcp_pi_t));
  865 + if (ctx->backend_data == NULL) {
  866 + modbus_free(ctx);
  867 + errno = ENOMEM;
  868 + return NULL;
  869 + }
854 870 ctx_tcp_pi = (modbus_tcp_pi_t *)ctx->backend_data;
855 871  
856 872 if (node == NULL) {
... ...