All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: SVM: Fix sparse: incorrect type in argument 1 (different base types)
@ 2018-02-19 16:12 Brijesh Singh
  2018-02-21 17:49 ` Al Viro
  0 siblings, 1 reply; 7+ messages in thread
From: Brijesh Singh @ 2018-02-19 16:12 UTC (permalink / raw)
  To: kvm
  Cc: Brijesh Singh, Paolo Bonzini, Radim Krčmář,
	Borislav Petkov, Tom Lendacky, linux-kernel, Joerg Roedel

Fix sparse: incorrect type in argument 1 (different base types). Typecast
the userspace address argument.

Fixes: 0d0736f76347 (KVM: SVM: Add support for KVM_SEV_LAUNCH_MEASURE ...)
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Radim Krčmář" <rkrcmar@redhat.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: linux-kernel@vger.kernel.org
Cc: Joerg Roedel <joro@8bytes.org>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 arch/x86/kvm/svm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index b3e488a74828..a2f1bb73640c 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -6262,7 +6262,9 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
 			goto e_free;
 		}
 
-		if (!access_ok(VERIFY_WRITE, params.uaddr, params.len)) {
+		if (!access_ok(VERIFY_WRITE,
+			       (void __user *)(uintptr_t)params.uaddr,
+			       params.len)) {
 			ret = -EFAULT;
 			goto e_free;
 		}
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] KVM: SVM: Fix sparse: incorrect type in argument 1 (different base types)
  2018-02-19 16:12 [PATCH] KVM: SVM: Fix sparse: incorrect type in argument 1 (different base types) Brijesh Singh
@ 2018-02-21 17:49 ` Al Viro
  2018-02-21 19:59   ` Brijesh Singh
  0 siblings, 1 reply; 7+ messages in thread
From: Al Viro @ 2018-02-21 17:49 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: kvm, Paolo Bonzini, Radim Krčmář,
	Borislav Petkov, Tom Lendacky, linux-kernel, Joerg Roedel

On Mon, Feb 19, 2018 at 10:12:28AM -0600, Brijesh Singh wrote:
> Fix sparse: incorrect type in argument 1 (different base types). Typecast
> the userspace address argument.

Better question: why the hell do we want that access_ok(), anyway?  The only
thing we do to params.uaddr is
        if (blob) {
                if (copy_to_user((void __user *)(uintptr_t)params.uaddr, blob, params.len))
                        ret = -EFAULT;
        }

downstream.  What does that access_ok() buy us?  It does not guarantee that
copy_to_user() won't fail.  It does not clamp params.len (we'd just done
that explicitly).  So why not somethings like this:

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index b3e488a74828..ba2c1a606985 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -6239,13 +6239,15 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
 	struct kvm_sev_info *sev = &kvm->arch.sev_info;
 	struct sev_data_launch_measure *data;
 	struct kvm_sev_launch_measure params;
+	void __user *measure = (void __user *)(uintptr_t)argp->data;
+	void __user *p = NULL;
 	void *blob = NULL;
 	int ret;
 
 	if (!sev_guest(kvm))
 		return -ENOTTY;
 
-	if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
+	if (copy_from_user(&params, measure, sizeof(params)))
 		return -EFAULT;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -6256,17 +6258,13 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
 	if (!params.len)
 		goto cmd;
 
-	if (params.uaddr) {
+	p = (void __user *)(uintptr_t)params.uaddr;
+	if (p) {
 		if (params.len > SEV_FW_BLOB_MAX_SIZE) {
 			ret = -EINVAL;
 			goto e_free;
 		}
 
-		if (!access_ok(VERIFY_WRITE, params.uaddr, params.len)) {
-			ret = -EFAULT;
-			goto e_free;
-		}
-
 		ret = -ENOMEM;
 		blob = kmalloc(params.len, GFP_KERNEL);
 		if (!blob)
@@ -6290,13 +6288,13 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
 		goto e_free_blob;
 
 	if (blob) {
-		if (copy_to_user((void __user *)(uintptr_t)params.uaddr, blob, params.len))
+		if (copy_to_user(p, blob, params.len))
 			ret = -EFAULT;
 	}
 
 done:
 	params.len = data->len;
-	if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params)))
+	if (copy_to_user(measure, &params, sizeof(params)))
 		ret = -EFAULT;
 e_free_blob:
 	kfree(blob);

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] KVM: SVM: Fix sparse: incorrect type in argument 1 (different base types)
  2018-02-21 17:49 ` Al Viro
@ 2018-02-21 19:59   ` Brijesh Singh
  2018-02-21 20:18     ` Al Viro
  0 siblings, 1 reply; 7+ messages in thread
From: Brijesh Singh @ 2018-02-21 19:59 UTC (permalink / raw)
  To: Al Viro
  Cc: brijesh.singh, kvm, Paolo Bonzini, Radim Krčmář,
	Borislav Petkov, Tom Lendacky, linux-kernel, Joerg Roedel



