summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gsmd/extrsp.h4
-rw-r--r--include/gsmd/gsmd.h1
-rw-r--r--include/gsmd/strl.h12
-rw-r--r--src/gsmd/Makefile.am2
-rw-r--r--src/gsmd/atcmd.c2
-rw-r--r--src/gsmd/ext_response.c6
-rw-r--r--src/gsmd/gsmd.c2
-rw-r--r--src/gsmd/operator_cache.c2
-rw-r--r--src/gsmd/strl.c86
-rw-r--r--src/gsmd/usock.c43
-rw-r--r--src/gsmd/vendor_ti.c4
-rw-r--r--src/gsmd/vendor_tihtc.c4
12 files changed, 134 insertions, 34 deletions
diff --git a/include/gsmd/extrsp.h b/include/gsmd/extrsp.h
index 1f6e6a5..f7c1430 100644
--- a/include/gsmd/extrsp.h
+++ b/include/gsmd/extrsp.h
@@ -7,6 +7,8 @@
/* how many individual sub-ranges can one range contain */
#define GSM_EXTRSP_MAX_RANGES 16
+/* how many character we are going to store in string buffer */
+#define GSM_EXTRSP_MAX_STRBUF 64
struct gsm_extrsp_range_item {
int min;
@@ -28,7 +30,7 @@ struct gsm_extrsp_tok {
struct gsm_extrsp_range_item item[GSM_EXTRSP_MAX_RANGES];
int num_items;
} range;
- char string[64];
+ char string[GSM_EXTRSP_MAX_STRBUF];
int numeric;
} u;
};
diff --git a/include/gsmd/gsmd.h b/include/gsmd/gsmd.h
index 585d78d..0521dd5 100644
--- a/include/gsmd/gsmd.h
+++ b/include/gsmd/gsmd.h
@@ -12,6 +12,7 @@
#include <gsmd/vendorplugin.h>
#include <gsmd/select.h>
#include <gsmd/state.h>
+#include <gsmd/strl.h>
void *gsmd_tallocs;
diff --git a/include/gsmd/strl.h b/include/gsmd/strl.h
new file mode 100644
index 0000000..de96ab4
--- /dev/null
+++ b/include/gsmd/strl.h
@@ -0,0 +1,12 @@
+#ifndef __GSMD_STRL_H
+#define __GSMD_STRL_H
+
+#ifdef __GSMD__
+
+/* safe strcpy and strcat versions */
+extern size_t strlcpy(char *dest, const char *src, size_t size);
+extern size_t strlcat(char *dest, const char *src, size_t count);
+
+#endif /* __GSMD__ */
+
+#endif
diff --git a/src/gsmd/Makefile.am b/src/gsmd/Makefile.am
index cd83b83..01d6a8d 100644
--- a/src/gsmd/Makefile.am
+++ b/src/gsmd/Makefile.am
@@ -18,7 +18,7 @@ sbin_PROGRAMS = gsmd
gsmd_CFLAGS = -D PLUGINDIR=\"$(plugindir)\"
gsmd_SOURCES = gsmd.c atcmd.c select.c machine.c vendor.c unsolicited.c log.c \
usock.c talloc.c timer.c operator_cache.c ext_response.c \
- sms_cb.c sms_pdu.c
+ sms_cb.c sms_pdu.c strl.c
gsmd_LDADD = -ldl
gsmd_LDFLAGS = -Wl,--export-dynamic
diff --git a/src/gsmd/atcmd.c b/src/gsmd/atcmd.c
index 8d71268..51c1722 100644
--- a/src/gsmd/atcmd.c
+++ b/src/gsmd/atcmd.c
@@ -619,7 +619,7 @@ struct gsmd_atcmd *atcmd_fill(const char *cmd, int rlen,
atcmd->cb = cb;
atcmd->resp = NULL;
atcmd->timeout = NULL;
- strncpy(atcmd->buf, cmd, buflen-1);
+ strlcpy(atcmd->buf, cmd, buflen);
if (!ct)
atcmd->create_timer_func = discard_timer;
diff --git a/src/gsmd/ext_response.c b/src/gsmd/ext_response.c
index e8b2ab3..0736b6e 100644
--- a/src/gsmd/ext_response.c
+++ b/src/gsmd/ext_response.c
@@ -122,12 +122,8 @@ struct gsm_extrsp *extrsp_parse(const void *ctx, const char *input)
break;
case TOKEN_STRING:
if (*cur == '"') {
- int len = strlen(buf);
- if (len > sizeof(cur_token->u.string)-1)
- len = sizeof(cur_token->u.string)-1;
-
/* end of string token */
- strncpy(cur_token->u.string, buf, len);
+ strlcpy(cur_token->u.string, buf, GSM_EXTRSP_MAX_STRBUF);
er->num_tokens++;
state = TOKEN_STRING_LASTQUOTE;
} else {
diff --git a/src/gsmd/gsmd.c b/src/gsmd/gsmd.c
index c11e59f..af6c4a3 100644
--- a/src/gsmd/gsmd.c
+++ b/src/gsmd/gsmd.c
@@ -152,7 +152,7 @@ static int gsmd_get_imsi_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
struct gsmd *g = ctx;
DEBUGP("imsi : %s\n", resp);
- strcpy(g->imsi, resp);
+ strlcpy(g->imsi, resp, sizeof(g->imsi));
return 0;
}
diff --git a/src/gsmd/operator_cache.c b/src/gsmd/operator_cache.c
index e680706..e37310c 100644
--- a/src/gsmd/operator_cache.c
+++ b/src/gsmd/operator_cache.c
@@ -82,7 +82,7 @@ int gsmd_opname_add(struct gsmd *g, const char *numeric_bcd_string,
strncpy(mcc, numeric_bcd_string, 3);
strncpy(mnc, numeric_bcd_string+3, 2);
- strncpy(op->alnum_long, alnum_long, sizeof(op->alnum_long-1));
+ strlcpy(op->alnum_long, alnum_long, sizeof(op->alnum_long));
op->numeric.mcc = atoi(mcc);
op->numeric.mnc = atoi(mnc);
diff --git a/src/gsmd/strl.c b/src/gsmd/strl.c
new file mode 100644
index 0000000..cf20ef0
--- /dev/null
+++ b/src/gsmd/strl.c
@@ -0,0 +1,86 @@
+/* safe strcpy and strcat versions
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright (C) 2008 by Paulius Zaleckas, JSC Teltonika
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <string.h>
+
+#include "gsmd.h"
+#include <gsmd/gsmd.h>
+
+/**
+ * strlcpy - Copy a %NUL terminated string into a sized buffer
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @size: size of destination buffer
+ *
+ * Compatible with *BSD: the result is always a valid
+ * NUL-terminated string that fits in the buffer (unless,
+ * of course, the buffer size is zero). It does not pad
+ * out the result like strncpy() does.
+ */
+size_t strlcpy(char *dest, const char *src, size_t size)
+{
+ size_t ret = strlen(src);
+
+ if (size) {
+ size_t len;
+ if (ret >= size) {
+ len = size - 1;
+ DEBUGP("\"%s\" was truncated by %i characters\n", src,
+ ret - len);
+ }
+ else
+ len = ret;
+ memcpy(dest, src, len);
+ dest[len] = '\0';
+ }
+ return ret;
+}
+
+/**
+ * strlcat - Append a length-limited, %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ * @count: The size of the destination buffer.
+ */
+size_t strlcat(char *dest, const char *src, size_t count)
+{
+ size_t dsize = strlen(dest);
+ size_t len = strlen(src);
+ size_t res = dsize + len;
+
+ /* This would be a bug */
+ if (dsize >= count) {
+ DEBUGP("Length of destination string > provided buffer size!\n");
+ return 0;
+ }
+
+ dest += dsize;
+ count -= dsize;
+ if (len >= count) {
+ len = count - 1;
+ DEBUGP("\"%s\" was truncated by %i characters\n", src,
+ res - len);
+ }
+ memcpy(dest, src, len);
+ dest[len] = 0;
+ return res;
+}
+
diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c
index 0faef65..c9f549d 100644
--- a/src/gsmd/usock.c
+++ b/src/gsmd/usock.c
@@ -160,7 +160,7 @@ static int voicecall_get_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
gcs.stat = er->tokens[2].u.numeric;
gcs.mode = er->tokens[3].u.numeric;
gcs.mpty = er->tokens[4].u.numeric;
- strcpy(gcs.number, er->tokens[5].u.string);
+ strlcpy(gcs.number, er->tokens[5].u.string, GSMD_ADDR_MAXLEN+1);
gcs.type = er->tokens[6].u.numeric;
}
else if ( er->num_tokens == 8 &&
@@ -186,9 +186,9 @@ static int voicecall_get_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
gcs.stat = er->tokens[2].u.numeric;
gcs.mode = er->tokens[3].u.numeric;
gcs.mpty = er->tokens[4].u.numeric;
- strcpy(gcs.number, er->tokens[5].u.string);
+ strlcpy(gcs.number, er->tokens[5].u.string, GSMD_ADDR_MAXLEN+1);
gcs.type = er->tokens[6].u.numeric;
- strncpy(gcs.alpha, er->tokens[7].u.string, 8+1);
+ strlcpy(gcs.alpha, er->tokens[7].u.string, GSMD_ALPHA_MAXLEN+1);
}
else {
DEBUGP("Invalid Input : Parse error\n");
@@ -257,7 +257,7 @@ static int voicecall_fwd_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
gcfs.status = er->tokens[0].u.numeric;
gcfs.classx = er->tokens[1].u.numeric;
- strcpy(gcfs.addr.number, er->tokens[2].u.string);
+ strlcpy(gcfs.addr.number, er->tokens[2].u.string, GSMD_ADDR_MAXLEN+1);
gcfs.addr.type = er->tokens[3].u.numeric;
}
else if ( er->num_tokens == 7 &&
@@ -271,7 +271,7 @@ static int voicecall_fwd_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
gcfs.status = er->tokens[0].u.numeric;
gcfs.classx = er->tokens[1].u.numeric;
- strcpy(gcfs.addr.number, er->tokens[2].u.string);
+ strlcpy(gcfs.addr.number, er->tokens[2].u.string, GSMD_ADDR_MAXLEN+1);
gcfs.addr.type = er->tokens[3].u.numeric;
gcfs.time = er->tokens[6].u.numeric;
}
@@ -560,18 +560,18 @@ static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
if (!cmd)
return -ENOMEM;
- strncat(cmd->buf, gp->pin, sizeof(gp->pin));
+ strlcat(cmd->buf, gp->pin, cmd->buflen);
switch (gp->type) {
case GSMD_PIN_SIM_PUK:
case GSMD_PIN_SIM_PUK2:
- strcat(cmd->buf, "\",\"");
- strncat(cmd->buf, gp->newpin, sizeof(gp->newpin));
+ strlcat(cmd->buf, "\",\"", cmd->buflen);
+ strlcat(cmd->buf, gp->newpin, cmd->buflen);
break;
default:
break;
}
- strcat(cmd->buf, "\"");
+ strlcat(cmd->buf, "\"", cmd->buflen);
break;
case GSMD_PIN_GET_STATUS:
cmd = atcmd_fill("AT+CPIN?", 8 + 1, &get_cpin_cb, gu, 0, NULL);
@@ -718,7 +718,7 @@ static int network_vmail_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
er->tokens[1].type == GSMD_ECMD_RTT_STRING &&
er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC) {
vmail.enable = er->tokens[0].u.numeric;
- strcpy(vmail.addr.number, er->tokens[1].u.string);
+ strlcpy(vmail.addr.number, er->tokens[1].u.string, GSMD_ADDR_MAXLEN+1);
vmail.addr.type = er->tokens[2].u.numeric;
}
rc = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_VMAIL_GET,
@@ -824,7 +824,7 @@ static int network_oper_n_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
er->tokens[2].type == GSMD_ECMD_RTT_STRING ) {
- strcpy(buf, er->tokens[2].u.string);
+ strlcpy(buf, er->tokens[2].u.string, sizeof(buf));
}
else {
DEBUGP("Invalid Input : Parse error\n");
@@ -896,9 +896,12 @@ static int network_opers_parse(const char *str, struct gsmd_msg_oper **out)
*/
out2->stat = er->tokens[0].u.numeric;
- strcpy(out2->opname_longalpha, er->tokens[1].u.string);
- strcpy(out2->opname_shortalpha, er->tokens[2].u.string);
- strcpy(out2->opname_num, er->tokens[3].u.string);
+ strlcpy(out2->opname_longalpha, er->tokens[1].u.string,
+ sizeof(out2->opname_longalpha));
+ strlcpy(out2->opname_shortalpha, er->tokens[2].u.string,
+ sizeof(out2->opname_shortalpha));
+ strlcpy(out2->opname_num, er->tokens[3].u.string,
+ sizeof(out2->opname_num));
}
else {
DEBUGP("Invalid Input : Parse error\n");
@@ -1131,9 +1134,9 @@ static int phonebook_find_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
*/
gps.pb.index = er->tokens[0].u.numeric;
- strcpy(gps.pb.numb, er->tokens[1].u.string);
+ strlcpy(gps.pb.numb, er->tokens[1].u.string, GSMD_PB_NUMB_MAXLEN+1);
gps.pb.type = er->tokens[2].u.numeric;
- strcpy(gps.pb.text, er->tokens[3].u.string);
+ strlcpy(gps.pb.text, er->tokens[3].u.string, GSMD_PB_TEXT_MAXLEN+1);
}
else {
DEBUGP("Invalid Input : Parse error\n");
@@ -1180,9 +1183,9 @@ static int phonebook_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
*/
gp.index = er->tokens[0].u.numeric;
- strcpy(gp.numb, er->tokens[1].u.string);
+ strlcpy(gp.numb, er->tokens[1].u.string, GSMD_PB_NUMB_MAXLEN+1);
gp.type = er->tokens[2].u.numeric;
- strcpy(gp.text, er->tokens[3].u.string);
+ strlcpy(gp.text, er->tokens[3].u.string, GSMD_PB_TEXT_MAXLEN+1);
}
else {
DEBUGP("Invalid Input : Parse error\n");
@@ -1231,9 +1234,9 @@ static int phonebook_readrg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
*/
gps.pb.index = er->tokens[0].u.numeric;
- strcpy(gps.pb.numb, er->tokens[1].u.string);
+ strlcpy(gps.pb.numb, er->tokens[1].u.string, GSMD_PB_NUMB_MAXLEN+1);
gps.pb.type = er->tokens[2].u.numeric;
- strcpy(gps.pb.text, er->tokens[3].u.string);
+ strlcpy(gps.pb.text, er->tokens[3].u.string, GSMD_PB_TEXT_MAXLEN+1);
}
else {
DEBUGP("Invalid Input : Parse error\n");
diff --git a/src/gsmd/vendor_ti.c b/src/gsmd/vendor_ti.c
index 219f23e..5c27c23 100644
--- a/src/gsmd/vendor_ti.c
+++ b/src/gsmd/vendor_ti.c
@@ -68,7 +68,7 @@ static int cpri_parse(const char *buf, int len, const char *param, struct gsmd *
char *tok1, *tok2;
char tx_buf[20];
- strcpy(tx_buf, buf);
+ strlcpy(tx_buf, buf, sizeof(tx_buf));
tok1 = strtok(tx_buf, ",");
if (!tok1)
return -EIO;
@@ -122,7 +122,7 @@ static int cpi_parse(const char *buf, int len, const char *param, struct gsmd *g
sizeof(*aux));
char tx_buf[64];
- strcpy(tx_buf, buf);
+ strlcpy(tx_buf, buf, sizeof(tx_buf));
DEBUGP("entering cpi_parse param=`%s'\n", param);
if (!ucmd)
return -EINVAL;
diff --git a/src/gsmd/vendor_tihtc.c b/src/gsmd/vendor_tihtc.c
index b7c284c..cf2a3c2 100644
--- a/src/gsmd/vendor_tihtc.c
+++ b/src/gsmd/vendor_tihtc.c
@@ -85,7 +85,7 @@ static int cpri_parse(const char *buf, int len, const char *param, struct gsmd *
char *tok1, *tok2;
char tx_buf[20];
- strcpy(tx_buf, buf);
+ strlcpy(tx_buf, buf, sizeof(tx_buf));
tok1 = strtok(tx_buf, ",");
if (!tok1)
return -EIO;
@@ -132,7 +132,7 @@ static int cpi_parse(const char *buf, int len, const char *param, struct gsmd *g
sizeof(*aux));
char tx_buf[64];
- strcpy(tx_buf, buf);
+ strlcpy(tx_buf, buf, sizeof(tx_buf));
DEBUGP("entering cpi_parse param=`%s'\n", param);
if (!ucmd)
return -EINVAL;
personal git repositories of Harald Welte. Your mileage may vary