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
| @@ -53,6 +53,10 @@ ERRORS | @@ -53,6 +53,10 @@ ERRORS | ||
| 53 | *EINVAL*:: | 53 | *EINVAL*:: |
| 54 | An invalid argument was given. | 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 | EXAMPLE | 61 | EXAMPLE |
| 58 | ------- | 62 | ------- |
doc/modbus_new_tcp.txt
| @@ -39,6 +39,10 @@ ERRORS | @@ -39,6 +39,10 @@ ERRORS | ||
| 39 | *EINVAL*:: | 39 | *EINVAL*:: |
| 40 | An invalid IP address was given. | 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 | EXAMPLE | 47 | EXAMPLE |
| 44 | ------- | 48 | ------- |
doc/modbus_new_tcp_pi.txt
| @@ -40,6 +40,10 @@ ERRORS | @@ -40,6 +40,10 @@ ERRORS | ||
| 40 | The node string is empty or has been truncated. The service string is empty or | 40 | The node string is empty or has been truncated. The service string is empty or |
| 41 | has been truncated. | 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 | EXAMPLE | 48 | EXAMPLE |
| 45 | ------- | 49 | ------- |
src/modbus-rtu.c
| @@ -1180,8 +1180,11 @@ static int _modbus_rtu_select(modbus_t *ctx, fd_set *rset, | @@ -1180,8 +1180,11 @@ static int _modbus_rtu_select(modbus_t *ctx, fd_set *rset, | ||
| 1180 | } | 1180 | } |
| 1181 | 1181 | ||
| 1182 | static void _modbus_rtu_free(modbus_t *ctx) { | 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 | free(ctx); | 1188 | free(ctx); |
| 1186 | } | 1189 | } |
| 1187 | 1190 | ||
| @@ -1229,14 +1232,27 @@ modbus_t* modbus_new_rtu(const char *device, | @@ -1229,14 +1232,27 @@ modbus_t* modbus_new_rtu(const char *device, | ||
| 1229 | } | 1232 | } |
| 1230 | 1233 | ||
| 1231 | ctx = (modbus_t *)malloc(sizeof(modbus_t)); | 1234 | ctx = (modbus_t *)malloc(sizeof(modbus_t)); |
| 1235 | + if (ctx == NULL) { | ||
| 1236 | + return NULL; | ||
| 1237 | + } | ||
| 1238 | + | ||
| 1232 | _modbus_init_common(ctx); | 1239 | _modbus_init_common(ctx); |
| 1233 | ctx->backend = &_modbus_rtu_backend; | 1240 | ctx->backend = &_modbus_rtu_backend; |
| 1234 | ctx->backend_data = (modbus_rtu_t *)malloc(sizeof(modbus_rtu_t)); | 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 | ctx_rtu = (modbus_rtu_t *)ctx->backend_data; | 1247 | ctx_rtu = (modbus_rtu_t *)ctx->backend_data; |
| 1236 | - ctx_rtu->device = NULL; | ||
| 1237 | 1248 | ||
| 1238 | /* Device name and \0 */ | 1249 | /* Device name and \0 */ |
| 1239 | ctx_rtu->device = (char *)malloc((strlen(device) + 1) * sizeof(char)); | 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 | strcpy(ctx_rtu->device, device); | 1256 | strcpy(ctx_rtu->device, device); |
| 1241 | 1257 | ||
| 1242 | ctx_rtu->baud = baud; | 1258 | ctx_rtu->baud = baud; |
src/modbus-tcp.c
| @@ -799,6 +799,9 @@ modbus_t* modbus_new_tcp(const char *ip, int port) | @@ -799,6 +799,9 @@ modbus_t* modbus_new_tcp(const char *ip, int port) | ||
| 799 | #endif | 799 | #endif |
| 800 | 800 | ||
| 801 | ctx = (modbus_t *)malloc(sizeof(modbus_t)); | 801 | ctx = (modbus_t *)malloc(sizeof(modbus_t)); |
| 802 | + if (ctx == NULL) { | ||
| 803 | + return NULL; | ||
| 804 | + } | ||
| 802 | _modbus_init_common(ctx); | 805 | _modbus_init_common(ctx); |
| 803 | 806 | ||
| 804 | /* Could be changed after to reach a remote serial Modbus device */ | 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,6 +810,11 @@ modbus_t* modbus_new_tcp(const char *ip, int port) | ||
| 807 | ctx->backend = &_modbus_tcp_backend; | 810 | ctx->backend = &_modbus_tcp_backend; |
| 808 | 811 | ||
| 809 | ctx->backend_data = (modbus_tcp_t *)malloc(sizeof(modbus_tcp_t)); | 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 | ctx_tcp = (modbus_tcp_t *)ctx->backend_data; | 818 | ctx_tcp = (modbus_tcp_t *)ctx->backend_data; |
| 811 | 819 | ||
| 812 | if (ip != NULL) { | 820 | if (ip != NULL) { |
| @@ -843,6 +851,9 @@ modbus_t* modbus_new_tcp_pi(const char *node, const char *service) | @@ -843,6 +851,9 @@ modbus_t* modbus_new_tcp_pi(const char *node, const char *service) | ||
| 843 | size_t ret_size; | 851 | size_t ret_size; |
| 844 | 852 | ||
| 845 | ctx = (modbus_t *)malloc(sizeof(modbus_t)); | 853 | ctx = (modbus_t *)malloc(sizeof(modbus_t)); |
| 854 | + if (ctx == NULL) { | ||
| 855 | + return NULL; | ||
| 856 | + } | ||
| 846 | _modbus_init_common(ctx); | 857 | _modbus_init_common(ctx); |
| 847 | 858 | ||
| 848 | /* Could be changed after to reach a remote serial Modbus device */ | 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,6 +862,11 @@ modbus_t* modbus_new_tcp_pi(const char *node, const char *service) | ||
| 851 | ctx->backend = &_modbus_tcp_pi_backend; | 862 | ctx->backend = &_modbus_tcp_pi_backend; |
| 852 | 863 | ||
| 853 | ctx->backend_data = (modbus_tcp_pi_t *)malloc(sizeof(modbus_tcp_pi_t)); | 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 | ctx_tcp_pi = (modbus_tcp_pi_t *)ctx->backend_data; | 870 | ctx_tcp_pi = (modbus_tcp_pi_t *)ctx->backend_data; |
| 855 | 871 | ||
| 856 | if (node == NULL) { | 872 | if (node == NULL) { |