9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: cinap_lenrek@gmx.de
To: 9fans@9fans.net
Subject: Re: [9fans] Race condition in /sys/src/9/pc/trap.c?
Date: Fri, 31 Jul 2009 19:13:47 +0200	[thread overview]
Message-ID: <f390245ec5802e1703b4bd6a6b15a6c3@gmx.de> (raw)
In-Reply-To: <fae87e311a68cf665cb109c17d5213c9@terzarima.net>

[-- Attachment #1: Type: text/plain, Size: 931 bytes --]

very interesting. thanks for the sum up.

but my testcase crashes a uniprocessor system, so here is no
waiting for mmuflushes on other processors going on.

any other process that shares the segment and was suspended
in the kernel may potentialy hold a pointer to that freed memory
area of the segment and may cause a fault in the kernel on resume.

process1:
	in kernel:
		read(buf)
			validaddr(buf)
			...
			*context switch*

process2:
	in kernel:
		...
			ibrk()
				mfreeseg()
					procflushseg()
				flushmmu()
		...
		*context switch*

process1:
	still in kernel:
		memmove(buf, ...)
		*fault*
		trap()
			fault386()
				fault() => -1
				if(!user){
					panic()
					*panic*
				}
				...
				postnote()


we cant really wait for all processes sharing the segment to be
in userspace as they may already be waiting in a long blocking
syscall.

how do we fix this?

--
cinap

[-- Attachment #2: Type: message/rfc822, Size: 6164 bytes --]

[-- Attachment #2.1.1: Type: text/plain, Size: 2077 bytes --]

this resulted in a little side discussion.
to save someone else from having to break a strong oath about 9fans,
i'll sum it up. the existing code handles this situation.

when several processes share a segment, and any one of them
decides to shrink the segment, all the processes must see
the change before the pages are made available for re-use.
any one of them could have any of those pages currently in their mmu state.
and any  must be removed from the mmu state local to the process,
to ensure that no further access to the pages is possible before they are freed.
the critical point is that it's irrelevant whether traps or syscalls are
involved: ordinary store instructions are clearly bad enough.

thus /sys/src/9/port/segment.c:/^mfreeseg contains (with s locked)
	/* flush this seg in all other processes */
	if(s->ref > 1)
		procflushseg(s);
and procflushseg finds all processes that share s, sets them all up
to flush their mmu states, and also sets any processor running such a process
to flush its state (that's picked up by a clock interrupt).

procflushseg will not proceed until all processes and processors that
might need to flush state have done so. (s remains locked throughout.)

after the flush, no process or processor can have a reference
to any of the pages in its mmu state.  it is safe to free them,
which mfreeseg does.

now, a process might still be executing a system call or some other trap
that might refer to that segment, to an address that's now been removed
by another process. to access the memory, it must ultimately issue
a load or a store instruction (even for syscalls, such as read or write).
that instruction will trap, because as described above there is no longer
a valid mmu mapping for that address within the process. normally, the
trap will find the right page in the software mmu structures and install the map.
in this case, however, it can't find the address, so it will raise an exception
in the process (ie, send a note). (all such searches are done with the
segment properly locked.)

[-- Attachment #2.1.2: Type: message/rfc822, Size: 1746 bytes --]

From: Charles Forsyth <forsyth@terzarima.net>
To: 9fans@9fans.net
Subject: Re: [9fans] Race condition in /sys/src/9/pc/trap.c?
Date: Thu, 30 Jul 2009 16:54:16 +0100
Message-ID: <1a242b28f6d149aec599a1175df52718@terzarima.net>

just stop processes with s->ref > 1 from freeing parts of s with ibrk.
it's not as if anything ever does in practice.

  parent reply	other threads:[~2009-07-31 17:13 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-30  4:03 Matthew J Jones
2009-07-30 11:27 ` erik quanstrom
2009-07-30 14:25   ` Elizabeth Jones
2009-07-30 14:37     ` Sape Mullender
2009-07-30 15:01       ` cinap_lenrek
2009-07-30 15:24         ` cinap_lenrek
2009-07-30 15:17       ` cinap_lenrek
2009-07-30 15:54         ` Charles Forsyth
2009-07-31 13:07           ` Charles Forsyth
2009-07-31 13:28             ` Richard Miller
2009-07-31 17:13             ` cinap_lenrek [this message]
2009-07-31 18:00               ` erik quanstrom
2009-07-31 18:08                 ` Devon H. O'Dell
2009-07-31 18:18                   ` erik quanstrom
2009-07-31 18:35                     ` Devon H. O'Dell
2009-07-31 21:52                 ` cinap_lenrek
2009-07-31 19:31               ` Charles Forsyth
2009-07-31 19:40                 ` erik quanstrom
2009-07-31 20:41                   ` Charles Forsyth
2009-07-30 15:20       ` erik quanstrom
2009-07-30 14:39     ` erik quanstrom

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f390245ec5802e1703b4bd6a6b15a6c3@gmx.de \
    --to=cinap_lenrek@gmx.de \
    --cc=9fans@9fans.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).