Commit 048a7f8b authored by Jean Delvare's avatar Jean Delvare Committed by David S. Miller

s390: qeth: Fix potential array overrun in cmd/rc lookup

Functions qeth_get_ipa_msg and qeth_get_ipa_cmd_name are modifying
the last member of global arrays without any locking that I can see.
If two instances of either function are running at the same time,
it could cause a race ultimately leading to an array overrun (the
contents of the last entry of the array is the only guarantee that
the loop will ever stop).

Performing the lookups without modifying the arrays is admittedly
slower (two comparisons per iteration instead of one) but these
are operations which are rare (should only be needed in error
cases or when debugging, not during successful operation) and it
seems still less costly than introducing a mutex to protect the
arrays in question.

As a side bonus, it allows us to declare both arrays as const data.
Signed-off-by: default avatarJean Delvare <jdelvare@suse.de>
Cc: Julian Wiedmann <jwi@linux.ibm.com>
Cc: Ursula Braun <ubraun@linux.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 065a2cdc
...@@ -610,7 +610,7 @@ static void qeth_put_reply(struct qeth_reply *reply) ...@@ -610,7 +610,7 @@ static void qeth_put_reply(struct qeth_reply *reply)
static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc, static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc,
struct qeth_card *card) struct qeth_card *card)
{ {
char *ipa_name; const char *ipa_name;
int com = cmd->hdr.command; int com = cmd->hdr.command;
ipa_name = qeth_get_ipa_cmd_name(com); ipa_name = qeth_get_ipa_cmd_name(com);
if (rc) if (rc)
......
...@@ -148,10 +148,10 @@ EXPORT_SYMBOL_GPL(IPA_PDU_HEADER); ...@@ -148,10 +148,10 @@ EXPORT_SYMBOL_GPL(IPA_PDU_HEADER);
struct ipa_rc_msg { struct ipa_rc_msg {
enum qeth_ipa_return_codes rc; enum qeth_ipa_return_codes rc;
char *msg; const char *msg;
}; };
static struct ipa_rc_msg qeth_ipa_rc_msg[] = { static const struct ipa_rc_msg qeth_ipa_rc_msg[] = {
{IPA_RC_SUCCESS, "success"}, {IPA_RC_SUCCESS, "success"},
{IPA_RC_NOTSUPP, "Command not supported"}, {IPA_RC_NOTSUPP, "Command not supported"},
{IPA_RC_IP_TABLE_FULL, "Add Addr IP Table Full - ipv6"}, {IPA_RC_IP_TABLE_FULL, "Add Addr IP Table Full - ipv6"},
...@@ -219,22 +219,23 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = { ...@@ -219,22 +219,23 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc) const char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc)
{ {
int x = 0; int x;
qeth_ipa_rc_msg[ARRAY_SIZE(qeth_ipa_rc_msg) - 1].rc = rc;
while (qeth_ipa_rc_msg[x].rc != rc) for (x = 0; x < ARRAY_SIZE(qeth_ipa_rc_msg) - 1; x++)
x++; if (qeth_ipa_rc_msg[x].rc == rc)
return qeth_ipa_rc_msg[x].msg;
return qeth_ipa_rc_msg[x].msg; return qeth_ipa_rc_msg[x].msg;
} }
struct ipa_cmd_names { struct ipa_cmd_names {
enum qeth_ipa_cmds cmd; enum qeth_ipa_cmds cmd;
char *name; const char *name;
}; };
static struct ipa_cmd_names qeth_ipa_cmd_names[] = { static const struct ipa_cmd_names qeth_ipa_cmd_names[] = {
{IPA_CMD_STARTLAN, "startlan"}, {IPA_CMD_STARTLAN, "startlan"},
{IPA_CMD_STOPLAN, "stoplan"}, {IPA_CMD_STOPLAN, "stoplan"},
{IPA_CMD_SETVMAC, "setvmac"}, {IPA_CMD_SETVMAC, "setvmac"},
...@@ -266,11 +267,12 @@ static struct ipa_cmd_names qeth_ipa_cmd_names[] = { ...@@ -266,11 +267,12 @@ static struct ipa_cmd_names qeth_ipa_cmd_names[] = {
{IPA_CMD_UNKNOWN, "unknown"}, {IPA_CMD_UNKNOWN, "unknown"},
}; };
char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd) const char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd)
{ {
int x = 0; int x;
qeth_ipa_cmd_names[ARRAY_SIZE(qeth_ipa_cmd_names) - 1].cmd = cmd;
while (qeth_ipa_cmd_names[x].cmd != cmd) for (x = 0; x < ARRAY_SIZE(qeth_ipa_cmd_names) - 1; x++)
x++; if (qeth_ipa_cmd_names[x].cmd == cmd)
return qeth_ipa_cmd_names[x].name;
return qeth_ipa_cmd_names[x].name; return qeth_ipa_cmd_names[x].name;
} }
...@@ -797,8 +797,8 @@ enum qeth_ipa_arp_return_codes { ...@@ -797,8 +797,8 @@ enum qeth_ipa_arp_return_codes {
QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008, QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008,
}; };
extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc); extern const char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd); extern const char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
#define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \ #define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
sizeof(struct qeth_ipacmd_setassparms_hdr)) sizeof(struct qeth_ipacmd_setassparms_hdr))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment