Skip to contentSkip to conversation

mpt3sas: downgrade full copy_from_user to access_ok check

PATCH In review Meng Xu 3 participants 4 messages Sep 20, 2017 – Sep 21, 2017

Subsystems (2)
lore
Share & tools
lore

Meng Xu

author
#0 lore raw

PATCH 1/1 mpt3sas: downgrade full copy_from_user to access_ok check

Since right after the user copy, we are going to memset(&karg, 0, sizeof(karg)), I guess an access_ok check is enough?

---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/mpt3sas/mpt3sas_ctl.c +1 -1
index bdffb69..b363d2d 100644
@@ -1065,7 +1065,7 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
 {
 	struct mpt3_ioctl_iocinfo karg;
 
-	if (copy_from_user(&karg, arg, sizeof(karg))) {
+	if (!access_ok(VERIFY_READ, arg, sizeof(karg))) {
 		pr_err("failure at %s:%d/%s()!\n",
 		    __FILE__, __LINE__, __func__);
 		return -EFAULT;
Signature · 1 line
2.7.4
#1 lore raw
Quoted 2 lines · Meng Xu

Since right after the user copy, we are going to memset(&karg, 0, sizeof(karg)), I guess an access_ok check is enough?

The right thing is to remove it entirely.

#2 lore raw
In reply to Meng Xu
Quoted 2 lines · Meng Xu

Since right after the user copy, we are going to memset(&karg, 0, sizeof(karg)), I guess an access_ok check is enough?

access_ok() is *NOT* "will copy_from_user() succeed?" Not even close. On a bunch of architectures (sparc64, for one) access_ok() is always true.

All it does is checking that address is not a kernel one - e.g. on i386 anything in range 0..3Gb qualifies. Whether anything's mapped at that address or not.

Why bother with that copy_from_user() at all? The same ioctl() proceeds to copy_to_user() on exact same range; all you get from it is "if the area passed by caller is writable, but not readable, fail with -EFAULT". Who cares?

Just drop that copy_from_user() completely. Anything access_ok() might've caught will be caught by copy_to_user() anyway.

author
#3 lore raw
Quoted 15 lines · Al Viro
Quoted 2 lines · Meng Xu

Since right after the user copy, we are going to memset(&karg, 0, sizeof(karg)), I guess an access_ok check is enough?

access_ok() is *NOT* "will copy_from_user() succeed?" Not even close. On a bunch of architectures (sparc64, for one) access_ok() is always true.

All it does is checking that address is not a kernel one - e.g. on i386 anything in range 0..3Gb qualifies. Whether anything's mapped at that address or not.

Quoted 7 lines

Why bother with that copy_from_user() at all? The same ioctl() proceeds to copy_to_user() on exact same range; all you get from it is "if the area passed by caller is writable, but not readable, fail with -EFAULT". Who cares?

Just drop that copy_from_user() completely. Anything access_ok() might've caught will be caught by copy_to_user() anyway.

Yes, Christoph has suggested the same thing and I have submitted another patch with copy_from_user removed entirely.