This is the problem with uninspired formalism. You throw up your hands and say "impossible," when a small (and very reasonable) compromise would yeild very useful results. Here's what the pbzip2 manpage says about that issue:
There is something to be said about being overly formal. There is also something to be said about comparing apples to oranges. The GP made a statement about bit-serial compressors, and the parent cited information from a batch compression algorithm.
bzip2 is based around the Burrows-Wheeler transform (BWT). The BWT is inherently a batch operation on blocks of data. IIRC, bzip2 uses 900,000 byte blocks. The BWT is also very CPU-intensive as long as the block size fits within the CPU cache. As I remember, little if any state is carried over between encodings of blocks. This is embarassingly parallel.
gzip, on the other hand, works with a sliding window, so each byte is influenced by the preceeding N bytes (32 kBytes, as I remember). This inherently serializes compression. There is a way of marking resets of state in the compression stream, so it would be possible to encode something like 32 MB pieces of a file in parallel and mark a state reset when joining the sections together. One could manually get this effect using dd to generate temporary files , gzipping the files, and then concatenating the compressed temporary files (in order, of course).
More importantly, the parent's criticism of the GP fails to take use cases into account. When maximum compression is needed, bzip2 or 7zip is usually used. However, gzip is used in cases where low compression latency and low memory footprint is desired. Buffering large amounts of input in order to facilitate parallelization may be counterproductive in the use cases where gzip is more desirable than bzip2 or 7zip.
As a US poster and grammar Nazi wannabe, let me be the first to say:
"The Canadians show how they are smarter and think clearer thAn Americans."
Don't forget to point out that (to the best of my knowledge), "clearer" has not formally been accepted as an adverb in any of the major English dialects. "More clearly" and "more clear" are the most commonly accepted ways to construct comparative adverbs from the adjective "clear" and the adverb "clear", respectively.
English text has only one point something bits of entropy per character on the usual estimate.
This is for English prose, using proper capitalization and spelling. Jokes about average slahdotters' spelling aside, presumably anyone using 60-character
pasphrases purposely contorts the phrase to increase its entropy.
Back in school, just for my own use I wrote a java applet that would use SecureRandom.seed(byte[]) and user-entered text to seed a CSPRNG, which was
used to randomly select words from a list of 2048 words of 5 letters or
less (with a few two-letter non-words thrown in). Capitialization of the
first and last letters of each word was randomized for a total of 13 bits
of entropy per word... which works out to around 3 bits per character.
"popE melT Apple fun UndeR" <- 65 bits, no longer in use by me
It's not very hard at all to remember a goofy phrase made up of 5 random
words with random capitalization. For my most important passwords, I used 8
word phrases, and sometimes replaced one of the words with 4 base64 digits
obtained by MIME-encoding some data from/dev/random. I can't remember
many pass phrases that long, so I only used the 104-118 bit passwords for
cryptographic purposes. Login passwords generally have an enforced maximum
rate of guesses, so 65-bits should be sufficient in most cases, as long
as the login password isn't used for drive encryption.
If our browsers used interprocess communication instead of cooperative multitasking (a concept far more outdated than 32 bit binaries) then this wouldn't be a practical problem.
I agree with what I think roystgnr was trying to say, but...
"You keep usinging that word. I do not think it means what you think it means." The conditions under which a context switch may be initiated is an orthogonal issue to the number of OS-level processes/tasks used to achieve a goal.
In pretty much any OS apart from MS DOS, an ancient version of the Macintosh System, or some toy OS (jokes about DOS and System 2.0 aside), the kernel (control program, executive, or equivalent notion) is capable of initiating a context switch without corrupting the state of the running thread.
Maybe roystgnr is confused because several OSes introduced memory protection around the same time that they introduced preemptive multitasking.
In any case, I think that roystgnr was trying to say that memory protection is underutilized by modern browsers. I would add that fault tolerance mechanisms in general tend to be under-utilized in modern software systems, especially in systems that rely on software components from 3rd parties (from device drivers on up).
The issue is the number of lines of code (assuming rougly equivalent complexity of lines of code) that must be audited in order to be reasonably sure that your code is free from a certain type of bug. (In some domains, "resonably sure" means "formally proven with full documentation" for certain types of bugs.)
With Java, some of the most complicated and historically bug-ridden code is encapsulated in the JVM and re-used by every single program, rather than spread throughout the code, doomed to be reimplemented by every software intern. It's about isolating the parts that people historically are bad at programming, auditing them, and heavily re-using the highly audited implementations.
If you don't trust your virtual machine and/or runtime, then the solution is to use a FOSS (or at least source-available) VM/runtime and audit the security critical portions yourself. On the other hand, very few people would fault you for using the JVM and Java runtime from the EAL-4 version of Solaris (if it contains a JVM and Java runtime... I'm not sure on that part) and just assuming that a Department of Defense EAL-4 audit is more rigorous that the audit you would perform yourself.
C and C++ use manual array bounds checking. Every line of code that uses arrays or pointers must be audited in order to assure reads and writes are in bounds. Once you've audited the (very few) lines of code in the bytecode interpreter and the JIT responsible for inserting bounds checks, you can be sure that out-of-bounds reads and writes will fail in all of your Java code.
C and C++ are weakly statically typed languages. In other words, you can completely bend the type systems by upcasting to (void *) and then perform uchecked downcasts. After you've audited the class loader, you can be sure your Java code is free from such manglings of the type system. The same sort of assurances in C/C++ require auditing all of your code. The author of TFA says that Java loses the strict data-code seperation of PAX. However, the JVMs strict enforcement of type safey already creates strict data-code seperation.
C and C++ use manual allocation and freeing of memory. In very complicated cases, engineers may have no choice but to use third-party automatic memory managers, or implement their own reference counting or other memory management systems. Proving that code does not perform double-frees can be very complicated. On the other hand, with Java code, only an audit of the JVM's garbage collector is required. (Depending on the exact type of garbage collector used, some other code may need to be audited to ensure that some of the representational invariants of the internal object representation are not violated.)
Wouldn't a buggy JVM that messes up on bounds checking still be able to generate buggy code? Or one that decrements a reference count in the garbage collectory too much, so it hits -1 and gets freed; then later bumps over that again and frees again. Double frees, buffer overflows.
I think you misunderstand the grandparent. The grandparent's point is that the C "Error kernel" includes the compiler, while for the most part the Java class loader will catch Java compiler bugs.
The array bounds checking in most JVMs is implemented in probably only one place, whereas bounds checking must be done every time an array is accessed in C (counting a
formal proof that an index is within bounds as an optimized bounds check). How many
lines of code must be audited for a formal proof that none of your 4 million lines of Java code will smash the stack? Now, what about the same question for your 4 million lines of C code?
You have the same flawed logic in your example about double-frees. The point is that the number of lines of code that must be audited in order to avoid the most common and costly bugs is minimized. You only need to audit the garbage collector in order to ensure that Java programs don't have double-frees.
Also, it's my understanding that most JVMs don't use reference counting.
Which is better, an open source VM(python/Mono) or closed source VM(Java/.Net) for security?
There are several OSS Java VMs. (Kaffe, IKVM, Jikes RVM, etc.)
Python is one of my favorite languages, but from a security standpoint, dynamic typing introduces a whole class of errors and makes code audits more difficult.
Sure, one could introduce manual type checks at the beginnings of methods and raise
TypeErrors, as well as checking returned types. However, the more correctness (security is a subset of correctness) checks that are performed/inserted by the compiler,
the fewer chances there are for undetected errors. Also, manual insertion of runtime time checks doesn't guarantee correctness, it only guarantees that type errors generate runtime failure and detection of incorrectness.
It would be neat if there were a type-inferencing lint for Python. Are any of you aware of such a beast?
(And yes, I'm aware of the Boo language, as well as proposals to add optional static typing to Python.)
Anyone care to explain why they opted for using pin numbers instead of electronic signature recognition - I was under the impression that signature recognition is quite reliable (it's certainly been around for a while). Signatures are much harder for someone to reproduce than a PIN and this method would remove the need for the cachier to check the signature (which they don't do anyway).
PIN technology was probably the easiest, cheapest, fastest solution. It's merchants that get hurt the most with fraud. It's my understanding that the credit card company still keeps its transaction fee on fraudulent transactions, the merchant pays back the fraudulent charge to the CC company, and the provider of the merchant account charges a "chargeback fee" to the merchant. The CC company makes the same amount of profit (minus a few minutes of wages for their phone staff), the merchant account provider makes more profit, and the merchant absorbs almost all of the costs.
For fraud prevention, the optimum cost/benefit point for the CC companies is much lower than that for the merchants. Unfortunately, it's the CC companies and merchant account providers that deploy the systems.
Also, people have a small tolerance for false negatives.
People are probably less likely blame a keypad for a false nagative as compared to a signature reader. People will probably get more angry at having to sign three times for a single transaction to succeed than having to input a PIN five times for a single transaction to succeed.
Um...there is no x86 emulation mode. The AMD64 is x86 with 64 bit extensions. All x86 software runs EXACTLY the same with no emulation.
Umm... are you saying that the AMD64 64-bit mode instructions are a superset of the i586 instructions? This is not the case and for this reason there is a seperate 32-bit compatibility mode for running 32-bit applications under 64-bit kernels. (See citation below.)
I think the poster meant 32-bit compatibility mode, not "emulation mode". The differences between a "legacy emulation mode" and a "legacy compatibility mode" are mostly semantic. In any case, the AMD64 instruction set is not a superset of the i586 instruction set, hence long-mode 32-bit ring3 "compatibility mode", which causes the CPU to run in 64-bit mode in ring0, but 32-bit mode in ring3. The FPU programming model is no-longer stack-oriented in 64-bit mode and I've heard that the BCD arithmetic instructions are gone in 64-bit mode. However, I have no personal in-depth knowledge of the ISA changes. Some instruction encodings have definately been eliminated in 64-bit mode. (See citation below)
See "The AMD64(tm) ISA Value Proposition", especially the first sentence in the last paragraph of page 5, which reads "Additionally, some of the binary instruction encodings have been eliminated to support future instruction set expansion." Also see the bottom of page 9, where it mentions the outdated x87 FP stack is eliminated in favor of a more modern FP register file. Clearly, the AMD64 ISA is not a superset of the i586 ISA.
Compare the multi-level 16-bit/32-bit/64-bit AMD64 compatibility modes (including kludges like the A20 gate) to the POWER/PowerPC ISA, where the original ISA was designed to be 64-bit with a pre-defined subset for 32-bit implementations. It's a shame Intel didn't come up with a completely new architecture and create a software emulator to ease transition, a la Apple's switch from m68k to PPC. At least AMD is finally getting rid of the x87 FP stack (except in compatibility modes).
Maybe some day there will be an x86 chip that starts up in 64-bit mode and allow the boot loader to switch the CPU into legacy modes so OS writers can forget all of that legacy kludge (including using a spare pin on the keyboard controller to determine the functionality of the 21st memory bus address line... necessitating keyboard controller chipset-dependent code to change addressing reverse-compatibility...)
Re:Why the Democrats lost the election
on
Buggy Voting Machines
·
· Score: 2, Informative
Remember in the scene in Dumb and Dumber where Jim Carrey's character hits on a really hot girl who says she's Austrian, and the male character procedes to say "Gooday" and "Throw a shrimp on the barbey"?
2. Democrats did not learn form the
Austrian elections: The Australian Prime Minister Howard took a lot of heat for supporting Bush and his war in Iraq. The media expected a big loss for Howard on the last election, but Howard ended winning by a good margin. When the Austrian voters were polled, most of them responded that they voted for Howard because economy was a bigger issue than the Iraqi war.
One out of three isn't so bad... Howard is the Australian PM, not Austrian.
My apologies if you really meant to talk about the Australian PM's influence on the voting habbits of a population halfway around the world from Australia.
Re:Swiss Internet voting built on two-factor authe
on
Buggy Voting Machines
·
· Score: 3, Informative
Discount anything claiming "foolproof security".
The Swiss system doesn't provide propper 2-factor authentication, as both pieces of information are something the user knows. No biometric or hardware token authentication is invoved. Itercepting the card and knowing a little about the person will give an attacker access.
Even 3-factor authentication doesn't provide foolproof security, unless you mean secure against fools as attackers.
Close, but no cigar. ED2K uses MD4 instead of MD5. MD4 is weaker, but faster to compute. MD5 was created when certain weaknesses in MD4 were pointed out. MD4 and MD5 are very similar.
(I believe nobody has solved the second pre-image problem for MD4. In other words, MD4 is weakly collission resistant but not strongly collision resistant. It takes less than 2^64 trials to create two bogus files with the same MD4 sum. However, I'm not aware of anyone demonstratting an attack that takes less than an average of 2^127 trials, or equivalent time, to generate a file with the same MD4 sum as a given legitimate file.)
Not that the distinction matters much now that MD5 has recently been shown to not be strongly collision resistant. MD4 and MD5 fall into pretty much the same category. In any case, it appears that for the purposes of detecting bogus shared files, MD4 and MD5 are both still sufficient. However, if I were to design a new protocol, I would probably use a truncated SHA-512 sum in order to allow for smooth transitions to longer hash sizes if the need arose.
XOR one-time pads are proovably secure, given that they are used properly. The proof does not rely on P != NP. The proof is rather simple: the ciphertext could be absolutely any of the possible plaintexts of the same length and an attacker has no way of deciding amoung plausible decryptions.
Now, the grandparent probably meant something very different, such as large modulus RSA and 3DES are conjectured to require several decades to crack. However, there are a whole class of one-time-pad ciphers that are provably secure. (Although they are impractical for most uses.)
I've heard that some governments send diplomatic couriers with breifcases full of DVD-RWs (containing OTP keys) to their embassies for their most secret traffic. Bits of the keys are burned over as they are read from the DVD-RWs and once a DVD is used up, it is shreaded. Periodically, the shreds are incinerated. As a rough estimate, a courier could probably inconspicuously carry 250 DVD-RWs, which works out to encryption keys enough to cover 1 TB of the most sensitive secrets.
Now, given that the US government allows tripple-wrapped SECRET documents (but not TOP SECRET) to be sent via regular mail, one could argue that sending website subcribers a few DVD-RWs full of OTP keys once a month could be considered a solution to the key distribution problem for low-level secrets, such as everyday chess game moves.
I have read elsewhere that they were using the Windows Encrypted File System, but using export grade (40-bit) encryption. As I remember, Win2k needs a 128-bit encryption upgrade patch to use X-DES rather than 40-bit DES.
Also, most people are very very bad with passwords and have no clue how weak their passwords are. Even if they were using 128-bit EFS, I doubt their passwords were anywhere near 40-bit strength against an Arabic dictionary attack.
Yes, you could soup-up your keyless entry keychain and jam the aircraft carrier, but I doubt the military would be able to prosecute. You will cook your head trying to jam an aircraft carrier's radar with a 100 MW home-brew keyless entry amplifier. Welcome to the Darwin awards.
It is much easier to search your person at the exit than it is to monitor all radio communications in and out of the building.
I would venture to say the ease of getting caught is much more important to security than the difficulty of actually performing espionage.
Restrictive rules are also probably more effective than posters at getting across the idea that you DO NOT bring your work home with you or talk about it outside the building. Rules are sometimes used to send messages and encourage mindsets rather than directly prevent problems.
A few users with tons of spyware will affect the mean greatly, while the median number of spyware programs per computer is much less affected by the statistical outlyers. I generally find the median less misleading than the mean. Then again, maybe I am just an idiot that has problems with means.
There is only one way to make copy protection work:
Make the amount of effort required to bypass the copy protection greater than the gain.
Ahh... so if experience seems to indicate that all copy protection mechanisms eventually become trivial to defeat... then the solution to the "copying problem" is crappier movies. A dim bulb brightens! Suddenly the world makes so much more sense!!!
GCC/DJGPP has been running on Win32 for a long time. It is probably easier to port *nix IDEs using GCC/DJGPP, since GCC syntax quirks will not need to be exchanged for MS VC syntax quirks.
Many of Linus's arguments apply to older microkernels like Minux and Mach, but not to newer microkernels like L4 Pistachio or the QNX kernel. As I remember, the QNX kernel for x86 is about 65 kB, half in assembly and half in C or C++.
Darwin isn't really a microkernel. The 4.4 BSD OS personality runs in the same address space as the kernel. (It's like one huge kernel module.) I think NeXT ran its 4.3 BSD personality in user space for better stability but worse performance. Apple acquired NeXT, upgrade the personality to 4.4 BSD, and decided to merge the BSD personality into the kernel to increase performance. Fortunately, I believe it's still possible for Apple to move the BSD personality back into user space and switch out Mach for a more modern microkernel without the user-space apps knowing the difference. (Does Apple publish the API for accessing the Mach system calls directly?)
I think Mach itself is about as big as a slimmed down Linux kernel. There is plenty of documentation out there describing how Mach was revolutionary in its day, but suffers from kernel bloat and is based on early microkernel ideas. There are much smaller and responsive microkernels out there. Many of the biases against microkernels are due to experience with Mach and other early microkernels.
Don't get me wrong. I like microkernels and think Darwin is a step in the right direction. I ran L4Linux (basically User Mode Linux on top of an L4 micro-/nano-kernel) for a little while, but the Linux 2.2 port to L4 user-space wasn't very stable back then. L4Linux was my only process that didn't depend on L4Linux, so when L4Linux died, all of my other processes hung. Linux with the stability of Win95!
I liked QNX and BeOS. They're both "fun" operating systems on top of microkernels. BeOS was single-user and had many file system anoyances (web browser shortcuts are 0 byte files with the URI in metadata, so that a tar ball of your shortcuts isn't sufficient to restore them after a complete OS reinstall... I learned that the hard way), but it was rather friendly and "slick" in its own way. There was lots of software and a friendly OSS/freeware community. My network driver had stability issues and about once a day or every other day I'd get a message like "your nextwork driver just shat all over everything and had to be killed. Would you like to start it again?" Open sockets would all close, but because it was a microkernel with drivers in their own address spaces, the driver would crap all over itself but not take the kernel or any other driver down.
I had a currupted UDF CD-RW that would crash both Win2k and Linux 2.4. It was so anoying to have to reboot every time I failed to recover data off of that CD.
It would be great if we started seeing OSes with each driver in its own process. Experimental or low quality drivers wouldn't be so much of a pain. The L4 hazelnut kernel has fast context switches and the fastest inter-process communication of any x86 kernel (well, any kernel known to its developers), at least it did a few years ago. This means that the price paid for putting drivers in their own process is pretty low.
I've seen a sourceforge project that is developing a kernel module to export a fexible and generic driver interface to userspace. Linux has fairly fast context switches because in the early days it didn't have good threading support, so the devlopers tweaked the hell out of context switches so that context switches on Linux could almost compete with thread switches on other OSes. Linux 2.6 is much more modular than 2.4 and seems that user-space drivers are the next logical step. Well, I can dream at least.
The larger code size of a memory-based representation is partially due to some of the information being redundantly present in a form that makes efficient register allocation easier. This information can still be extracted from stack-based representations, but more processing time is required.
Like I said... read Ken Thompson's paper. I didn't say you can't generate efficient native code from a stack-based representation... I just said that other representations allow the process to run faster. Basically, a stack-based VM is a two-register VM (top two items on the stack). Stack-based representations do imply a finite register file (either zero or two GP registers, depending on your point of view). A memory-based representation assumes a register file that spans your entire address space. If you want to generate code optimized for more registers than are represented in your byte code, you end up taking the byte code and working backwards to the AST/ASD, using the AST/ASD to generate RTL, and register folding the RTL down to the number of registers you actually have. See OpenJIT for an example of generating ASTs from Java bytecode.
If, on the other hand you use a VM with more registers than your hardware (such as a memory machine), you can treat the VM bytecode as RTL and register fold it down to the number of registers you actually have, allowing you to skip the first two steps.
Now, there are other JIT techniques that are faster, but result in less efficient register allocation and therefore less efficient native code. On register-starved architectures like ia32, the difference in register allocation may not be very noticable.
For most applications, it makes sense to trade larger code size for more speed. If you're running your VM in an embedded environment, that's a different story. At the moment, it seems that speed is more of a problem for Java adoption than code size is.
On the other hand, I have played with the idea of VM with two instruction sets... a stack-based instruction set that gets compiled to native code when the object code is downloaded/installed (taking the time to optimize the heck out of the code) and a memory-based instruction set that gets JIT compiled.
I agree that it would be nice to have many common languages that will compile well for a common virtual machine. Java is a nice language, but I also really like Ocaml, Python, and other languages that aren't easily expressed in JVM or.NET CLR bytecode.
The JVM and.NET CLR both enforce a strongly typed object model at the lowest levels. As much as Microsoft would like you to think otherwise, the.NET CLR leverages heavily on Microsoft's experience writing a JVM. Both virtual machines can trace their lineage to Sun's Oak project, designed to express the symantics of only a strongly statically typed language and be interpretable on 8-bit microcontrollers in toasters and fridges. Stack based virtual machines are simple to implement and are nearly ideal for interpreters (see Xavier LeRoy's design paper for Zinc, the Ocaml VM) but very much not ideal for just-in-time compilation (see Ken Tompson's design paper on Dis, the Inferno OS VM). There's simply a lot of work that has to be done in order to get the abstract syntax tree back out of the stack-based byte code.
Essentially, your stack-based bytecode is optimized for a two-register machine (the top two values on the stack). If you're close to having only two spare registers after the VM claims a couple for overhead, then directly JIT compiling stack based VM code doesn't create code that's that bad. In this sense, stack-based JIT VMs aren't so bad on register-starved architectures like x86. However, on architectures like x86-64, PowerPC, Itanium, and Sparc, and MIPS, you really want to work backwards from the bytecode to the AST and then generate RTL and finally do register folding on the RTL so that it will run on the number of registers you really have.
On the other hand, Parrot bytecode with its 3 sets of 16 registers can probably be directly translated to RTL and generate very good code on most architectures. (Itanium has many more than 32 GP and 16 FP registers, so it will take a lot of work to get Parrot to take full advantage of Itanium. Register folding even on x86 should take much much less time than AST and RTL generation from stack-based bytecode.)
Finally, the Dis virtual machine has more or less 4 billion registers (it's a memory-based virtual machine). If a partucular routine for Dis takes more registers than physically available, then your JIT compiler will need to perform register folding, but for most machines with fewer than 4 billion physical registers, Dis should generate good native code very quickly and easily.
Something like Parrot or Dis would make a much better target for a C++ compiler because of the less restrictive object models. If you wanted pointer safety or a more strict object model, that could be enforced more flexibly in the (replaceable) class loader than in the VM's low-level functionality.
There's also the point that the JVM provides no opcodes for pointer arithmetic and no way to cast between pointers (references) and integers. Using a class loader that allows integer opcodes when a reference is on top of the stack will break on VM implementations that use a seperate reference stack to improve garbage collection. You could have all of your objects live in an array of ints and emulate pointer arithmetic with index changes and bit shifts, but that makes using standard Java libraries with your objects much more difficult and slower.
Does it crash under VMWare or does VMWare crash? Your heading makes it sound like a CoLinux bug, but your text makes it sound like a VMWare bug. My guess is that it's a VMWare bug.
There is something to be said about being overly formal. There is also something to be said about comparing apples to oranges. The GP made a statement about bit-serial compressors, and the parent cited information from a batch compression algorithm.
bzip2 is based around the Burrows-Wheeler transform (BWT). The BWT is inherently a batch operation on blocks of data. IIRC, bzip2 uses 900,000 byte blocks. The BWT is also very CPU-intensive as long as the block size fits within the CPU cache. As I remember, little if any state is carried over between encodings of blocks. This is embarassingly parallel.
gzip, on the other hand, works with a sliding window, so each byte is influenced by the preceeding N bytes (32 kBytes, as I remember). This inherently serializes compression. There is a way of marking resets of state in the compression stream, so it would be possible to encode something like 32 MB pieces of a file in parallel and mark a state reset when joining the sections together. One could manually get this effect using dd to generate temporary files , gzipping the files, and then concatenating the compressed temporary files (in order, of course).
More importantly, the parent's criticism of the GP fails to take use cases into account. When maximum compression is needed, bzip2 or 7zip is usually used. However, gzip is used in cases where low compression latency and low memory footprint is desired. Buffering large amounts of input in order to facilitate parallelization may be counterproductive in the use cases where gzip is more desirable than bzip2 or 7zip.
This is for English prose, using proper capitalization and spelling. Jokes about average slahdotters' spelling aside, presumably anyone using 60-character pasphrases purposely contorts the phrase to increase its entropy.
Back in school, just for my own use I wrote a java applet that would use SecureRandom.seed(byte[]) and user-entered text to seed a CSPRNG, which was used to randomly select words from a list of 2048 words of 5 letters or less (with a few two-letter non-words thrown in). Capitialization of the first and last letters of each word was randomized for a total of 13 bits of entropy per word... which works out to around 3 bits per character.
"popE melT Apple fun UndeR" <- 65 bits, no longer in use by me
It's not very hard at all to remember a goofy phrase made up of 5 random words with random capitalization. For my most important passwords, I used 8 word phrases, and sometimes replaced one of the words with 4 base64 digits obtained by MIME-encoding some data from /dev/random. I can't remember
many pass phrases that long, so I only used the 104-118 bit passwords for
cryptographic purposes. Login passwords generally have an enforced maximum
rate of guesses, so 65-bits should be sufficient in most cases, as long
as the login password isn't used for drive encryption.
I agree with what I think roystgnr was trying to say, but...
"You keep usinging that word. I do not think it means what you think it means." The conditions under which a context switch may be initiated is an orthogonal issue to the number of OS-level processes/tasks used to achieve a goal.
In pretty much any OS apart from MS DOS, an ancient version of the Macintosh System, or some toy OS (jokes about DOS and System 2.0 aside), the kernel (control program, executive, or equivalent notion) is capable of initiating a context switch without corrupting the state of the running thread.
Maybe roystgnr is confused because several OSes introduced memory protection around the same time that they introduced preemptive multitasking.
In any case, I think that roystgnr was trying to say that memory protection is underutilized by modern browsers. I would add that fault tolerance mechanisms in general tend to be under-utilized in modern software systems, especially in systems that rely on software components from 3rd parties (from device drivers on up).
With Java, some of the most complicated and historically bug-ridden code is encapsulated in the JVM and re-used by every single program, rather than spread throughout the code, doomed to be reimplemented by every software intern. It's about isolating the parts that people historically are bad at programming, auditing them, and heavily re-using the highly audited implementations.
If you don't trust your virtual machine and/or runtime, then the solution is to use a FOSS (or at least source-available) VM/runtime and audit the security critical portions yourself. On the other hand, very few people would fault you for using the JVM and Java runtime from the EAL-4 version of Solaris (if it contains a JVM and Java runtime... I'm not sure on that part) and just assuming that a Department of Defense EAL-4 audit is more rigorous that the audit you would perform yourself.
C and C++ use manual array bounds checking. Every line of code that uses arrays or pointers must be audited in order to assure reads and writes are in bounds. Once you've audited the (very few) lines of code in the bytecode interpreter and the JIT responsible for inserting bounds checks, you can be sure that out-of-bounds reads and writes will fail in all of your Java code.
C and C++ are weakly statically typed languages. In other words, you can completely bend the type systems by upcasting to (void *) and then perform uchecked downcasts. After you've audited the class loader, you can be sure your Java code is free from such manglings of the type system. The same sort of assurances in C/C++ require auditing all of your code. The author of TFA says that Java loses the strict data-code seperation of PAX. However, the JVMs strict enforcement of type safey already creates strict data-code seperation.
C and C++ use manual allocation and freeing of memory. In very complicated cases, engineers may have no choice but to use third-party automatic memory managers, or implement their own reference counting or other memory management systems. Proving that code does not perform double-frees can be very complicated. On the other hand, with Java code, only an audit of the JVM's garbage collector is required. (Depending on the exact type of garbage collector used, some other code may need to be audited to ensure that some of the representational invariants of the internal object representation are not violated.)
I think you misunderstand the grandparent. The grandparent's point is that the C "Error kernel" includes the compiler, while for the most part the Java class loader will catch Java compiler bugs.
The array bounds checking in most JVMs is implemented in probably only one place, whereas bounds checking must be done every time an array is accessed in C (counting a formal proof that an index is within bounds as an optimized bounds check). How many lines of code must be audited for a formal proof that none of your 4 million lines of Java code will smash the stack? Now, what about the same question for your 4 million lines of C code?
You have the same flawed logic in your example about double-frees. The point is that the number of lines of code that must be audited in order to avoid the most common and costly bugs is minimized. You only need to audit the garbage collector in order to ensure that Java programs don't have double-frees.
Also, it's my understanding that most JVMs don't use reference counting.
There are several OSS Java VMs. (Kaffe, IKVM, Jikes RVM, etc.)
Python is one of my favorite languages, but from a security standpoint, dynamic typing introduces a whole class of errors and makes code audits more difficult. Sure, one could introduce manual type checks at the beginnings of methods and raise TypeErrors, as well as checking returned types. However, the more correctness (security is a subset of correctness) checks that are performed/inserted by the compiler, the fewer chances there are for undetected errors. Also, manual insertion of runtime time checks doesn't guarantee correctness, it only guarantees that type errors generate runtime failure and detection of incorrectness.
It would be neat if there were a type-inferencing lint for Python. Are any of you aware of such a beast?
(And yes, I'm aware of the Boo language, as well as proposals to add optional static typing to Python.)
PIN technology was probably the easiest, cheapest, fastest solution. It's merchants that get hurt the most with fraud. It's my understanding that the credit card company still keeps its transaction fee on fraudulent transactions, the merchant pays back the fraudulent charge to the CC company, and the provider of the merchant account charges a "chargeback fee" to the merchant. The CC company makes the same amount of profit (minus a few minutes of wages for their phone staff), the merchant account provider makes more profit, and the merchant absorbs almost all of the costs.
For fraud prevention, the optimum cost/benefit point for the CC companies is much lower than that for the merchants. Unfortunately, it's the CC companies and merchant account providers that deploy the systems.
Also, people have a small tolerance for false negatives.
People are probably less likely blame a keypad for a false nagative as compared to a signature reader. People will probably get more angry at having to sign three times for a single transaction to succeed than having to input a PIN five times for a single transaction to succeed.
Umm... are you saying that the AMD64 64-bit mode instructions are a superset of the i586 instructions? This is not the case and for this reason there is a seperate 32-bit compatibility mode for running 32-bit applications under 64-bit kernels. (See citation below.)
I think the poster meant 32-bit compatibility mode, not "emulation mode". The differences between a "legacy emulation mode" and a "legacy compatibility mode" are mostly semantic. In any case, the AMD64 instruction set is not a superset of the i586 instruction set, hence long-mode 32-bit ring3 "compatibility mode", which causes the CPU to run in 64-bit mode in ring0, but 32-bit mode in ring3. The FPU programming model is no-longer stack-oriented in 64-bit mode and I've heard that the BCD arithmetic instructions are gone in 64-bit mode. However, I have no personal in-depth knowledge of the ISA changes. Some instruction encodings have definately been eliminated in 64-bit mode. (See citation below)
See "The AMD64(tm) ISA Value Proposition", especially the first sentence in the last paragraph of page 5, which reads "Additionally, some of the binary instruction encodings have been eliminated to support future instruction set expansion." Also see the bottom of page 9, where it mentions the outdated x87 FP stack is eliminated in favor of a more modern FP register file. Clearly, the AMD64 ISA is not a superset of the i586 ISA.
Compare the multi-level 16-bit/32-bit/64-bit AMD64 compatibility modes (including kludges like the A20 gate) to the POWER/PowerPC ISA, where the original ISA was designed to be 64-bit with a pre-defined subset for 32-bit implementations. It's a shame Intel didn't come up with a completely new architecture and create a software emulator to ease transition, a la Apple's switch from m68k to PPC. At least AMD is finally getting rid of the x87 FP stack (except in compatibility modes).
Maybe some day there will be an x86 chip that starts up in 64-bit mode and allow the boot loader to switch the CPU into legacy modes so OS writers can forget all of that legacy kludge (including using a spare pin on the keyboard controller to determine the functionality of the 21st memory bus address line... necessitating keyboard controller chipset-dependent code to change addressing reverse-compatibility...)
One out of three isn't so bad... Howard is the Australian PM, not Austrian.
My apologies if you really meant to talk about the Australian PM's influence on the voting habbits of a population halfway around the world from Australia.
The Swiss system doesn't provide propper 2-factor authentication, as both pieces of information are something the user knows. No biometric or hardware token authentication is invoved. Itercepting the card and knowing a little about the person will give an attacker access.
Even 3-factor authentication doesn't provide foolproof security, unless you mean secure against fools as attackers.
(I believe nobody has solved the second pre-image problem for MD4. In other words, MD4 is weakly collission resistant but not strongly collision resistant. It takes less than 2^64 trials to create two bogus files with the same MD4 sum. However, I'm not aware of anyone demonstratting an attack that takes less than an average of 2^127 trials, or equivalent time, to generate a file with the same MD4 sum as a given legitimate file.)
Not that the distinction matters much now that MD5 has recently been shown to not be strongly collision resistant. MD4 and MD5 fall into pretty much the same category. In any case, it appears that for the purposes of detecting bogus shared files, MD4 and MD5 are both still sufficient. However, if I were to design a new protocol, I would probably use a truncated SHA-512 sum in order to allow for smooth transitions to longer hash sizes if the need arose.
XOR one-time pads are proovably secure, given that they are used properly. The proof does not rely on P != NP. The proof is rather simple: the ciphertext could be absolutely any of the possible plaintexts of the same length and an attacker has no way of deciding amoung plausible decryptions.
Now, the grandparent probably meant something very different, such as large modulus RSA and 3DES are conjectured to require several decades to crack. However, there are a whole class of one-time-pad ciphers that are provably secure. (Although they are impractical for most uses.)
I've heard that some governments send diplomatic couriers with breifcases full of DVD-RWs (containing OTP keys) to their embassies for their most secret traffic. Bits of the keys are burned over as they are read from the DVD-RWs and once a DVD is used up, it is shreaded. Periodically, the shreds are incinerated. As a rough estimate, a courier could probably inconspicuously carry 250 DVD-RWs, which works out to encryption keys enough to cover 1 TB of the most sensitive secrets.
Now, given that the US government allows tripple-wrapped SECRET documents (but not TOP SECRET) to be sent via regular mail, one could argue that sending website subcribers a few DVD-RWs full of OTP keys once a month could be considered a solution to the key distribution problem for low-level secrets, such as everyday chess game moves.
Also, most people are very very bad with passwords and have no clue how weak their passwords are. Even if they were using 128-bit EFS, I doubt their passwords were anywhere near 40-bit strength against an Arabic dictionary attack.
Higher-end switches can be configured to stop accepting new MAC addresses instead of falling back to hub mode when their ARP tables get full.
Yes, you could soup-up your keyless entry keychain and jam the aircraft carrier, but I doubt the military would be able to prosecute. You will cook your head trying to jam an aircraft carrier's radar with a 100 MW home-brew keyless entry amplifier. Welcome to the Darwin awards.
I would venture to say the ease of getting caught is much more important to security than the difficulty of actually performing espionage.
Restrictive rules are also probably more effective than posters at getting across the idea that you DO NOT bring your work home with you or talk about it outside the building. Rules are sometimes used to send messages and encourage mindsets rather than directly prevent problems.
Or maybe the author understands abstraction layers but also understands Redmond's knack for ignoring them or getting them wrong ;-)
Just because it's dumb doesn't mean it won't be done.
GCC/DJGPP has been running on Win32 for a long time. It is probably easier to port *nix IDEs using GCC/DJGPP, since GCC syntax quirks will not need to be exchanged for MS VC syntax quirks.
Darwin isn't really a microkernel. The 4.4 BSD OS personality runs in the same address space as the kernel. (It's like one huge kernel module.) I think NeXT ran its 4.3 BSD personality in user space for better stability but worse performance. Apple acquired NeXT, upgrade the personality to 4.4 BSD, and decided to merge the BSD personality into the kernel to increase performance. Fortunately, I believe it's still possible for Apple to move the BSD personality back into user space and switch out Mach for a more modern microkernel without the user-space apps knowing the difference. (Does Apple publish the API for accessing the Mach system calls directly?)
I think Mach itself is about as big as a slimmed down Linux kernel. There is plenty of documentation out there describing how Mach was revolutionary in its day, but suffers from kernel bloat and is based on early microkernel ideas. There are much smaller and responsive microkernels out there. Many of the biases against microkernels are due to experience with Mach and other early microkernels.
Don't get me wrong. I like microkernels and think Darwin is a step in the right direction. I ran L4Linux (basically User Mode Linux on top of an L4 micro-/nano-kernel) for a little while, but the Linux 2.2 port to L4 user-space wasn't very stable back then. L4Linux was my only process that didn't depend on L4Linux, so when L4Linux died, all of my other processes hung. Linux with the stability of Win95!
I liked QNX and BeOS. They're both "fun" operating systems on top of microkernels. BeOS was single-user and had many file system anoyances (web browser shortcuts are 0 byte files with the URI in metadata, so that a tar ball of your shortcuts isn't sufficient to restore them after a complete OS reinstall... I learned that the hard way), but it was rather friendly and "slick" in its own way. There was lots of software and a friendly OSS/freeware community. My network driver had stability issues and about once a day or every other day I'd get a message like "your nextwork driver just shat all over everything and had to be killed. Would you like to start it again?" Open sockets would all close, but because it was a microkernel with drivers in their own address spaces, the driver would crap all over itself but not take the kernel or any other driver down.
I had a currupted UDF CD-RW that would crash both Win2k and Linux 2.4. It was so anoying to have to reboot every time I failed to recover data off of that CD.
It would be great if we started seeing OSes with each driver in its own process. Experimental or low quality drivers wouldn't be so much of a pain. The L4 hazelnut kernel has fast context switches and the fastest inter-process communication of any x86 kernel (well, any kernel known to its developers), at least it did a few years ago. This means that the price paid for putting drivers in their own process is pretty low.
I've seen a sourceforge project that is developing a kernel module to export a fexible and generic driver interface to userspace. Linux has fairly fast context switches because in the early days it didn't have good threading support, so the devlopers tweaked the hell out of context switches so that context switches on Linux could almost compete with thread switches on other OSes. Linux 2.6 is much more modular than 2.4 and seems that user-space drivers are the next logical step. Well, I can dream at least.
Like I said... read Ken Thompson's paper. I didn't say you can't generate efficient native code from a stack-based representation... I just said that other representations allow the process to run faster. Basically, a stack-based VM is a two-register VM (top two items on the stack). Stack-based representations do imply a finite register file (either zero or two GP registers, depending on your point of view). A memory-based representation assumes a register file that spans your entire address space. If you want to generate code optimized for more registers than are represented in your byte code, you end up taking the byte code and working backwards to the AST/ASD, using the AST/ASD to generate RTL, and register folding the RTL down to the number of registers you actually have. See OpenJIT for an example of generating ASTs from Java bytecode.
If, on the other hand you use a VM with more registers than your hardware (such as a memory machine), you can treat the VM bytecode as RTL and register fold it down to the number of registers you actually have, allowing you to skip the first two steps.
Now, there are other JIT techniques that are faster, but result in less efficient register allocation and therefore less efficient native code. On register-starved architectures like ia32, the difference in register allocation may not be very noticable.
For most applications, it makes sense to trade larger code size for more speed. If you're running your VM in an embedded environment, that's a different story. At the moment, it seems that speed is more of a problem for Java adoption than code size is.
On the other hand, I have played with the idea of VM with two instruction sets... a stack-based instruction set that gets compiled to native code when the object code is downloaded/installed (taking the time to optimize the heck out of the code) and a memory-based instruction set that gets JIT compiled.
The JVM and .NET CLR both enforce a strongly typed object model at the lowest levels. As much as Microsoft would like you to think otherwise, the .NET CLR leverages heavily on Microsoft's experience writing a JVM. Both virtual machines can trace their lineage to Sun's Oak project, designed to express the symantics of only a strongly statically typed language and be interpretable on 8-bit microcontrollers in toasters and fridges. Stack based virtual machines are simple to implement and are nearly ideal for interpreters (see Xavier LeRoy's design paper for Zinc, the Ocaml VM) but very much not ideal for just-in-time compilation (see Ken Tompson's design paper on Dis, the Inferno OS VM). There's simply a lot of work that has to be done in order to get the abstract syntax tree back out of the stack-based byte code.
Essentially, your stack-based bytecode is optimized for a two-register machine (the top two values on the stack). If you're close to having only two spare registers after the VM claims a couple for overhead, then directly JIT compiling stack based VM code doesn't create code that's that bad. In this sense, stack-based JIT VMs aren't so bad on register-starved architectures like x86. However, on architectures like x86-64, PowerPC, Itanium, and Sparc, and MIPS, you really want to work backwards from the bytecode to the AST and then generate RTL and finally do register folding on the RTL so that it will run on the number of registers you really have.
On the other hand, Parrot bytecode with its 3 sets of 16 registers can probably be directly translated to RTL and generate very good code on most architectures. (Itanium has many more than 32 GP and 16 FP registers, so it will take a lot of work to get Parrot to take full advantage of Itanium. Register folding even on x86 should take much much less time than AST and RTL generation from stack-based bytecode.)
Finally, the Dis virtual machine has more or less 4 billion registers (it's a memory-based virtual machine). If a partucular routine for Dis takes more registers than physically available, then your JIT compiler will need to perform register folding, but for most machines with fewer than 4 billion physical registers, Dis should generate good native code very quickly and easily.
Something like Parrot or Dis would make a much better target for a C++ compiler because of the less restrictive object models. If you wanted pointer safety or a more strict object model, that could be enforced more flexibly in the (replaceable) class loader than in the VM's low-level functionality.
There's also the point that the JVM provides no opcodes for pointer arithmetic and no way to cast between pointers (references) and integers. Using a class loader that allows integer opcodes when a reference is on top of the stack will break on VM implementations that use a seperate reference stack to improve garbage collection. You could have all of your objects live in an array of ints and emulate pointer arithmetic with index changes and bit shifts, but that makes using standard Java libraries with your objects much more difficult and slower.
Does it crash under VMWare or does VMWare crash? Your heading makes it sound like a CoLinux bug, but your text makes it sound like a VMWare bug. My guess is that it's a VMWare bug.