arielby's comments

arielby | 10 years ago | on: Critical Xen bug in PV memory virtualization code

No. This is a subtle vulnerability that involves the flags in the x86 page table not matching the hypervisor's view of them - not a mere buffer overflow. Ordinary static analysis couldn't have fixed this. Safe languages couldn't have fixed this. Even a complete formal proof would have missed this without a good model.

arielby | 10 years ago | on: Critical Xen bug in PV memory virtualization code

> This bug might also be considered an argument for the view of ditching of para-virtualized (PV) VMs, and switch to HVMs

It's not like Xen HVMs have a better security story than PVMs. The paravirtualization code should probably be more heavily audited than it is already.

arielby | 10 years ago | on: BoringSSL

Not more difficult than C - you write the crypto functions in asm. You could use a C compiler to handle the ABI but the code isn't really C code.

arielby | 10 years ago | on: Several types of types in programming languages

The arithmetic operators in x86/x86-64 are certainly polymorphic (over word-length, plus integer vs. x87 vs. SSE).

I think the distinction is that #3b-types, which denote the "encoding" of a value, mapping it to its meaning, are often used as a basis for a #2-types system (to parametrize operations).

arielby | 10 years ago | on: Several types of types in programming languages

I would split use #3 into two parts: 3a) disambiguation for builtin operators - e.g. a float local needs to go in a float register, adding 16-bit integers uses 16-bit addition, a struct local needs to go in an appropriately-sized memory location. This is basically the same as #2. 3b) schema-ed data storage. This allows laying out structured data in a compact way in memory (e.g. `struct x { int a; int b; }` consists of 2 integers one after the other). This functionality is useful even in unityped code.

arielby | 10 years ago | on: St. Petersburg paradox

The problem with the original lottery is that most of its value is from high-EV tiny-probability events, e.g. the 2^{-50} probability of winning 2^50 dollars. The practical result of that event does not seem to be worth 2^50 utilons, to say the least. It is hard to think about events worth that many.

However, many perturbations of this lottery can actually be good bets.

For example, suppose you gain 3^n dollars with probability 2^{-n}. Then you have a 1/128 chance of winning $2187, a 1/256 change of winning $6561, and this game starts looking much nicer.

The "Pascal's Mugging" divergence is a different problem, where Solomonoff-style priors imply negative-exponential probabilities of Busy-Beaverish payoffs. Ordinary priors don't really have this problem.

arielby | 10 years ago | on: Factoring RSA Keys with TLS Perfect Forward Secrecy

This is the well-known CRT fault attack, nothing new. SSL implementations that don't verify their signatures leak the private key if their signature routine has a bug - this is essentially a hardware problem. Verifying your signatures is fast, though, so doing it is worthwhile hardening (NSA can potentially use cosmic rays for this attack, probably nobody else).

The findings are very similar to the classic "Ron was wrong, Whit is right" paper - if you scan the entire Internet, you will find broken hardware. You will also find SSH servers with their root password being `12345678`.

arielby | 10 years ago | on: What is wrong with NULL

well C++11 strings are just "reallocate when you look at them funny". Or you use shared_ptr and are back to square 1.

arielby | 10 years ago | on: What is wrong with NULL

> Slicing Pascal-style strings is also easy and constant-time: just track the buffer, offset, and length of the slice of characters you want. Java used to do it implicitly whenever you called `substring`.

That's just coercing into a "modern C buffer" and slicing it. It has the disadvantage that coercion is not equality or subtyping - i.e. you will have to do lots of wrappings and unwrappings in mixed code.

> Every C method that takes a character buffer either a) has a corresponding length parameter or b) is avoided because of the security risks. In practice this means that C also stores the length information, just on the side instead of combined into a struct with the buffer.

You are surely talking about the buffer's capacity, not the string's length. These are distinct concepts. Anyway, functions that only read strings, and structs that only store them read-only, aren't interested in the capacity of any buffer.

Anyway, C strings aren't responsible for the fixed-size buffers of Cold War-era code - that code uses fixed-size buffers for everything. Their main claim to fame is their popularity in parsing code, which is edge-case- and bug-prone.

arielby | 10 years ago | on: What is wrong with NULL

NUL-terminated strings aren't that bad:

* unlike Pascal-style strings, they can be usefully sliced, especially if you can modify them strtok-style.

* unlike (ptr,len) "Modern C buffers"/Rust-style strings, references to them are pointer-sized, and they can be used as a serialization format.

This makes the kind of application that is based on cutting pieces of a string and passing them around a good measure faster, especially compared to say C++'s "atomically reference-counted, re-allocating at the slightest touch" std::string.

This style of programming is not particularly popular nowadays, so buffer-strings are better-fitting. Its main problem is its multitude of edge-cases, which tend to demonstrate C's "every bug is exploitable" problem well.

arielby | 10 years ago | on: Lock freedom without garbage collection in Rust

According to the paper, it simply makes everywhere outside of data structure code a quiescent state. This may be a big difference in practice through, because one of the appeals of RCU is being able to interact with data structures with no fear of following dangling pointers.

However, with both RCU and the epoch-based scheme, you can make quiescent states as fine- or coarse-grained as you desire.

arielby | 10 years ago | on: Lock freedom without garbage collection in Rust

Could someone explain the big difference between RCU and epoch-based reclamation? It seems that the only difference is that RCU has quiescent periods between reschedules and epoch-based has them when you don't have a Guard struct active. Seems like six of one, half a dozen of the other.

arielby | 10 years ago | on: Indices Point Between Elements

A pointer points to the start of its pointee - i.e. the point "just before" its pointee. That's how derived-to-base casts work. That's also how you can have "one-past-the-end" pointers, which are actually "just after" the relevant array.

for example, if you have the following structs

    typedef struct { void *key; } base;
    typedef struct { base b; int misc; int data[2]; } derived;
then derived is laid out as follows

    -----+------+---------+---------+---------+-----
     ... | base | derived | data[0] | data[1] | ...
    -----+------+---------+---------+---------+-----
         ^                ^                   ^
         |                |                   |
        base         derived.data      &derived.data[2]
page 1