All of lore.kernel.org
 help / color / mirror / Atom feed
* I/O port permission bit inheritance between threads
@ 2013-05-20 21:24 Stephen Hemminger
  2013-05-21  9:50 ` Joerg Roedel
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Hemminger @ 2013-05-20 21:24 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: kvm

ioperm() inheritance across threads is different in KVM then when run
on physical hardware.  The following program runs on physical hardware
but get SEGV under KVM.

It appears that the I/O permission bits are not shared between threads
in the same way.

/* Original Copyright 2011, Kees Cook <kees@outflux.net>, License: GPLv2 */
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/io.h>

static void *beep(void *arg)
{
	unsigned char bits;

	fprintf(stderr, "waiting\n");
	sleep(1);

	fprintf(stderr, "beeping\n");
	/* turn on speaker */
	bits = inb(0x61);
	bits |= 3;
	outb(bits, 0x61);

	/* set 1000 Hz frequency */
	bits = 0xA9;
	outb(bits, 0x42);
	bits = 0x04;
	outb(bits, 0x42);

	/* listen to the beep */
	sleep(4);
	fprintf(stderr, "done\n");

	return NULL;
}

int main() {
	pthread_t tid;
	unsigned char orig;

	if (pthread_create(&tid, NULL, &beep, NULL)) {
		perror("pthread");
		return 1;
	}

	/* gain access to speaker control port */
	if (ioperm(0x61, 0x61, 1) < 0) {
		perror("0x61");
		return 1;
	}
	orig = inb(0x61);

	/* gain access to speaker frequency port */
	if (ioperm(0x42, 0x42, 1) < 0) {
		perror("0x42");
		return 2;
	}

	fprintf(stderr, "joining\n");
	pthread_join(tid, NULL);
	
	/* restore speaker bits to turn off speaker */
	outb(orig, 0x61);
	fprintf(stderr, "done\n");
	return 0;
}

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

* Re: I/O port permission bit inheritance between threads
  2013-05-20 21:24 I/O port permission bit inheritance between threads Stephen Hemminger
@ 2013-05-21  9:50 ` Joerg Roedel
  2013-05-21 10:01   ` Gleb Natapov
  0 siblings, 1 reply; 5+ messages in thread
From: Joerg Roedel @ 2013-05-21  9:50 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: kvm

Hey Stephen,

On Mon, May 20, 2013 at 02:24:31PM -0700, Stephen Hemminger wrote:
> ioperm() inheritance across threads is different in KVM then when run
> on physical hardware.  The following program runs on physical hardware
> but get SEGV under KVM.
> 
> It appears that the I/O permission bits are not shared between threads
> in the same way.

Is this specific to SVM or do you see it on VMX too? My first guess
would be that the KVM instruction emulator does not check to
IO-permissions correctly, but that would affect VMX and SVM.


	Joerg



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

* Re: I/O port permission bit inheritance between threads
  2013-05-21  9:50 ` Joerg Roedel
@ 2013-05-21 10:01   ` Gleb Natapov
  2013-05-21 15:27     ` Stephen Hemminger
  0 siblings, 1 reply; 5+ messages in thread
From: Gleb Natapov @ 2013-05-21 10:01 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Stephen Hemminger, kvm

On Tue, May 21, 2013 at 11:50:30AM +0200, Joerg Roedel wrote:
> Hey Stephen,
> 
> On Mon, May 20, 2013 at 02:24:31PM -0700, Stephen Hemminger wrote:
> > ioperm() inheritance across threads is different in KVM then when run
> > on physical hardware.  The following program runs on physical hardware
> > but get SEGV under KVM.
> > 
> > It appears that the I/O permission bits are not shared between threads
> > in the same way.
> 
> Is this specific to SVM or do you see it on VMX too? My first guess
> would be that the KVM instruction emulator does not check to
> IO-permissions correctly, but that would affect VMX and SVM.
> 
The program segfaults on physical hardware:
# ./a.out 
joining
waiting
beeping
Segmentation fault

--
			Gleb.

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

