Commit c258137adcc6182a50effb2dd1d77c54ac0798a0
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>
Showing
5 changed files
with
47 additions
and
3 deletions
doc/modbus_new_rtu.txt
doc/modbus_new_tcp.txt
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) { | ... | ... |