Linux-man Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH] iopl.2: Changing description of permissions set per-process to per-thread
@ 2020-05-24 13:22 Thomas Piekarski
  2020-05-25 13:57 ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 7+ messages in thread
From: Thomas Piekarski @ 2020-05-24 13:22 UTC (permalink / raw)
  To: Michael Kerrisk (man-pages); +Cc: linux-man, victorm007

iopl is setting permissions for port-mapped I/O not per-process but only 
for threads and its children.

See https://bugzilla.kernel.org/show_bug.cgi?id=205317

Reported-by: victorm007@yahoo.com
Signed-off-by: Thomas Piekarski <t.piekarski@deloquencia.de>


---


1. Test case if permissions are granted per-process or per-thread

I took the opportunity to dig into PMIO and granting permissions with 
iopl and ioperm.

Wrote the following code in which two threads are created and try to 
read some data with inb(). First thread (read_from_sleepy_child) is 
created before permissions are granted (but is delayed) and the second 
one (read_from_child) after that.

If those permissions would be granted on process level should the first 
thread not succeed?

I hope I did not make any mistake, applied threading well and can solve 
this issue as well as support the discussion at LKML.

2. Test Code

#include <pthread.h>
#include <stdio.h>
#include <sys/io.h>
#include <unistd.h>

#define PORT 0x378 // lp0

void *read_from_sleepy_child()
{
   sleep(3);

   // The inb() will fail due to missing permissions and it'll segfault
   // although permissions are acquired before threads are joined.
   // When permissions are set per process this should work.
   printf("Read anything from (sleepy) child thread (%x).\n", inb(PORT));

   return NULL;
}

void *read_from_child()
{
   // The inb() will succeed due to permissions are inherited to
   // childs after they got acquired with either iopl or ioperm
   printf("Read anything from child thread (%x).\n", inb(PORT));

   return NULL;
}

int main()
{
   pthread_t delayed_thread, thread;

   pthread_create(&delayed_thread, NULL, read_from_sleepy_child, NULL);

   iopl(3);
   // ioperm(0, 0xFFFF, 1); // the same segfault

   // The inb() will succeed due to being the main, default thread
   // where permissions got acquired in first place
   printf("Read anything from main thread (%x).\n", inb(PORT));

   pthread_create(&thread, NULL, read_from_child, NULL);
   pthread_join(delayed_thread, NULL);
   pthread_join(thread, NULL);

   return 0;
}


3. Patch

  man2/iopl.2 | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/man2/iopl.2 b/man2/iopl.2
index e5b216a14..329095808 100644
--- a/man2/iopl.2
+++ b/man2/iopl.2
@@ -39,7 +39,7 @@ iopl \- change I/O privilege level
  .BI "int iopl(int " level );
  .SH DESCRIPTION
  .BR iopl ()
-changes the I/O privilege level of the calling process,
+changes the I/O privilege level of the calling thread,
  as specified by the two least significant bits in
  .IR level .
  .PP
@@ -50,7 +50,7 @@ Since these X servers require access to all 65536 I/O 
ports, the
  call is not sufficient.
  .PP
  In addition to granting unrestricted I/O port access, running at a higher
-I/O privilege level also allows the process to disable interrupts.
+I/O privilege level also allows the thread to disable interrupts.
  This will probably crash the system, and is not recommended.
  .PP
  Permissions are not inherited by the child process created by
@@ -79,7 +79,7 @@ is greater than 3.
  This call is unimplemented.
  .TP
  .B EPERM
-The calling process has insufficient privilege to call
+The calling thread has insufficient privilege to call
  .BR iopl ();
  the
  .B CAP_SYS_RAWIO
-- 
2.20.1

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

end of thread, back to index

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-24 13:22 [PATCH] iopl.2: Changing description of permissions set per-process to per-thread Thomas Piekarski
2020-05-25 13:57 ` Michael Kerrisk (man-pages)
2020-05-28 13:22   ` Thomas Gleixner
2020-05-28 14:52     ` Thomas Piekarski
2020-06-24  9:53       ` Michael Kerrisk (man-pages)
2020-06-26 20:29         ` [PATCH-v2] iopl.2: Updating description of permissions and disabling interrupts Thomas Piekarski
2020-06-29 11:49           ` Michael Kerrisk (man-pages)

Linux-man Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-man/0 linux-man/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-man linux-man/ https://lore.kernel.org/linux-man \
		linux-man@vger.kernel.org
	public-inbox-index linux-man

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-man


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git