On 2/21/18 11:49 AM, Al Viro wrote:
> On Mon, Feb 19, 2018 at 10:12:28AM -0600, Brijesh Singh wrote:
>> Fix sparse: incorrect type in argument 1 (different base types). Typecast
>> the userspace address argument.
> Better question: why the hell do we want that access_ok(), anyway?  The only
> thing we do to params.uaddr is
>         if (blob) {
>                 if (copy_to_user((void __user *)(uintptr_t)params.uaddr, blob, params.len))
>                         ret = -EFAULT;
>         }
>
> downstream.  What does that access_ok() buy us?  It does not guarantee that
> copy_to_user() won't fail.  


Sure, checking access_ok() does not guarantee that later
copy_from_user() will not fail. But it does eliminate one possible
reason for the failure. We are trying to validate most of the user
inputs before we invoke  SEV command. The SEV command handler does heavy
lifting (which includes setting up PSP mailbox,  issuing FW command, 
and handling the response etc). I would like to avoid invoking SEV
command when we know for sure that copy_to_user() will fail later.


> It does not clamp params.len (we'd just done
> that explicitly).  So why not somethings like this:
>
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index b3e488a74828..ba2c1a606985 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -6239,13 +6239,15 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
>  	struct kvm_sev_info *sev = &kvm->arch.sev_info;
>  	struct sev_data_launch_measure *data;
>  	struct kvm_sev_launch_measure params;
> +	void __user *measure = (void __user *)(uintptr_t)argp->data;
> +	void __user *p = NULL;
>  	void *blob = NULL;
>  	int ret;
>  
>  	if (!sev_guest(kvm))
>  		return -ENOTTY;
>  
> -	if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
> +	if (copy_from_user(&params, measure, sizeof(params)))
>  		return -EFAULT;
>  
>  	data = kzalloc(sizeof(*data), GFP_KERNEL);
> @@ -6256,17 +6258,13 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
>  	if (!params.len)
>  		goto cmd;
>  
> -	if (params.uaddr) {
> +	p = (void __user *)(uintptr_t)params.uaddr;
> +	if (p) {
>  		if (params.len > SEV_FW_BLOB_MAX_SIZE) {
>  			ret = -EINVAL;
>  			goto e_free;
>  		}
>  
> -		if (!access_ok(VERIFY_WRITE, params.uaddr, params.len)) {
> -			ret = -EFAULT;
> -			goto e_free;
> -		}
> -
>  		ret = -ENOMEM;
>  		blob = kmalloc(params.len, GFP_KERNEL);
>  		if (!blob)
> @@ -6290,13 +6288,13 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
>  		goto e_free_blob;
>  
>  	if (blob) {
> -		if (copy_to_user((void __user *)(uintptr_t)params.uaddr, blob, params.len))
> +		if (copy_to_user(p, blob, params.len))
>  			ret = -EFAULT;
>  	}
>  
>  done:
>  	params.len = data->len;
> -	if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params)))
> +	if (copy_to_user(measure, &params, sizeof(params)))
>  		ret = -EFAULT;
>  e_free_blob:
>  	kfree(blob);

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] KVM: SVM: Fix sparse: incorrect type in argument 1 (different base types)
  2018-02-21 19:59   ` Brijesh Singh
@ 2018-02-21 20:18     ` Al Viro
  2018-02-22 15:56       ` Brijesh Singh
  0 siblings, 1 reply; 7+ messages in thread
From: Al Viro @ 2018-02-21 20:18 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: kvm, Paolo Bonzini, Radim Krčmář,
	Borislav Petkov, Tom Lendacky, linux-kernel, Joerg Roedel

On Wed, Feb 21, 2018 at 01:59:55PM -0600, Brijesh Singh wrote:

> Sure, checking access_ok() does not guarantee that later
> copy_from_user() will not fail. But it does eliminate one possible
> reason for the failure. We are trying to validate most of the user
> inputs before we invoke  SEV command.

That makes no sense whatsoever.  If user is deliberately fuzzing
your code or trying to DoS it, that "validation" doesn't buy you
anything - they can just as well feed you NULL, after all.

What is the rationale for that?  "Userland is accidentally feeding
us garbage pointers" is the case where slowness is the least of your
concerns...

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] KVM: SVM: Fix sparse: incorrect type in argument 1 (different base types)
  2018-02-21 20:18     ` Al Viro
@ 2018-02-22 15:56       ` Brijesh Singh
  2018-02-23 18:05         ` Paolo Bonzini
  0 siblings, 1 reply; 7+ messages in thread
From: Brijesh Singh @ 2018-02-22 15:56 UTC (permalink / raw)
  To: Al Viro
  Cc: brijesh.singh, kvm, Paolo Bonzini, Radim Krčmář,
	Borislav Petkov, Tom Lendacky, linux-kernel, Joerg Roedel



On 02/21/2018 02:18 PM, Al Viro wrote:
> On Wed, Feb 21, 2018 at 01:59:55PM -0600, Brijesh Singh wrote:
> 
>> Sure, checking access_ok() does not guarantee that later
>> copy_from_user() will not fail. But it does eliminate one possible
>> reason for the failure. We are trying to validate most of the user
>> inputs before we invoke  SEV command.
> 
> That makes no sense whatsoever.  If user is deliberately fuzzing
> your code or trying to DoS it, that "validation" doesn't buy you
> anything - they can just as well feed you NULL, after all.
> 


