lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CALCETrVioVM=pdCU3WhU6qDtGQyqML=btBRZ5+aV6bASj9GkOQ@mail.gmail.com>
Date:	Thu, 18 Jul 2013 17:26:12 -0700
From:	Andy Lutomirski <luto@...capital.net>
To:	linux-kernel@...r.kernel.org
Cc:	gcc@....gnu.org
Subject: [RFC / musing] Scoped exception handling in Linux userspace?

Windows has a feature that I've wanted on Linux forever: stack-based
(i.e. scoped) exception handling.  The upshot is that you can do,
roughly, this (pseudocode):

int callback(...)
{
  /* Called if code_that_may_fault faults.  May return "unwind to
landing pad", "propagate the fault", or "fixup and retry" */
}

void my_function()
{
  __hideous_try_thing(callback) {
    code_that_may_fault();
  } blahblahblah {
    landing_pad_code();
  }
}

Windows calls it SEH (structured exception handling), and the
implementation on 32-bit Windows is rather gnarly.  I don't really
know how it works on 64-bit windows, but I think it's saner.

This has two really nice properties:

1. It works in libraries!

2. It's localized.  So you can mmap something, read from it *and
handle SIGBUS*, and unmap.

Could Linux support such a thing?  Here's a sketch of a way:

 - The kernel would need to have a fairly well-defined concept of
synchronous faults that can be handled with this mechanism.  Calls to
force_sig_info are probably the right thing to hook in to.

 - The userspace runtime optionally registers (via a new syscall or
prctl, say) a handler for synchronous faults.

 - When a synchronous fault happens, if the process (struct
sighand_struct) has a synchronous fault handler registered, the signal
is delivered to that handler, on the thread that faulted, instead of
via the normal signal handling mechanism.

 - The userspace runtime walks the chain of personality handlers and
gives them a chance to respond.

 - If no handler claims the fault, then the user code somehow* causes
ordinary signal delivery to happen.

* This may need kernel help, too -- if the process is going to die, it
should die for the right reason, so perhaps there should be a syscall
to redeliver the signal.  If the runtime wants to be fancy and a
signal handler is installed, then there could be a fast path.  Maybe
if we got really fancy, it could live in the vdso.

Now everyone wins!  After someone writes the libgcc support for this
(ugh!), then you can write CFI-based exception handlers in assembly!
Presumably you could write them in C++, too, if you don't care about
restarting, like this:

try {
   code_that_may_fault();
} catch (cxxabi::synchronous_kernel_fault &) {
   amazingly_dont_crash();
}

Is this worth persuing?  I'm not touching the gcc part with a ten-foot
pole, but I could probably do some of the kernel work.  I'm a bit
scared of libgcc, too.

It's worth noting that SIGBUS isn't the only interesting signal here.
SIGFPE could work, too.  I'm not sure whether SIGPIPE would make
sense.  SIGSEGV would clearly work, but anyone using this mechanism
for SIGSEGV is probably asking for trouble.


--Andy

P.S.  Just because you can probably get away with throwing a C++
exception from a signal handler right now does not mean it's a good
idea.  Especially in a library.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