Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1448066 > unrolled thread
| Started by | tom.ty89@gmail.com |
|---|---|
| First post | 2016-07-21 20:50 +0200 |
| Last post | 2016-07-22 01:40 +0200 |
| Articles | 14 — 4 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH resend 2/5] libata-scsi: fix read-only bits checking in ata_mselect_*() tom.ty89@gmail.com - 2016-07-21 20:50 +0200
[PATCH resend 3/5] libata-scsi: fix overflow in mode page copy tom.ty89@gmail.com - 2016-07-21 20:50 +0200
[PATCH resend 4/5] libata-scsi: have all checks done before calling ata_mselect_*() tom.ty89@gmail.com - 2016-07-21 20:50 +0200
Re: [PATCH resend 3/5] libata-scsi: fix overflow in mode page copy Tejun Heo <tj@kernel.org> - 2016-07-21 23:20 +0200
Re: [PATCH resend 3/5] libata-scsi: fix overflow in mode page copy Tom Yan <tom.ty89@gmail.com> - 2016-07-21 23:40 +0200
Re: [PATCH resend 3/5] libata-scsi: fix overflow in mode page copy Tejun Heo <tj@kernel.org> - 2016-07-21 23:50 +0200
[PATCH resend v2 3/5] libata-scsi: use u8 array to store mode page copy tom.ty89@gmail.com - 2016-07-22 01:30 +0200
Re: [PATCH resend v2 3/5] libata-scsi: use u8 array to store mode page copy Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> - 2016-07-22 12:00 +0200
Re: [PATCH resend v2 3/5] libata-scsi: use u8 array to store mode page copy Tom Yan <tom.ty89@gmail.com> - 2016-07-22 20:30 +0200
[PATCH resend v3 3/5] libata-scsi: use u8 array to store mode page copy tom.ty89@gmail.com - 2016-07-22 20:40 +0200
[PATCH resend v2 3/5] libata-scsi: use u8 array to store mode page copy tom.ty89@gmail.com - 2016-07-22 01:40 +0200
Re: [PATCH resend 2/5] libata-scsi: fix read-only bits checking in ata_mselect_*() Tom Yan <tom.ty89@gmail.com> - 2016-07-22 01:30 +0200
[PATCH resend v2 2/5] libata-scsi: fix read-only bits checking in ata_mselect_*() tom.ty89@gmail.com - 2016-07-22 01:30 +0200
[PATCH resend v2 2/5] libata-scsi: fix read-only bits checking in ata_mselect_*() tom.ty89@gmail.com - 2016-07-22 01:40 +0200
| From | tom.ty89@gmail.com |
|---|---|
| Date | 2016-07-21 20:50 +0200 |
| Subject | [PATCH resend 2/5] libata-scsi: fix read-only bits checking in ata_mselect_*() |
| Message-ID | <rXrcJ-2T6-7@gated-at.bofh.it> |
From: Tom Yan <tom.ty89@gmail.com>
Commit 7780081c1f04 ("libata-scsi: Set information sense field for
invalid parameter") changed how ata_mselect_*() make sure read-only
bits are not modified. The new implementation introduced a bug that
the read-only bits in the byte that has a changeable bit will not
be checked.
Added the necessary check, with comments explaining the heuristic.
Signed-off-by: Tom Yan <tom.ty89@gmail.com>
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index eb5e8ff..ac90676 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3631,8 +3631,18 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
*/
ata_msense_caching(dev->id, mpage, false);
for (i = 0; i < CACHE_MPAGE_LEN - 2; i++) {
- if (i == 0)
- continue;
+ /* Check the first byte */
+ if (i == 0) {
+ /* except the WCE bit */
+ if ((mpage[i + 2] & 0xfb) != (buf[i] & 0xfb)) {
+ *fp = i;
+ return -EINVAL;
+ } else {
+ continue;
+ }
+ }
+
+ /* Check the remaining bytes */
if (mpage[i + 2] != buf[i]) {
*fp = i;
return -EINVAL;
@@ -3686,8 +3696,18 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
*/
ata_msense_control(dev, mpage, false);
for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) {
- if (i == 0)
- continue;
+ /* Check the first byte */
+ if (i == 0) {
+ /* except the D_SENSE bit */
+ if ((mpage[i + 2] & 0xfb) != (buf[i] & 0xfb)) {
+ *fp = i;
+ return -EINVAL;
+ } else {
+ continue;
+ }
+ }
+
+ /* Check the remaining bytes */
if (mpage[2 + i] != buf[i]) {
*fp = i;
return -EINVAL;
--
2.9.0
[toc] | [next] | [standalone]
| From | tom.ty89@gmail.com |
|---|---|
| Date | 2016-07-21 20:50 +0200 |
| Subject | [PATCH resend 3/5] libata-scsi: fix overflow in mode page copy |
| Message-ID | <rXrcJ-2T6-9@gated-at.bofh.it> |
| In reply to | #1448066 |
From: Tom Yan <tom.ty89@gmail.com>
ata_mselect_*() would initialize a char array for storing a copy of
the current mode page. However, if char was actually signed char,
overflow could occur.
For example, `0xff` from def_control_mpage[] would be "truncated"
to `-1`. This prevented ata_mselect_control() from working at all,
since when it did the read-only bits check, there would always be
a mismatch.
Signed-off-by: Tom Yan <tom.ty89@gmail.com>
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index ac90676..3c93341 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3610,7 +3610,7 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
{
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
- char mpage[CACHE_MPAGE_LEN];
+ u8 mpage[CACHE_MPAGE_LEN];
u8 wce;
int i;
@@ -3675,7 +3675,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
const u8 *buf, int len, u16 *fp)
{
struct ata_device *dev = qc->dev;
- char mpage[CONTROL_MPAGE_LEN];
+ u8 mpage[CONTROL_MPAGE_LEN];
u8 d_sense;
int i;
--
2.9.0
[toc] | [prev] | [next] | [standalone]
| From | tom.ty89@gmail.com |
|---|---|
| Date | 2016-07-21 20:50 +0200 |
| Subject | [PATCH resend 4/5] libata-scsi: have all checks done before calling ata_mselect_*() |
| Message-ID | <rXrcJ-2T6-11@gated-at.bofh.it> |
| In reply to | #1448068 |
From: Tom Yan <tom.ty89@gmail.com>
The one-page-at-a-time check in ata_scsi_mode_select_xlat() should
be done before either of the ata_mselect_*() is called.
Also updated the comment. We have more than one mode page that has
changeable bit since commit 06dbde5f3a44 ("libata: Implement
control mode page to select sense format").
Signed-off-by: Tom Yan <tom.ty89@gmail.com>
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 3c93341..6c424c5 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3837,6 +3837,12 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
if (pg_len > len)
goto invalid_param_len;
+ /*
+ * Currently we only support setting one page at a time.
+ */
+ if (len > pg_len)
+ goto invalid_param;
+
switch (pg) {
case CACHE_MPAGE:
if (ata_mselect_caching(qc, p, pg_len, &fp) < 0) {
@@ -3855,13 +3861,6 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
goto invalid_param;
}
- /*
- * Only one page has changeable data, so we only support setting one
- * page at a time.
- */
- if (len > pg_len)
- goto invalid_param;
-
return 0;
invalid_fld:
--
2.9.0
[toc] | [prev] | [next] | [standalone]
| From | Tejun Heo <tj@kernel.org> |
|---|---|
| Date | 2016-07-21 23:20 +0200 |
| Subject | Re: [PATCH resend 3/5] libata-scsi: fix overflow in mode page copy |
| Message-ID | <rXtxT-4A4-9@gated-at.bofh.it> |
| In reply to | #1448068 |
Hello, On Fri, Jul 22, 2016 at 02:41:52AM +0800, tom.ty89@gmail.com wrote: > From: Tom Yan <tom.ty89@gmail.com> > > ata_mselect_*() would initialize a char array for storing a copy of > the current mode page. However, if char was actually signed char, > overflow could occur. Do you mean sign extension? > For example, `0xff` from def_control_mpage[] would be "truncated" > to `-1`. This prevented ata_mselect_control() from working at all, > since when it did the read-only bits check, there would always be > a mismatch. Heh, the description doesn't really make sense. Are you talking about something like the following? char ar[N]; int i; i = ar[x]; if (i == 0xff) asdf; If so, the description isn't quite right. Thanks. -- tejun
[toc] | [prev] | [next] | [standalone]
| From | Tom Yan <tom.ty89@gmail.com> |
|---|---|
| Date | 2016-07-21 23:40 +0200 |
| Subject | Re: [PATCH resend 3/5] libata-scsi: fix overflow in mode page copy |
| Message-ID | <rXtRf-4HJ-11@gated-at.bofh.it> |
| In reply to | #1448150 |
Well, I mean this is happening when ata_mselect_*() calls ata_msense_*():
[tom@localhost ~]$ cat test.c
#include <stdio.h>
#include <string.h>
typedef unsigned char u8;
int main() {
u8 a[2] = { 0xff, 0xff };
char b[2];
memcpy(b, a, 2);
for (int i=0; i<2; i++) {
printf("%d\n", a[i]);
}
for (int i=0; i<2; i++) {
printf("%d\n", b[i]);
}
}
[tom@localhost ~]$ cc test.c
[tom@localhost ~]$ ./a.out
255
255
-1
-1
Let me know how I should polish the description for this.
On 22 July 2016 at 05:17, Tejun Heo <tj@kernel.org> wrote:
> Hello,
>
> On Fri, Jul 22, 2016 at 02:41:52AM +0800, tom.ty89@gmail.com wrote:
>> From: Tom Yan <tom.ty89@gmail.com>
>>
>> ata_mselect_*() would initialize a char array for storing a copy of
>> the current mode page. However, if char was actually signed char,
>> overflow could occur.
>
> Do you mean sign extension?
>
>> For example, `0xff` from def_control_mpage[] would be "truncated"
>> to `-1`. This prevented ata_mselect_control() from working at all,
>> since when it did the read-only bits check, there would always be
>> a mismatch.
>
> Heh, the description doesn't really make sense. Are you talking about
> something like the following?
>
> char ar[N];
> int i;
>
> i = ar[x];
> if (i == 0xff)
> asdf;
>
> If so, the description isn't quite right.
>
> Thanks.
>
> --
> tejun
[toc] | [prev] | [next] | [standalone]
| From | Tejun Heo <tj@kernel.org> |
|---|---|
| Date | 2016-07-21 23:50 +0200 |
| Subject | Re: [PATCH resend 3/5] libata-scsi: fix overflow in mode page copy |
| Message-ID | <rXu0V-4Lj-3@gated-at.bofh.it> |
| In reply to | #1448195 |
On Fri, Jul 22, 2016 at 05:39:27AM +0800, Tom Yan wrote: > Let me know how I should polish the description for this. The above is because the signed ones are getting sign-extended making them different from the unsigned ones which don't get padded in the high bits. Converting to u8 is the right thing to do but nothing here is getting truncated. Thanks. -- tejun
[toc] | [prev] | [next] | [standalone]
| From | tom.ty89@gmail.com |
|---|---|
| Date | 2016-07-22 01:30 +0200 |
| Subject | [PATCH resend v2 3/5] libata-scsi: use u8 array to store mode page copy |
| Message-ID | <rXvzI-5X0-1@gated-at.bofh.it> |
| In reply to | #1448196 |
From: Tom Yan <tom.ty89@gmail.com>
ata_mselect_*() would initialize a char array for storing a copy of
the current mode page. However, char could be signed char. In that
case, bytes larger than 127 would be converted to negative number.
For example, 0xff from def_control_mpage[] would become -1. This
prevented ata_mselect_control() from working at all, since when it
did the read-only bits check, there would always be a mismatch.
Signed-off-by: Tom Yan <tom.ty89@gmail.com>
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4a4e6f1..a28e2ea94 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3610,7 +3610,7 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
{
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
- char mpage[CACHE_MPAGE_LEN];
+ u8 mpage[CACHE_MPAGE_LEN];
u8 wce, mask;
int i;
@@ -3668,7 +3668,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
const u8 *buf, int len, u16 *fp)
{
struct ata_device *dev = qc->dev;
- char mpage[CONTROL_MPAGE_LEN];
+ u8 mpage[CONTROL_MPAGE_LEN];
u8 d_sense, mask;
int i;
--
2.9.0
[toc] | [prev] | [next] | [standalone]
| From | Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> |
|---|---|
| Date | 2016-07-22 12:00 +0200 |
| Subject | Re: [PATCH resend v2 3/5] libata-scsi: use u8 array to store mode page copy |
| Message-ID | <rXFpn-46k-11@gated-at.bofh.it> |
| In reply to | #1448247 |
Hello.
On 7/22/2016 2:29 AM, tom.ty89@gmail.com wrote:
> From: Tom Yan <tom.ty89@gmail.com>
>
> ata_mselect_*() would initialize a char array for storing a copy of
> the current mode page. However, char could be signed char. In that
> case, bytes larger than 127 would be converted to negative number.
>
> For example, 0xff from def_control_mpage[] would become -1. This
> prevented ata_mselect_control() from working at all, since when it
> did the read-only bits check, there would always be a mismatch.
>
> Signed-off-by: Tom Yan <tom.ty89@gmail.com>
>
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 4a4e6f1..a28e2ea94 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -3610,7 +3610,7 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
> {
> struct ata_taskfile *tf = &qc->tf;
> struct ata_device *dev = qc->dev;
> - char mpage[CACHE_MPAGE_LEN];
> + u8 mpage[CACHE_MPAGE_LEN];
> u8 wce, mask;
> int i;
>
> @@ -3668,7 +3668,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
> const u8 *buf, int len, u16 *fp)
> {
> struct ata_device *dev = qc->dev;
> - char mpage[CONTROL_MPAGE_LEN];
> + u8 mpage[CONTROL_MPAGE_LEN];
Indent with tabs please, as above.
[...]
MBR, Sergei
[toc] | [prev] | [next] | [standalone]
| From | Tom Yan <tom.ty89@gmail.com> |
|---|---|
| Date | 2016-07-22 20:30 +0200 |
| Subject | Re: [PATCH resend v2 3/5] libata-scsi: use u8 array to store mode page copy |
| Message-ID | <rXNmW-WX-15@gated-at.bofh.it> |
| In reply to | #1448514 |
Strange. I merely changed the two "char" to "u8". I wonder how the tab
became spaces. Anyway, sorry about that, resending soon.
On 22 July 2016 at 17:59, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Hello.
>
>
> On 7/22/2016 2:29 AM, tom.ty89@gmail.com wrote:
>
>> From: Tom Yan <tom.ty89@gmail.com>
>>
>> ata_mselect_*() would initialize a char array for storing a copy of
>> the current mode page. However, char could be signed char. In that
>> case, bytes larger than 127 would be converted to negative number.
>>
>> For example, 0xff from def_control_mpage[] would become -1. This
>> prevented ata_mselect_control() from working at all, since when it
>> did the read-only bits check, there would always be a mismatch.
>>
>> Signed-off-by: Tom Yan <tom.ty89@gmail.com>
>>
>> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
>> index 4a4e6f1..a28e2ea94 100644
>> --- a/drivers/ata/libata-scsi.c
>> +++ b/drivers/ata/libata-scsi.c
>> @@ -3610,7 +3610,7 @@ static int ata_mselect_caching(struct ata_queued_cmd
>> *qc,
>> {
>> struct ata_taskfile *tf = &qc->tf;
>> struct ata_device *dev = qc->dev;
>> - char mpage[CACHE_MPAGE_LEN];
>> + u8 mpage[CACHE_MPAGE_LEN];
>> u8 wce, mask;
>> int i;
>>
>> @@ -3668,7 +3668,7 @@ static int ata_mselect_control(struct ata_queued_cmd
>> *qc,
>> const u8 *buf, int len, u16 *fp)
>> {
>> struct ata_device *dev = qc->dev;
>> - char mpage[CONTROL_MPAGE_LEN];
>> + u8 mpage[CONTROL_MPAGE_LEN];
>
>
> Indent with tabs please, as above.
>
> [...]
>
> MBR, Sergei
>
[toc] | [prev] | [next] | [standalone]
| From | tom.ty89@gmail.com |
|---|---|
| Date | 2016-07-22 20:40 +0200 |
| Subject | [PATCH resend v3 3/5] libata-scsi: use u8 array to store mode page copy |
| Message-ID | <rXNwB-117-3@gated-at.bofh.it> |
| In reply to | #1448715 |
From: Tom Yan <tom.ty89@gmail.com>
ata_mselect_*() would initialize a char array for storing a copy of
the current mode page. However, char could be signed char. In that
case, bytes larger than 127 would be converted to negative number.
For example, 0xff from def_control_mpage[] would become -1. This
prevented ata_mselect_control() from working at all, since when it
did the read-only bits check, there would always be a mismatch.
Signed-off-by: Tom Yan <tom.ty89@gmail.com>
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4a4e6f1..5cfcb4b 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3610,7 +3610,7 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
{
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
- char mpage[CACHE_MPAGE_LEN];
+ u8 mpage[CACHE_MPAGE_LEN];
u8 wce, mask;
int i;
@@ -3668,7 +3668,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
const u8 *buf, int len, u16 *fp)
{
struct ata_device *dev = qc->dev;
- char mpage[CONTROL_MPAGE_LEN];
+ u8 mpage[CONTROL_MPAGE_LEN];
u8 d_sense, mask;
int i;
--
2.9.0
[toc] | [prev] | [next] | [standalone]
| From | tom.ty89@gmail.com |
|---|---|
| Date | 2016-07-22 01:40 +0200 |
| Subject | [PATCH resend v2 3/5] libata-scsi: use u8 array to store mode page copy |
| Message-ID | <rXvJn-60q-5@gated-at.bofh.it> |
| In reply to | #1448196 |
From: Tom Yan <tom.ty89@gmail.com>
ata_mselect_*() would initialize a char array for storing a copy of
the current mode page. However, char could be signed char. In that
case, bytes larger than 127 would be converted to negative number.
For example, 0xff from def_control_mpage[] would become -1. This
prevented ata_mselect_control() from working at all, since when it
did the read-only bits check, there would always be a mismatch.
Signed-off-by: Tom Yan <tom.ty89@gmail.com>
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4a4e6f1..a28e2ea94 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3610,7 +3610,7 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
{
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
- char mpage[CACHE_MPAGE_LEN];
+ u8 mpage[CACHE_MPAGE_LEN];
u8 wce, mask;
int i;
@@ -3668,7 +3668,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
const u8 *buf, int len, u16 *fp)
{
struct ata_device *dev = qc->dev;
- char mpage[CONTROL_MPAGE_LEN];
+ u8 mpage[CONTROL_MPAGE_LEN];
u8 d_sense, mask;
int i;
--
2.9.0
[toc] | [prev] | [next] | [standalone]
| From | Tom Yan <tom.ty89@gmail.com> |
|---|---|
| Date | 2016-07-22 01:30 +0200 |
| Message-ID | <rXvzI-5X0-9@gated-at.bofh.it> |
| In reply to | #1448066 |
This is actually a bit clumsy. Sending a rewritten version.
On 22 July 2016 at 02:41, <tom.ty89@gmail.com> wrote:
> From: Tom Yan <tom.ty89@gmail.com>
>
> Commit 7780081c1f04 ("libata-scsi: Set information sense field for
> invalid parameter") changed how ata_mselect_*() make sure read-only
> bits are not modified. The new implementation introduced a bug that
> the read-only bits in the byte that has a changeable bit will not
> be checked.
>
> Added the necessary check, with comments explaining the heuristic.
>
> Signed-off-by: Tom Yan <tom.ty89@gmail.com>
>
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index eb5e8ff..ac90676 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -3631,8 +3631,18 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
> */
> ata_msense_caching(dev->id, mpage, false);
> for (i = 0; i < CACHE_MPAGE_LEN - 2; i++) {
> - if (i == 0)
> - continue;
> + /* Check the first byte */
> + if (i == 0) {
> + /* except the WCE bit */
> + if ((mpage[i + 2] & 0xfb) != (buf[i] & 0xfb)) {
> + *fp = i;
> + return -EINVAL;
> + } else {
> + continue;
> + }
> + }
> +
> + /* Check the remaining bytes */
> if (mpage[i + 2] != buf[i]) {
> *fp = i;
> return -EINVAL;
> @@ -3686,8 +3696,18 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
> */
> ata_msense_control(dev, mpage, false);
> for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) {
> - if (i == 0)
> - continue;
> + /* Check the first byte */
> + if (i == 0) {
> + /* except the D_SENSE bit */
> + if ((mpage[i + 2] & 0xfb) != (buf[i] & 0xfb)) {
> + *fp = i;
> + return -EINVAL;
> + } else {
> + continue;
> + }
> + }
> +
> + /* Check the remaining bytes */
> if (mpage[2 + i] != buf[i]) {
> *fp = i;
> return -EINVAL;
> --
> 2.9.0
>
[toc] | [prev] | [next] | [standalone]
| From | tom.ty89@gmail.com |
|---|---|
| Date | 2016-07-22 01:30 +0200 |
| Subject | [PATCH resend v2 2/5] libata-scsi: fix read-only bits checking in ata_mselect_*() |
| Message-ID | <rXvzI-5X0-21@gated-at.bofh.it> |
| In reply to | #1448249 |
From: Tom Yan <tom.ty89@gmail.com>
Commit 7780081c1f04 ("libata-scsi: Set information sense field for
invalid parameter") changed how ata_mselect_*() make sure read-only
bits are not modified. The new implementation introduced a bug that
the read-only bits in the byte that has a changeable bit will not
be checked.
Made it check every byte but mask the changeable bit.
Signed-off-by: Tom Yan <tom.ty89@gmail.com>
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index eb5e8ff..4a4e6f1 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3611,7 +3611,7 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
char mpage[CACHE_MPAGE_LEN];
- u8 wce;
+ u8 wce, mask;
int i;
/*
@@ -3632,8 +3632,11 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
ata_msense_caching(dev->id, mpage, false);
for (i = 0; i < CACHE_MPAGE_LEN - 2; i++) {
if (i == 0)
- continue;
- if (mpage[i + 2] != buf[i]) {
+ mask = 0xfb;
+ else
+ mask = 0xff;
+
+ if ((mpage[i + 2] & mask) != (buf[i] & mask)) {
*fp = i;
return -EINVAL;
}
@@ -3666,7 +3669,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
{
struct ata_device *dev = qc->dev;
char mpage[CONTROL_MPAGE_LEN];
- u8 d_sense;
+ u8 d_sense, mask;
int i;
/*
@@ -3687,8 +3690,11 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
ata_msense_control(dev, mpage, false);
for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) {
if (i == 0)
- continue;
- if (mpage[2 + i] != buf[i]) {
+ mask = 0xfb;
+ else
+ mask = 0xff;
+
+ if ((mpage[2 + i] & mask) != (buf[i] & mask)) {
*fp = i;
return -EINVAL;
}
--
2.9.0
[toc] | [prev] | [next] | [standalone]
| From | tom.ty89@gmail.com |
|---|---|
| Date | 2016-07-22 01:40 +0200 |
| Subject | [PATCH resend v2 2/5] libata-scsi: fix read-only bits checking in ata_mselect_*() |
| Message-ID | <rXvJn-60q-19@gated-at.bofh.it> |
| In reply to | #1448249 |
From: Tom Yan <tom.ty89@gmail.com>
Commit 7780081c1f04 ("libata-scsi: Set information sense field for
invalid parameter") changed how ata_mselect_*() make sure read-only
bits are not modified. The new implementation introduced a bug that
the read-only bits in the byte that has a changeable bit will not
be checked.
Made it check every byte but mask the changeable bit.
Signed-off-by: Tom Yan <tom.ty89@gmail.com>
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index eb5e8ff..4a4e6f1 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3611,7 +3611,7 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
char mpage[CACHE_MPAGE_LEN];
- u8 wce;
+ u8 wce, mask;
int i;
/*
@@ -3632,8 +3632,11 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
ata_msense_caching(dev->id, mpage, false);
for (i = 0; i < CACHE_MPAGE_LEN - 2; i++) {
if (i == 0)
- continue;
- if (mpage[i + 2] != buf[i]) {
+ mask = 0xfb;
+ else
+ mask = 0xff;
+
+ if ((mpage[i + 2] & mask) != (buf[i] & mask)) {
*fp = i;
return -EINVAL;
}
@@ -3666,7 +3669,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
{
struct ata_device *dev = qc->dev;
char mpage[CONTROL_MPAGE_LEN];
- u8 d_sense;
+ u8 d_sense, mask;
int i;
/*
@@ -3687,8 +3690,11 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
ata_msense_control(dev, mpage, false);
for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) {
if (i == 0)
- continue;
- if (mpage[2 + i] != buf[i]) {
+ mask = 0xfb;
+ else
+ mask = 0xff;
+
+ if ((mpage[2 + i] & mask) != (buf[i] & mask)) {
*fp = i;
return -EINVAL;
}
--
2.9.0
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web