Currently, we let user query the blob length with params.len == 0 || 
param.uaddr == NULL. We could limit it to just params.len == 0.


> What is the rationale for that?  "Userland is accidentally feeding
> us garbage pointers" is the case where slowness is the least of your
> concerns...
> 

My intent was to do some obvious failure checks on user inputs before 
invoking the HW. I do see your point that if userspace is feeding us 
garbage then slowness is least of our concern. If you think that we 
should not be using access_ok() in this particular case then I am okay 
with it.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] KVM: SVM: Fix sparse: incorrect type in argument 1 (different base types)
  2018-02-22 15:56       ` Brijesh Singh
@ 2018-02-23 18:05         ` Paolo Bonzini
  2018-02-23 18:26           ` Brijesh Singh
  0 siblings, 1 reply; 7+ messages in thread
From: Paolo Bonzini @ 2018-02-23 18:05 UTC (permalink / raw)
  To: Brijesh Singh, Al Viro
  Cc: kvm, Radim Krčmář,
	Borislav Petkov, Tom Lendacky, linux-kernel, Joerg Roedel

On 22/02/2018 16:56, Brijesh Singh wrote:
> 
> 
> On 02/21/2018 02:18 PM, Al Viro wrote:
>> On Wed, Feb 21, 2018 at 01:59:55PM -0600, Brijesh Singh wrote:
>>
>>> Sure, checking access_ok() does not guarantee that later
>>> copy_from_user() will not fail. But it does eliminate one possible
>>> reason for the failure. We are trying to validate most of the user
>>> inputs before we invoke  SEV command.
>>
>> That makes no sense whatsoever.  If user is deliberately fuzzing
>> your code or trying to DoS it, that "validation" doesn't buy you
>> anything - they can just as well feed you NULL, after all.
>>
> 
> 
> Currently, we let user query the blob length with params.len == 0 ||
> param.uaddr == NULL. We could limit it to just params.len == 0.
> 
> 
>> What is the rationale for that?  "Userland is accidentally feeding
>> us garbage pointers" is the case where slowness is the least of your
>> concerns...
>>
> 
> My intent was to do some obvious failure checks on user inputs before
> invoking the HW. I do see your point that if userspace is feeding us
> garbage then slowness is least of our concern. If you think that we
> should not be using access_ok() in this particular case then I am okay
> with it.

Can you please send a patch?  Thanks!

Paolo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] KVM: SVM: Fix sparse: incorrect type in argument 1 (different base types)
  2018-02-23 18:05         ` Paolo Bonzini
@ 2018-02-23 18:26           ` Brijesh Singh
  0 siblings, 0 replies; 7+ messages in thread
From: Brijesh Singh @ 2018-02-23 18:26 UTC (permalink / raw)
  To: Paolo Bonzini, Al Viro
  Cc: brijesh.singh, kvm, Radim Krčmář,
	Borislav Petkov, Tom Lendacky, linux-kernel, Joerg Roedel



On 02/23/2018 12:05 PM, Paolo Bonzini wrote:
> On 22/02/2018 16:56, Brijesh Singh wrote:
>>
>>
>> On 02/21/2018 02:18 PM, Al Viro wrote:
>>> On Wed, Feb 21, 2018 at 01:59:55PM -0600, Brijesh Singh wrote:
>>>
>>>> Sure, checking access_ok() does not guarantee that later
>>>> copy_from_user() will not fail. But it does eliminate one possible
>>>> reason for the failure. We are trying to validate most of the user
>>>> inputs before we invoke  SEV command.
>>>
>>> That makes no sense whatsoever.  If user is deliberately fuzzing
>>> your code or trying to DoS it, that "validation" doesn't buy you
>>> anything - they can just as well feed you NULL, after all.
>>>
>>
>>
>> Currently, we let user query the blob length with params.len == 0 ||
>> param.uaddr == NULL. We could limit it to just params.len == 0.
>>
>>
>>> What is the rationale for that?  "Userland is accidentally feeding
>>> us garbage pointers" is the case where slowness is the least of your
>>> concerns...
>>>
>>
>> My intent was to do some obvious failure checks on user inputs before
>> invoking the HW. I do see your point that if userspace is feeding us
>> garbage then slowness is least of our concern. If you think that we
>> should not be using access_ok() in this particular case then I am okay
>> with it.
> 
> Can you please send a patch?  Thanks!
> 

Sure, I will send patch soon.

-Brijesh

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-02-23 18:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-19 16:12 [PATCH] KVM: SVM: Fix sparse: incorrect type in argument 1 (different base types) Brijesh Singh
2018-02-21 17:49 ` Al Viro
2018-02-21 19:59   ` Brijesh Singh
2018-02-21 20:18     ` Al Viro
2018-02-22 15:56       ` Brijesh Singh
2018-02-23 18:05         ` Paolo Bonzini
2018-02-23 18:26           ` Brijesh Singh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.