Commit 7e1621de authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

ALSA: firewire-lib/bebob/oxfw: improve response evaluation for AV/C commands

In ALSA firewire stack, some AV/C commands are supported, including
vendor's extensions. Drivers includes response parser of each command,
according to its requirements, while the parser is written with loose
fashion in two points; error check and length check. This doesn't cause
any issues such as kernel corruption, but should be improved.

This commit modifies evaluations of return value on each parsers.
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 5b33504b
...@@ -31,13 +31,15 @@ int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id, ...@@ -31,13 +31,15 @@ int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
err = fcp_avc_transaction(unit, buf, 12, buf, 12, err = fcp_avc_transaction(unit, buf, 12, buf, 12,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
BIT(6) | BIT(7) | BIT(8)); BIT(6) | BIT(7) | BIT(8));
if (err > 0 && err < 9) if (err < 0)
;
else if (err < 9)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
else if (buf[0] == 0x0a) /* REJECTED */ else if (buf[0] == 0x0a) /* REJECTED */
err = -EINVAL; err = -EINVAL;
else if (err > 0) else
err = 0; err = 0;
kfree(buf); kfree(buf);
...@@ -67,7 +69,9 @@ int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id, ...@@ -67,7 +69,9 @@ int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
err = fcp_avc_transaction(unit, buf, 12, buf, 12, err = fcp_avc_transaction(unit, buf, 12, buf, 12,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
BIT(6) | BIT(8)); BIT(6) | BIT(8));
if (err > 0 && err < 9) if (err < 0)
;
else if (err < 9)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
...@@ -120,7 +124,9 @@ int avc_bridgeco_get_plug_type(struct fw_unit *unit, ...@@ -120,7 +124,9 @@ int avc_bridgeco_get_plug_type(struct fw_unit *unit,
err = fcp_avc_transaction(unit, buf, 12, buf, 12, err = fcp_avc_transaction(unit, buf, 12, buf, 12,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
BIT(6) | BIT(7) | BIT(9)); BIT(6) | BIT(7) | BIT(9));
if ((err >= 0) && (err < 8)) if (err < 0)
;
else if (err < 11)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
...@@ -150,7 +156,9 @@ int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit, ...@@ -150,7 +156,9 @@ int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
err = fcp_avc_transaction(unit, buf, 12, buf, 256, err = fcp_avc_transaction(unit, buf, 12, buf, 256,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(1) | BIT(2) | BIT(3) | BIT(4) |
BIT(5) | BIT(6) | BIT(7) | BIT(9)); BIT(5) | BIT(6) | BIT(7) | BIT(9));
if ((err >= 0) && (err < 8)) if (err < 0)
;
else if (err < 11)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
...@@ -187,7 +195,9 @@ int avc_bridgeco_get_plug_section_type(struct fw_unit *unit, ...@@ -187,7 +195,9 @@ int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
err = fcp_avc_transaction(unit, buf, 12, buf, 12, err = fcp_avc_transaction(unit, buf, 12, buf, 12,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
BIT(6) | BIT(7) | BIT(9) | BIT(10)); BIT(6) | BIT(7) | BIT(9) | BIT(10));
if ((err >= 0) && (err < 8)) if (err < 0)
;
else if (err < 12)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
...@@ -221,7 +231,9 @@ int avc_bridgeco_get_plug_input(struct fw_unit *unit, ...@@ -221,7 +231,9 @@ int avc_bridgeco_get_plug_input(struct fw_unit *unit,
err = fcp_avc_transaction(unit, buf, 16, buf, 16, err = fcp_avc_transaction(unit, buf, 16, buf, 16,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
BIT(6) | BIT(7)); BIT(6) | BIT(7));
if ((err >= 0) && (err < 8)) if (err < 0)
;
else if (err < 16)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
...@@ -260,7 +272,9 @@ int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit, ...@@ -260,7 +272,9 @@ int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit,
err = fcp_avc_transaction(unit, buf, 12, buf, *len, err = fcp_avc_transaction(unit, buf, 12, buf, *len,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
BIT(6) | BIT(7) | BIT(10)); BIT(6) | BIT(7) | BIT(10));
if ((err >= 0) && (err < 12)) if (err < 0)
;
else if (err < 12)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
......
...@@ -63,7 +63,9 @@ int avc_general_set_sig_fmt(struct fw_unit *unit, unsigned int rate, ...@@ -63,7 +63,9 @@ int avc_general_set_sig_fmt(struct fw_unit *unit, unsigned int rate,
/* do transaction and check buf[1-5] are the same against command */ /* do transaction and check buf[1-5] are the same against command */
err = fcp_avc_transaction(unit, buf, 8, buf, 8, err = fcp_avc_transaction(unit, buf, 8, buf, 8,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
if (err >= 0 && err < 8) if (err < 0)
;
else if (err < 8)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
...@@ -106,7 +108,9 @@ int avc_general_get_sig_fmt(struct fw_unit *unit, unsigned int *rate, ...@@ -106,7 +108,9 @@ int avc_general_get_sig_fmt(struct fw_unit *unit, unsigned int *rate,
/* do transaction and check buf[1-4] are the same against command */ /* do transaction and check buf[1-4] are the same against command */
err = fcp_avc_transaction(unit, buf, 8, buf, 8, err = fcp_avc_transaction(unit, buf, 8, buf, 8,
BIT(1) | BIT(2) | BIT(3) | BIT(4)); BIT(1) | BIT(2) | BIT(3) | BIT(4));
if (err >= 0 && err < 8) if (err < 0)
;
else if (err < 8)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
...@@ -154,7 +158,9 @@ int avc_general_get_plug_info(struct fw_unit *unit, unsigned int subunit_type, ...@@ -154,7 +158,9 @@ int avc_general_get_plug_info(struct fw_unit *unit, unsigned int subunit_type,
buf[3] = 0xff & subfunction; buf[3] = 0xff & subfunction;
err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2)); err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2));
if (err >= 0 && err < 8) if (err < 0)
;
else if (err < 8)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
......
...@@ -34,7 +34,9 @@ int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir, ...@@ -34,7 +34,9 @@ int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir,
err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10, err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
BIT(6) | BIT(7) | BIT(8)); BIT(6) | BIT(7) | BIT(8));
if ((err > 0) && (err < len + 10)) if (err < 0)
;
else if (err < len + 10)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
...@@ -77,7 +79,9 @@ int avc_stream_get_format(struct fw_unit *unit, ...@@ -77,7 +79,9 @@ int avc_stream_get_format(struct fw_unit *unit,
err = fcp_avc_transaction(unit, buf, 12, buf, *len, err = fcp_avc_transaction(unit, buf, 12, buf, *len,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
BIT(6) | BIT(7)); BIT(6) | BIT(7));
if ((err > 0) && (err < 10)) if (err < 0)
;
else if (err < 12)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
...@@ -139,7 +143,9 @@ int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate, ...@@ -139,7 +143,9 @@ int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate,
/* do transaction and check buf[1-5] are the same against command */ /* do transaction and check buf[1-5] are the same against command */
err = fcp_avc_transaction(unit, buf, 8, buf, 8, err = fcp_avc_transaction(unit, buf, 8, buf, 8,
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
if ((err > 0) && (err < 8)) if (err < 0)
;
else if (err < 8)
err = -EIO; err = -EIO;
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
err = -ENOSYS; err = -ENOSYS;
......
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