[ofa-general] [PATCH] libibmad: fix snprintf() usage
Sasha Khapyorsky
sashak at voltaire.com
Sun Jun 29 09:09:16 PDT 2008
snprintf() can return a value larger than provided buffer size, so this
case should be checked.
Also there is rework of dump_linkwidth() and dump_linkspeed() functions
which addresses this requirement.
Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
libibmad/src/dump.c | 71 +++++++++++++++++++++++++++++++------------------
libibmad/src/portid.c | 4 +++
2 files changed, 49 insertions(+), 26 deletions(-)
diff --git a/libibmad/src/dump.c b/libibmad/src/dump.c
index b2798b8..61933ee 100644
--- a/libibmad/src/dump.c
+++ b/libibmad/src/dump.c
@@ -193,21 +193,23 @@ mad_dump_linkwidth(char *buf, int bufsz, void *val, int valsz)
static void
dump_linkwidth(char *buf, int bufsz, int width)
{
- char *s = buf, *e = s + bufsz;
+ int n = 0;
if (width & 0x1)
- s += snprintf(s, e - s, "1X or ");
- if (s < e && (width & 0x2))
- s += snprintf(s, e - s, "4X or ");
- if (s < e && (width & 0x4))
- s += snprintf(s, e - s, "8X or ");
- if (s < e && (width & 0x8))
- s += snprintf(s, e - s, "12X or ");
-
- if ((width >> 4) || s == buf)
- s += snprintf(s, e - s, "undefined (%d)", width);
- else
- s[-4] = 0;
+ n += snprintf(buf + n, bufsz - n, "1X or ");
+ if (n < bufsz && (width & 0x2))
+ n += snprintf(buf + n, bufsz - n, "4X or ");
+ if (n < bufsz && (width & 0x4))
+ n += snprintf(buf + n, bufsz - n, "8X or ");
+ if (n < bufsz && (width & 0x8))
+ n += snprintf(buf + n, bufsz - n, "12X or ");
+
+ if (n >= bufsz)
+ return;
+ else if (width == 0 || (width >> 4))
+ snprintf(buf + n, bufsz - n, "undefined (%d)", width);
+ else if (bufsz > 3)
+ buf[n-4] = '\0';
}
void
@@ -265,19 +267,25 @@ mad_dump_linkspeed(char *buf, int bufsz, void *val, int valsz)
static void
dump_linkspeed(char *buf, int bufsz, int speed)
{
- char *s = buf, *e = s + bufsz;
+ int n = 0;
if (speed & 0x1)
- s += snprintf(s, e - s, "2.5 Gbps or ");
- if (s < e && (speed & 0x2))
- s += snprintf(s, e - s, "5.0 Gbps or ");
- if (s < e && (speed & 0x4))
- s += snprintf(s, e - s, "10.0 Gbps or ");
-
- if ((speed >> 3) || s == buf)
- s += snprintf(s, e - s, "undefined (%d)", speed);
- else
- s[-4] = 0;
+ n += snprintf(buf + n, bufsz - n, "2.5 Gbps or ");
+ if (n < bufsz && (speed & 0x2))
+ n += snprintf(buf + n, bufsz - n, "5.0 Gbps or ");
+ if (n < bufsz && (speed & 0x4))
+ n += snprintf(buf + n, bufsz - n, "10.0 Gbps or ");
+
+ if (n >= bufsz)
+ return;
+ else if (speed == 0 || (speed >> 3)) {
+ n += snprintf(buf + n, bufsz - n, "undefined (%d)", speed);
+ if (n >= bufsz)
+ return;
+ } else if (bufsz > 3) {
+ buf[n-4] = '\0';
+ n -= 4;
+ }
switch (speed) {
case 1:
@@ -287,7 +295,7 @@ dump_linkspeed(char *buf, int bufsz, int speed)
break;
default:
if (!(speed >> 3))
- snprintf(s, e - s, " (IBA extension)");
+ snprintf(buf + n, bufsz - n, " (IBA extension)");
break;
}
}
@@ -613,6 +621,8 @@ mad_dump_sltovl(char *buf, int bufsz, void *val, int valsz)
for (i = 0; i < 16; i++) {
ib_slvl_get_i(p_slvl_tbl, i, &vl);
n += snprintf(buf + n, bufsz - n, "%2u|", vl);
+ if (n >= bufsz)
+ break;
}
snprintf(buf + n, bufsz - n, "\n");
}
@@ -627,15 +637,24 @@ mad_dump_vlarbitration(char *buf, int bufsz, void *val, int num)
num /= sizeof(p_vla_tbl->vl_entry[0]);
n = snprintf(buf, bufsz, "\nVL : |");
+ if (n >= bufsz)
+ return;
for (i = 0; i < num; i++) {
ib_vl_arb_get_vl(p_vla_tbl->vl_entry[i].res_vl, &vl);
n += snprintf(buf + n, bufsz - n, "0x%-2X|", vl);
+ if (n >= bufsz)
+ return;
}
n += snprintf(buf + n, bufsz - n, "\nWEIGHT: |");
- for (i = 0; i < num; i++)
+ if (n >= bufsz)
+ return;
+ for (i = 0; i < num; i++) {
n += snprintf(buf + n, bufsz - n, "0x%-2X|",
p_vla_tbl->vl_entry[i].weight);
+ if (n >= bufsz)
+ return;
+ }
snprintf(buf + n, bufsz - n, "\n");
}
diff --git a/libibmad/src/portid.c b/libibmad/src/portid.c
index c6b5135..f8114f2 100644
--- a/libibmad/src/portid.c
+++ b/libibmad/src/portid.c
@@ -115,8 +115,12 @@ drpath2str(ib_dr_path_t *path, char *dstr, size_t dstr_size)
int i = 0;
int rc = snprintf(dstr, dstr_size, "slid %d; dlid %d; %d",
path->drslid, path->drdlid, path->p[0]);
+ if (rc >= dstr_size)
+ return dstr;
for (i = 1; i <= path->cnt; i++) {
rc += snprintf(dstr+rc, dstr_size-rc, ",%d", path->p[i]);
+ if (rc >= dstr_size)
+ break;
}
return (dstr);
}
--
1.5.5.1.178.g1f811
More information about the general
mailing list