diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2017-04-03 08:13:55 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2017-04-05 15:37:23 -0400 |
commit | 7e1621de146fbed6172252f14a6a41b2c5999a93 (patch) | |
tree | 244737dfe7058e9e958aee74358526c2656d5106 | |
parent | 5b33504bada4d85092b69b3aaa7048c398b21dbb (diff) |
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: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/firewire/bebob/bebob_command.c | 30 | ||||
-rw-r--r-- | sound/firewire/fcp.c | 12 | ||||
-rw-r--r-- | sound/firewire/oxfw/oxfw-command.c | 12 |
3 files changed, 40 insertions, 14 deletions
diff --git a/sound/firewire/bebob/bebob_command.c b/sound/firewire/bebob/bebob_command.c index 9402cc15dbc1..f9b4225dd86f 100644 --- a/sound/firewire/bebob/bebob_command.c +++ b/sound/firewire/bebob/bebob_command.c | |||
@@ -31,13 +31,15 @@ int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id, | |||
31 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, | 31 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, |
32 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | 32 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | |
33 | BIT(6) | BIT(7) | BIT(8)); | 33 | BIT(6) | BIT(7) | BIT(8)); |
34 | if (err > 0 && err < 9) | 34 | if (err < 0) |
35 | ; | ||
36 | else if (err < 9) | ||
35 | err = -EIO; | 37 | err = -EIO; |
36 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 38 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
37 | err = -ENOSYS; | 39 | err = -ENOSYS; |
38 | else if (buf[0] == 0x0a) /* REJECTED */ | 40 | else if (buf[0] == 0x0a) /* REJECTED */ |
39 | err = -EINVAL; | 41 | err = -EINVAL; |
40 | else if (err > 0) | 42 | else |
41 | err = 0; | 43 | err = 0; |
42 | 44 | ||
43 | kfree(buf); | 45 | kfree(buf); |
@@ -67,7 +69,9 @@ int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id, | |||
67 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, | 69 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, |
68 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | 70 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | |
69 | BIT(6) | BIT(8)); | 71 | BIT(6) | BIT(8)); |
70 | if (err > 0 && err < 9) | 72 | if (err < 0) |
73 | ; | ||
74 | else if (err < 9) | ||
71 | err = -EIO; | 75 | err = -EIO; |
72 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 76 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
73 | err = -ENOSYS; | 77 | err = -ENOSYS; |
@@ -120,7 +124,9 @@ int avc_bridgeco_get_plug_type(struct fw_unit *unit, | |||
120 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, | 124 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, |
121 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | 125 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | |
122 | BIT(6) | BIT(7) | BIT(9)); | 126 | BIT(6) | BIT(7) | BIT(9)); |
123 | if ((err >= 0) && (err < 8)) | 127 | if (err < 0) |
128 | ; | ||
129 | else if (err < 11) | ||
124 | err = -EIO; | 130 | err = -EIO; |
125 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 131 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
126 | err = -ENOSYS; | 132 | err = -ENOSYS; |
@@ -150,7 +156,9 @@ int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit, | |||
150 | err = fcp_avc_transaction(unit, buf, 12, buf, 256, | 156 | err = fcp_avc_transaction(unit, buf, 12, buf, 256, |
151 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | | 157 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | |
152 | BIT(5) | BIT(6) | BIT(7) | BIT(9)); | 158 | BIT(5) | BIT(6) | BIT(7) | BIT(9)); |
153 | if ((err >= 0) && (err < 8)) | 159 | if (err < 0) |
160 | ; | ||
161 | else if (err < 11) | ||
154 | err = -EIO; | 162 | err = -EIO; |
155 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 163 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
156 | err = -ENOSYS; | 164 | err = -ENOSYS; |
@@ -187,7 +195,9 @@ int avc_bridgeco_get_plug_section_type(struct fw_unit *unit, | |||
187 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, | 195 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, |
188 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | 196 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | |
189 | BIT(6) | BIT(7) | BIT(9) | BIT(10)); | 197 | BIT(6) | BIT(7) | BIT(9) | BIT(10)); |
190 | if ((err >= 0) && (err < 8)) | 198 | if (err < 0) |
199 | ; | ||
200 | else if (err < 12) | ||
191 | err = -EIO; | 201 | err = -EIO; |
192 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 202 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
193 | err = -ENOSYS; | 203 | err = -ENOSYS; |
@@ -221,7 +231,9 @@ int avc_bridgeco_get_plug_input(struct fw_unit *unit, | |||
221 | err = fcp_avc_transaction(unit, buf, 16, buf, 16, | 231 | err = fcp_avc_transaction(unit, buf, 16, buf, 16, |
222 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | 232 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | |
223 | BIT(6) | BIT(7)); | 233 | BIT(6) | BIT(7)); |
224 | if ((err >= 0) && (err < 8)) | 234 | if (err < 0) |
235 | ; | ||
236 | else if (err < 16) | ||
225 | err = -EIO; | 237 | err = -EIO; |
226 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 238 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
227 | err = -ENOSYS; | 239 | err = -ENOSYS; |
@@ -260,7 +272,9 @@ int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit, | |||
260 | err = fcp_avc_transaction(unit, buf, 12, buf, *len, | 272 | err = fcp_avc_transaction(unit, buf, 12, buf, *len, |
261 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | 273 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | |
262 | BIT(6) | BIT(7) | BIT(10)); | 274 | BIT(6) | BIT(7) | BIT(10)); |
263 | if ((err >= 0) && (err < 12)) | 275 | if (err < 0) |
276 | ; | ||
277 | else if (err < 12) | ||
264 | err = -EIO; | 278 | err = -EIO; |
265 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 279 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
266 | err = -ENOSYS; | 280 | err = -ENOSYS; |
diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c index cce19768f43d..61dda828f767 100644 --- a/sound/firewire/fcp.c +++ b/sound/firewire/fcp.c | |||
@@ -63,7 +63,9 @@ int avc_general_set_sig_fmt(struct fw_unit *unit, unsigned int rate, | |||
63 | /* do transaction and check buf[1-5] are the same against command */ | 63 | /* do transaction and check buf[1-5] are the same against command */ |
64 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, | 64 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, |
65 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); | 65 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); |
66 | if (err >= 0 && err < 8) | 66 | if (err < 0) |
67 | ; | ||
68 | else if (err < 8) | ||
67 | err = -EIO; | 69 | err = -EIO; |
68 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 70 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
69 | err = -ENOSYS; | 71 | err = -ENOSYS; |
@@ -106,7 +108,9 @@ int avc_general_get_sig_fmt(struct fw_unit *unit, unsigned int *rate, | |||
106 | /* do transaction and check buf[1-4] are the same against command */ | 108 | /* do transaction and check buf[1-4] are the same against command */ |
107 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, | 109 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, |
108 | BIT(1) | BIT(2) | BIT(3) | BIT(4)); | 110 | BIT(1) | BIT(2) | BIT(3) | BIT(4)); |
109 | if (err >= 0 && err < 8) | 111 | if (err < 0) |
112 | ; | ||
113 | else if (err < 8) | ||
110 | err = -EIO; | 114 | err = -EIO; |
111 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 115 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
112 | err = -ENOSYS; | 116 | err = -ENOSYS; |
@@ -154,7 +158,9 @@ int avc_general_get_plug_info(struct fw_unit *unit, unsigned int subunit_type, | |||
154 | buf[3] = 0xff & subfunction; | 158 | buf[3] = 0xff & subfunction; |
155 | 159 | ||
156 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2)); | 160 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2)); |
157 | if (err >= 0 && err < 8) | 161 | if (err < 0) |
162 | ; | ||
163 | else if (err < 8) | ||
158 | err = -EIO; | 164 | err = -EIO; |
159 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 165 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
160 | err = -ENOSYS; | 166 | err = -ENOSYS; |
diff --git a/sound/firewire/oxfw/oxfw-command.c b/sound/firewire/oxfw/oxfw-command.c index 12ef3253bc89..ac3e2e301666 100644 --- a/sound/firewire/oxfw/oxfw-command.c +++ b/sound/firewire/oxfw/oxfw-command.c | |||
@@ -34,7 +34,9 @@ int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir, | |||
34 | err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10, | 34 | err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10, |
35 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | 35 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | |
36 | BIT(6) | BIT(7) | BIT(8)); | 36 | BIT(6) | BIT(7) | BIT(8)); |
37 | if ((err > 0) && (err < len + 10)) | 37 | if (err < 0) |
38 | ; | ||
39 | else if (err < len + 10) | ||
38 | err = -EIO; | 40 | err = -EIO; |
39 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 41 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
40 | err = -ENOSYS; | 42 | err = -ENOSYS; |
@@ -77,7 +79,9 @@ int avc_stream_get_format(struct fw_unit *unit, | |||
77 | err = fcp_avc_transaction(unit, buf, 12, buf, *len, | 79 | err = fcp_avc_transaction(unit, buf, 12, buf, *len, |
78 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | 80 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | |
79 | BIT(6) | BIT(7)); | 81 | BIT(6) | BIT(7)); |
80 | if ((err > 0) && (err < 10)) | 82 | if (err < 0) |
83 | ; | ||
84 | else if (err < 12) | ||
81 | err = -EIO; | 85 | err = -EIO; |
82 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 86 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
83 | err = -ENOSYS; | 87 | err = -ENOSYS; |
@@ -139,7 +143,9 @@ int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate, | |||
139 | /* do transaction and check buf[1-5] are the same against command */ | 143 | /* do transaction and check buf[1-5] are the same against command */ |
140 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, | 144 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, |
141 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); | 145 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); |
142 | if ((err > 0) && (err < 8)) | 146 | if (err < 0) |
147 | ; | ||
148 | else if (err < 8) | ||
143 | err = -EIO; | 149 | err = -EIO; |
144 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | 150 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ |
145 | err = -ENOSYS; | 151 | err = -ENOSYS; |