#emc-devel | Logs for 2007-04-16

[01:22:29] <jmkasunich> cradek: you around?
[01:23:53] <jmkasunich> http://pastebin.ca/442151
[01:24:07] <jmkasunich> thats the header for some user space PCI handling code I'm writing
[01:24:23] <jmkasunich> (an offshoot from the 5i20 work)
[01:24:38] <jmkasunich> its not done yet, but close - I'm wondering where in the EMC tree it should go
[01:37:56] <cradek> good question
[01:38:40] <cradek> it's not src/emc, and it's not really src/hal either
[01:38:54] <cradek> will it used by hal? or something else?
[01:39:23] <jmkasunich> it will be used by the user space program that loads the FPGA bitfile into the FPGA
[01:39:57] <cradek> where is the rest of that?
[01:39:57] <jmkasunich> and by any program that we used to twiddle with the FPGAs "config ram"
[01:39:57] <jmkasunich> (the ram block that tells the HAL driver what to export)
[01:40:14] <cradek> ok I see that's hal/utils
[01:40:18] <jmkasunich> today, the loader program is in src/hal/utils, but to be honest I don't like that
[01:40:38] <jmkasunich> I think it should be associated with the 5i20 drivers and/or firmware files
[01:40:45] <jmkasunich> (the loader, not the PCI lib)
[01:41:04] <cradek> I don't think I have any useful input for you
[01:41:14] <jmkasunich> well darn
[01:41:43] <cradek> other than: make a new directory if you think that's appropriate
[01:42:01] <jmkasunich> we really don't have any kind of general purpose libs directory
[01:42:10] <jmkasunich> libnml is as close as we get
[01:42:20] <jmkasunich> and it has a lot of non-nml stuff in it, like posemath
[01:42:31] <jmkasunich> probably for the same reason
[01:43:53] <cradek> darn, ran out of daylight, have to go finish some outside stuff
[01:43:54] <cradek> bbl
[01:43:59] <jmkasunich> ok
[01:49:21] <jmkasunich> what about emc2/src/lib, for sources of libs that are neither hal, rtapi, nml, nor emc specific
[01:49:49] <jmkasunich> hmm... IIRC jepler copied a few things into our tree, like the togl source, etc
[01:51:04] <jmkasunich> togl is in src/emc/usr_intf/axis/extensions....
[01:51:17] <jmkasunich> thats not a precedent I want to follow ;-)
[01:53:12] <jmkasunich> our copy of bwidget is in lib/python, not relevant for a C thing
[01:55:36] <cradek> I don't like /lib because it has both source and generated/target files
[01:55:45] <cradek> requiring heavy use of .cvsignore
[01:56:03] <jmkasunich> src/lib
[01:56:34] <cradek> will this actually be built into a library?
[01:56:42] <jmkasunich> waffle
[01:56:49] <jmkasunich> probably not, I'm lazy
[01:57:22] <jmkasunich> just linked with whatever programs require it
[01:57:33] <cradek> maybe you should back up and think of where you want things like m5i20cfg to go, and consider this only a (generic) part of it
[01:58:07] <cradek> assuming 'setup' was a good name for that kind of program, you could have setup/m5i20, setup/common
[01:58:50] <jmkasunich> well, if I'm gonna do that, I'd leave it in hal/utils
[01:59:26] <jmkasunich> the new 5i20 driver is gonna be in src/hal/drivers/mesa5i20/foo.c
[01:59:51] <cradek> will this loader be called by hal when the hal driver is loaded?
[02:00:10] <jmkasunich> the 5i20 firmware files (VHDL source and bitfiles, at the moment) are in src/hal/drivers/mesa5i20/firmware/*
[02:00:28] <jmkasunich> it will be a separete loadusr line in the hal file
[02:00:38] <cradek> ok
[02:00:43] <jmkasunich> loadusr 5i20_loader <thebitfile>
[02:00:48] <cradek> src/hal/appropriate/whatever seems fine to me then
[02:00:49] <jmkasunich> loadrt <thedriver>
[02:02:00] <jmkasunich> I'll probaby stick all the source for the loader in src/hal/drivers/mesa5i20
[02:02:16] <cradek> ok
[02:02:33] <jmkasunich> if somebody someday wants to use the upci stuff elsewhere, they'll have fun...
[02:02:51] <cradek> it'd be easy
[02:03:10] <jmkasunich> even if they are in say src/emc/something?
[02:03:20] <cradek> with nonrecursive make, the directories are only there for the programmer's benefit
[02:03:35] <cradek> cross-directory dependencies are just as easy as any others
[02:03:38] <jmkasunich> oh
[02:03:52] <cradek> it's only odd/confusing for the programmer
[02:04:04] <jmkasunich> hey, I resemble that remark
[02:04:15] <cradek> heh
[02:04:43] <cradek> I sure like this week between snow and mosquitos
[02:04:49] <jmkasunich> the other bit-o-fun is that the loader (and any other util that messes with fpga config) needs to be setuid
[02:05:01] <jmkasunich> between?
[02:05:12] <jmkasunich> we had more snow yesterday/today
[02:05:21] <cradek> it was amazing here
[02:05:30] <jmkasunich> only about an inch on the ground overnight, and it melted today
[02:05:32] <cradek> maybe for you it'll be next week
[02:05:37] <jmkasunich> I hope so
[02:06:21] <cradek> got out my chevy and fixed it up a bit
[02:06:30] <jmkasunich> the old one?
[02:06:32] <cradek> the accelerator pump was sticking (holding the gas pedal down)
[02:06:33] <cradek> yeah
[02:06:47] <jmkasunich> gonna drive it to the workshop?
[02:06:51] <cradek> so I took it out, stretched the spring to about twice its original length, and put it back together
[02:07:11] <cradek> it'll need a new one in a few years I'm sure
[02:07:14] <jmkasunich> hey, if it sticks force it...
[02:07:19] <cradek> yep
[02:07:40] <cradek> it's leather (I think) and it's old - they probably only ever lasted a few years
[02:08:30] <cradek> might be a rubber equivalent that would fit, hard to say
[02:08:57] <cradek> the whole rebuild kit has maybe 8 parts - can easily put it in in an hour
[02:09:22] <jmkasunich> ah, the simpler days...
[02:09:47] <cradek> the other day some guy was interested in it - I'd sure drive it to fest to sell it
[02:10:01] <jmkasunich> I saw that
[02:10:27] <cradek> I don't need it, and probably won't fix it up - just will preserve it - so if someone else wants to fix it up, they can have it
[02:10:47] <jmkasunich> nobody "needs" an antique car
[02:10:57] <cradek> it's nothing special except it's a nice survivor
[02:13:44] <cradek> http://www.trademe.co.nz/Trade-Me-Motors/Specialist-cars/Hot-rods/photos/a-95122680/p-36747485.htm
[02:13:49] <cradek> this is the car
[02:14:01] <jmkasunich> the exact car, or the make and model?
[02:14:08] <cradek> except mine has nice original bias-ply wide whitewalls
[02:14:14] <cradek> yes I think so
[02:14:27] <cradek> on the original wheels even
[02:14:32] <jmkasunich> you think so?
[02:14:50] <jmkasunich> when I say exact car, I mean, is that your car for sale in that listing, or just one like it?
[02:14:52] <cradek> the tires are new, but made with the original molds that are still around
[02:15:01] <cradek> no this is someone else's car
[02:15:09] <cradek> mine's the same model, but more original
[02:37:36] <jmkasunich> what are the general rules when writing a setuid program?
[02:38:36] <cradek> be careful, don't write to a file if you don't absolutely need to, drop privs when you don't need them
[02:38:59] <jmkasunich> that 2nd one surprised me
[02:39:05] <jmkasunich> but I guess it makes sense
[02:39:09] <jmkasunich> my problem:
[02:39:29] <jmkasunich> gotta be setuid to read the ram content that says "heres what this FPGA is capable of"
[02:39:52] <jmkasunich> then interact with the user for a while to let him say "this is the subset of those capabilities I want"
[02:40:04] <jmkasunich> then gotta be setuid again to write it back to the fpga
[02:40:15] <cradek> what do you mean by interact?
[02:40:32] <jmkasunich> the first time - actual interaction, prompts, menus, etc
[02:40:43] <jmkasunich> subsequent times would use saved info
[02:40:54] <cradek> sounds like you want two programs
[02:41:13] <jmkasunich> yeah, I was thinking of a simple one that would read the fpga, write it to a file, exit
[02:41:21] <cradek> setuid-backend --what-can-it-do
[02:41:24] <jmkasunich> then the big one reads the file, interacts, writes a file
[02:41:30] <cradek> setuid-backend --he-wants=this
[02:41:33] <jmkasunich> and the little one reads the file, writes to the fpga
[02:42:19] <jmkasunich> --what-it-can-dd and --he-wants-this are 1Kbytes each
[02:42:31] <jmkasunich> s/dd/do
[02:42:45] <jmkasunich> oh, 1K and binary ;-)
[02:42:45] <cradek> so stdout/commandline is inconvenient
[02:43:03] <jmkasunich> yeah, a little
[02:43:18] <jmkasunich> besides, the code to interpret the binary should be part of the bigger interaction program
[02:43:27] <jmkasunich> so when you add a new function, you change that only, not the setuid part
[02:45:23] <jmkasunich> the reason for avoiding writing a file is that an attack might trick it into overwriting an important file?
[02:45:31] <cradek> yes
[02:45:40] <cradek> temp file handling is especially dangerous
[02:45:53] <jmkasunich> what if I get privilges, read the fpga ram into a 1K buffer, then drop priv and write the buffer to a file?
[02:46:08] <cradek> yes that's what you want to do
[02:47:27] <jmkasunich> this program opens /dev/mem for writing... I bet there are possible attacks thru that as well
[02:48:02] <cradek> I don't know if that's particularly bad
[02:48:03] <jmkasunich> although the region of /dev/mem that it maps is supposed to be only the FPGA, and is determined by reading /proc/bus/pci
[02:48:14] <cradek> I'm not a security programmer, but I read bugtraq...
[02:48:36] <cradek> proc and dev are probably among the safest things to read/write
[02:48:51] <cradek> it's /tmp and . you really have to worry about
[02:49:26] <jmkasunich> well, a write to /dev/mem writes directly to physical memory... use the wrong address and you don't get a segfault, you write into some other process (or the kernel)
[02:49:41] <jmkasunich> I guess the key is to not use the wrong address
[02:49:48] <cradek> that's the "be careful" advice I guess
[02:50:09] <cradek> also, don't trust anything the user gives you
[02:50:16] <cradek> (another important one)
[02:50:32] <jmkasunich> yeah, my open region routine mmaps only the part of /dev/mem that /proc/bus/pci says belongs to my device
[02:50:48] <jmkasunich> and my write routine makes sure the address is within the range that belongs to the device
[02:51:12] <jmkasunich> I will be writing data that the user gives me, but I control where it goes
[02:52:38] <cradek> you just have to make sure what he gives you is sane (the right length etc)
[02:52:48] <jmkasunich> right
[02:53:23] <jmkasunich> for write to fpga I'll do the same thing - file -> buffer, get priv, buffer -> FPGA, drop priv
[02:53:29] <jmkasunich> the buffer will only be 1K
[02:53:59] <cradek> yes sounds simple enough
[03:12:59] <jmkasunich> /* drop root privs temporarily */
[03:13:00] <jmkasunich> seteuid(getuid());
[03:13:05] <jmkasunich> that snipped is from module_helper
[03:13:17] <jmkasunich> /* reinstate root privs */
[03:13:17] <jmkasunich> seteuid(0);
[03:13:19] <jmkasunich> as is that one
[03:13:49] <jmkasunich> if the user is not root (or the program is not setuid), the 2nd one will fail
[03:13:55] <jmkasunich> but the first one won't, will it?
[03:19:16] <cradek> there's a check earlier to make sure it's setuid
[03:19:54] <jmkasunich> so you don't have to worry about it failing...
[03:20:40] <jmkasunich> I was confused, the drop privs code will never run unless the get privs code already did, at least in this library
[03:20:49] <jmkasunich> in the main program I'll run the drop privs right away
[03:21:02] <jmkasunich> (and I'll test for being root right away)
[03:21:19] <jmkasunich> parts of the lib can be used by non-root, and I didn't want to prevent that
[03:21:41] <jmkasunich> * jmkasunich rambles... but the gist of it is - I figgered it out ;-)
[03:25:10] <cradek> heh, sorry I was away
[03:26:22] <jmkasunich> I'm doing "reference counting", when callers open regions and then close them, so when the close the last io region, I do iopl(0), and when they close the last mem region I do close(/dev/mem), and when both are close, I drop root privs
[03:28:40] <cradek> you may be able to drop privs right after opening - not sure
[03:29:04] <jmkasunich> you mean mmap doesn't need privs? or read/write?
[03:29:22] <jmkasunich> I suppose I should test
[03:29:38] <cradek> mmap probably does
[03:29:43] <cradek> I guess I don't know how it works
[03:29:46] <jmkasunich> if I can get privs, do iopl(3), drop privs, and still be able to do outb, inb, that would be simpler
[03:30:29] <jmkasunich> ditto if I can get privs, do mmap(), drop privs, and still access the mapped memory
[03:30:44] <cradek> I suspect you can do both of those
[03:30:50] <jmkasunich> I guess I'll code it the easy way and try it
[03:40:26] <jmkasunich> heh, I just realised one of the sneaky ways to attack a setuid program
[03:40:54] <jmkasunich> its not good to get privliges, try something, if it fails print an error message and _then_ drop privs
[03:41:15] <jmkasunich> an attacker could do "myprog input-that-will-cause-an-error >importantfile"
[03:41:43] <cradek> no, > is in the user's shell, the setuid doesn't affect it
[03:41:48] <jmkasunich> oh
[03:41:57] <jmkasunich> well, thats good
[03:42:08] <cradek> myprog --log-errors-to=/root/.rhosts
[03:42:38] <jmkasunich> thats bad
[03:43:23] <jmkasunich> dropping privs should never fail, right?
[03:43:43] <jmkasunich> so I can do it before printing the error message (just on general principles) and it won't mung errno
[03:44:34] <cradek> I don't know...
[03:45:01] <jmkasunich> the man page says the only error is EPERM
[04:21:08] <jmkasunich> I have uids spinning around in my head
[04:45:43] <jmkasunich> * jmkasunich cops out - first make it work, then make it secure...
[05:37:22] <jmkasunich> it works1
[05:37:26] <jmkasunich> it works!
[05:37:29] <jmkasunich> time for sleep
[17:49:37] <SWPadnos_> SWPadnos_ is now known as SWPadnos