* Re: I/O port permission bit inheritance between threads
  2013-05-21 10:01   ` Gleb Natapov
@ 2013-05-21 15:27     ` Stephen Hemminger
  2013-05-23  9:27       ` Gleb Natapov
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Hemminger @ 2013-05-21 15:27 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: Joerg Roedel, kvm

On Tue, 21 May 2013 13:01:18 +0300
Gleb Natapov <gleb@redhat.com> wrote:

> On Tue, May 21, 2013 at 11:50:30AM +0200, Joerg Roedel wrote:
> > Hey Stephen,
> > 
> > On Mon, May 20, 2013 at 02:24:31PM -0700, Stephen Hemminger wrote:
> > > ioperm() inheritance across threads is different in KVM then when run
> > > on physical hardware.  The following program runs on physical hardware
> > > but get SEGV under KVM.
> > > 
> > > It appears that the I/O permission bits are not shared between threads
> > > in the same way.
> > 
> > Is this specific to SVM or do you see it on VMX too? My first guess
> > would be that the KVM instruction emulator does not check to
> > IO-permissions correctly, but that would affect VMX and SVM.
> > 
> The program segfaults on physical hardware:
> # ./a.out 
> joining
> waiting
> beeping
> Segmentation fault
> 
> --
> 			Gleb.

The program had timing races, changing it slightly shows that.
# ./beep
beeping
done
oo
# ./beep --pre
joining
beeping
Segmentation fault
# ./beep --post
beeping
joining
done
oo
# 

/* Original Copyright 2011, Kees Cook <kees@outflux.net>, License: GPLv2 */
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/io.h>

enum { NOFORK, BEFORE, AFTER } cases = NOFORK;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

static void *beep(void *arg)
{
	unsigned char bits;

	pthread_mutex_lock(&mut);
	fprintf(stderr, "beeping\n");
	/* turn on speaker */
	bits = inb(0x61);
	bits |= 3;
	outb(bits, 0x61);

	/* set 1000 Hz frequency */
	bits = 0xA9;
	outb(bits, 0x42);
	bits = 0x04;
	outb(bits, 0x42);

	/* listen to the beep */
	sleep(4);
	fprintf(stderr, "done\n");
	pthread_mutex_unlock(&mut);

	return NULL;
}

int main(int argc, char **argv) {
	pthread_t tid;
	unsigned char orig;

	if (argc > 1) {
		if (!strcmp(argv[1], "--pre")) cases = BEFORE;
		if (!strcmp(argv[1], "--post")) cases = AFTER;
	}


	pthread_mutex_lock(&mut);
	if (cases == BEFORE && pthread_create(&tid, NULL, &beep, NULL)) {
		perror("pthread");
		return 1;
	}

	/* gain access to speaker control port */
	if (ioperm(0x61, 0x61, 1) < 0) {
		perror("0x61");
		return 1;
	}

	/* record original value */
	orig = inb(0x61);

	/* gain access to speaker frequency port */
	if (ioperm(0x42, 0x42, 1) < 0) {
		perror("0x42");
		return 2;
	}
	pthread_mutex_unlock(&mut);

	if (cases == AFTER && pthread_create(&tid, NULL, &beep, NULL)) {
		perror("pthread");
		return 1;
	}

	if (cases == NOFORK)
		beep(NULL);
	else {
		fprintf(stderr, "joining\n");
		pthread_join(tid, NULL);
	}
	
	/* restore speaker bits to turn off speaker */
	outb(orig, 0x61);
	fprintf(stderr, "oo\n");
	return 0;
}

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

* Re: I/O port permission bit inheritance between threads
  2013-05-21 15:27     ` Stephen Hemminger
@ 2013-05-23  9:27       ` Gleb Natapov
  0 siblings, 0 replies; 5+ messages in thread
From: Gleb Natapov @ 2013-05-23  9:27 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Joerg Roedel, kvm

On Tue, May 21, 2013 at 08:27:09AM -0700, Stephen Hemminger wrote:
> On Tue, 21 May 2013 13:01:18 +0300
> Gleb Natapov <gleb@redhat.com> wrote:
> 
> > On Tue, May 21, 2013 at 11:50:30AM +0200, Joerg Roedel wrote:
> > > Hey Stephen,
> > > 
> > > On Mon, May 20, 2013 at 02:24:31PM -0700, Stephen Hemminger wrote:
> > > > ioperm() inheritance across threads is different in KVM then when run
> > > > on physical hardware.  The following program runs on physical hardware
> > > > but get SEGV under KVM.
> > > > 
> > > > It appears that the I/O permission bits are not shared between threads
> > > > in the same way.
> > > 
> > > Is this specific to SVM or do you see it on VMX too? My first guess
> > > would be that the KVM instruction emulator does not check to
> > > IO-permissions correctly, but that would affect VMX and SVM.
> > > 
> > The program segfaults on physical hardware:
> > # ./a.out 
> > joining
> > waiting
> > beeping
> > Segmentation fault
> > 
> > --
> > 			Gleb.
> 
> The program had timing races, changing it slightly shows that.
> # ./beep
> beeping
> done
> oo
> # ./beep --pre
> joining
> beeping
> Segmentation fault
> # ./beep --post
> beeping
> joining
> done
> oo
> # 
> 
And I get the same in a VM on Intel host.

--
			Gleb.

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

end of thread, other threads:[~2013-05-23  9:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-20 21:24 I/O port permission bit inheritance between threads Stephen Hemminger
2013-05-21  9:50 ` Joerg Roedel
2013-05-21 10:01   ` Gleb Natapov
2013-05-21 15:27     ` Stephen Hemminger
2013-05-23  9:27       ` Gleb Natapov

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.