The security hole in sudo
nakedsecurity.sophos.com
nakedsecurity.sophos.com
switch(something)
{
case 1:
// Do stuff
goto case 4;
case 2:
// Do stuff
goto case 1;
case 3:
// Do stuff
goto case 5;
case 4:
// Do stuff
goto case 3;
case 5:
// Do stuff
break;
}C# already implies no implicit fallthrough, so there's no need to explicitly state that you're not falling through. A better solution (for every language, really) would be a "fallthrough;" statement or "goto case x;", which C# does get right.
To a sibling comment: C# does permit fallthrough, just with ugly syntax. You can "goto case 2". http://stackoverflow.com/questions/174155/switch-statement-f...
switch (v) {
case FOO_A:
case FOO_B:
do some_foo();
break; // if you really want :P
case BAR_X:
case BAR_Y:
do_some_bar();
}
Here you have two implicit fallthroughs used for cleaner code.Another use is to express one case as a subset or superset of another case:
switch (v) {
case FOO_BAR:
do_some_foo();
case BAR:
do_some_bar();
/*...*/
}
IIRC, there was some C-like programming language out there (C# probably?) which only provided default fallthrough if there was no code between the cases, as in the above example.We do car diagnostics and we code in C. Endless time I would not understand why a particular path was not taken, and a missing break was the answer.
Now, I can see the utility of fall-thru switch construct, but this is a kind of bug that could be avoided at the syntax level. Just don't require a break and develop another syntax for fall-thru cases.
What exactly do you do? The reason I ask is because 50 hours a week I'm an Auto Tech. The remaining hours that I'm awake I code. This week my project has been reverse engineering a pc based scanner that I have to learn about how it interacts with OBDII / CAN in an attempt to make a super tool that gives me specific abilities. The people I deal with during day know nothing of computers and the people I deal with at night know nothing of cars.
You are the first person that I have ever heard mention both in the same post.
If there's a university nearby, you might want to go check out their engineering library and see if they have a copy. I don't recall the ISO number off the top of my head. If you're really serious about the project, I think the book only costs around $400 or so.
Some newer and higher-end cars even use proprietary crypto keyed off of the VIN number and a shared secret to protect from access by third-party tools. There's a good-sized cottage industry in breaking proprietary ECU protocols and crypto, because there's a solid niche market in selling mechanics one $20,000 "multiflash" tool to replace their ten $10000 manufacturer-provided "diagnostic systems," especially in the high-end exotic market.
I was able to find enough resource online to build an ISO OBD-II scanner as my seventh-grade final project, without needing to resort to hunting down the standard. Today there are even open-source projects like http://en.wikipedia.org/wiki/OBDuino which can provide a solid code-based understanding of the three old OBD signaling types (PWM, VPW, ISO), as well as the basic protocol.
I hit an idea slump in my normal utility making and decided to put my otherwise wasted time to use.
Thanks Again ~
I don't know what you mean by 'erasing the emission monitor', unless you mean the freeze frame, which usually gets erased when you erase DTCs with the standard 0x14 request.
Anyway I work exactly as you do, by reverse-engineering official tools.
And I'm not very knowledgeable about cars anyway :)
I'm leaving in a week, so it won't be a problem for me anymore...
I'm not a zealot on this stuff, and write switch statements regularly (though I do strongly prefer if chains for most stuff) but if you're really hitting this regularly I think a change in process might be in order.
Most of our code is machine-generated, and our boss doesn't want to touch the generator in general.
One of the many good decisions that went into C# is reversing how it works; in other words making it compulsory to explicitly state when you need control to fall from one case to another.
switch (uint8_t bla){ case 0: stuff; ...
... and filling everything as you go along, first type the skeleton ...
switch () {case: break; default: break;}
... and then fill everything in. It's anal/pedantic but it becomes second nature really fast. Do it for everything (loops, structs, functions,...).
I once lost 2 entire days of my life I kid you not hunting an if (a = b) that had to be a == b and decided to change my approach.
Over time, I've come to believe C is deadly flawed, and greenfield projects should seriously investigate languages that are better designed.
Trivial errors in C like dangling elses, fallthroughs in switches, and easy buffer-overruns by default say to me that C's broken, has been broken, and will continue being broken.
For non-realtime apps, I would recommend pretty much anything but C; for realtime apps, I would be looking into things like SystemC or D and choose appropriately.
This class of avoidable bug should not be happening in 2012.
(For reference, a project I have at hand is compiled with -std=c99 -pedantic -W -Wall -Wno-sign-compare -Wno-unused-parameter -Wbad-function-cast -Wcast-align -Wchar-subscripts -Wfloat-equal -Wmissing-declarations -Wmissing-format-attribute -Wmissing-noreturn -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings -Wundef -Werror and uses lint to check for improper conversion between types.)
If you told C "make me a sandwich", it'd give a warning about not having enough mustard to cover your entire body and an error about not have a large enough bun type to fit you in.
Compiler writers can do whatever the heck they want, and if dumping ALL THE WARNINGS was the priority, you'd need three lines of command line switches to turn off the "noise" warnings. Clearly, the a bunch of people see it as "noise" or don't care about writing clean code. That's more systemic of programmers.
To make it even more fun, there are many use cases for fall through switch statements. My personal favorite is duff's device, which is an unwrapped version of a serial copy that will run faster on certain architectures than a more typical serial copy will run: send(to, from, count) register short to, from; register count; { register n = (count + 7) / 8; switch(count % 8) { case 0: do { to = from++; //this is for a memory mapped register. case 7: to = from++; // use to++ for non memory mapped registers case 6: to = from++; case 5: to = from++; case 4: to = from++; case 3: to = from++; case 2: to = from++; case 1: to = *from++; } while(--n > 0); } }
But, most of the bugs I notice in the static analysis output are not possible in the model of other languages. That's... kind of depressing.
C isn't broken. Gah. Why does everyone have such a hard time understanding that? The language does //exactly what you tell it to do//. If that's overrun a buffer, then that's what you get. If it is fallthrough a switch statement, that's what you get. If it is typecast a block of memory that is too small to hold the structure, then that's what you get. In short, for many programs, that means doing stupid things at some time. For many programs, edge cases aren't considered at all. Blame C? It let me?
For every single one of the "warts" of C, there is also a usecase. This is why it will not be "fixed" and why it isn't "flawed". To remove them is to remove a useful function that could otherwise cause more machine code to be needed. THIS IS THE KEY. Minimizing machine code (overhead).
If you aren't good at managing these edge cases, don't need native code, don't need interop with other code, can take a performance hit, or don't want to use automated tools to help you, then don't use C for large programs.
Take it for what it is: a low level, mostly portable, mask over assembly. Stop complaining about C, start complaining about programmers.
But this switch/case/break statement behavior exists in lots of languages. I almost expect it. (It doesn't in Ruby and I usually have to stop and think about it when geeking out in that language.)
Most C code isn't that critical. Say, about 97% of the time.
Plan 9 doesn't have the concept of superuser. "sudo" is moot. Plan 9 is written in C.
Just two examples that come to mind.
Maybe it's not the language. Maybe it's the person using it.
There is never going to be a perfectly "idiot-proof" language that shares the power of a language like C. But many still seem to believe this is possible.
As someone who supports ordinary programmers, expecting smarts is not the right track. expecting average and mistakes is the right track. If your foundation is not robust by default, your systems will not be robust by default either.
To mix metaphors: Better to design foundations that keep the gloves on by default, then when you need to, take them off. You can see that design philosophy in Mercurial.
Suppose - for argument's sake - that C had two different pointer types: checked pointers for arrays and unchecked pointers for arbitrary memory and that conversions between the two were relatively seamless. What difference would that make, 97% of the time?
Plan 9 settled the issue.
But sometimes I think some people have come to love the mental challenge of UNIX permissions. It is like a game to them. I made a function that produces all possible permissions for a file, including the nonsensical ones, so I could display permissions as octal instead of the usual ls format. Have you ever thought about how many possibilities there are? Too many.
The setuid concept is interesting and must have seemed quite innovative at the time. Doesn't surprise me they filed a patent for it. But today, I could just as well do without the complexity.
For example having to type the root password every time I want to run a vaguely administrative program or install something etc gets old fast.
Not to mention the number of times I've made a bunch of edits to something like a conf file in nano and then gone to save and got "permission denied" where the only solution seems to be to exit nano and run it again (and do the edits again) with sudo. Surely it should be able to prompt me for the password at save time?
As for your last point, you're complaining about nano. It would be perfectly possible for an editor to sudo when writing to disk.
I think there's a sense, which I generally agree with, that random applications asking for your password is something we don't want users to get used to.
"/etc/mail/aliases" [Read only] 36 lines, 1023 characters
Its simply a matter of remaining keen when doing admin tasks. Sure I have to close/re-open with sudo but its prompting me up front that I won't be able to save it. :w !sudo tee % > /dev/null
It's a bit of a hack, but it works.No, you don't, and yes, you will:
:w !sudo tee %If you try creating a new user through the control panel, you'll notice that the default selection is to create a standard user.
Rather what I said. A borked version of sudo.
-Save your modified file to a temp file and work it out with cp or mv after.
or
-Use Vim, and the infamous ":w !sudo tee %".
Nano asks you for the file name/location when you save, just save the file somewhere you have write access to then move it with sudo afterwards. No need to retype your edits.
sudoedit handles this exact case. Try it, it's very convenient. (Of course, you have to set at least one of SUDO_EDITOR, VISUAL or EDITOR correctly.)
You also want to know about visudo, which will save you some oh-shit-I-locked-myself-out moments.
sudo -i
# do root work
exit # or ^D switch(something)
{
case 1:
// Do stuff
break;
case 2:
#pragma switch_fallthrough
case 3:
// Do stuff
break;
#pragma switch_nodefault
}I recommend using:
- vagrant http://vagrantup.com/
- toft https://github.com/exceedhl/toft/
- cucumber http://cukes.info/
- aruba https://github.com/cucumber/aruba
to write/reverse engineer examples/user stories.
Enough with the nonsense. TDD is great for some tools, in some situations. It's not a "solve all". And now comes "ATDD", people should start working instead on inventing acronyms.
vagrant? really, REALLY?
Try QEMU. Try chroot
News flash, sudo is not a RoR application. Especially sudo with all the magic that goes behind executing a process as another user.
Your last sentence kills your standpoint totally.
Please check out the mentioned "toft". It's lxc inside vagrant and designed to test complex infrastructure code from the outside in. Nothing web related.