My proposal -- discussed with Maksim at length -- would *derive the
user-ID from the ownership of the link*. The sample set up would then be
as follows. Suppose, user named wallaby has a device with BD_ADDR
01:02:03:04:05:06. The user would create a subdirectory for their
bluetooth files (or use something existing, like ~/Desktop/):
wallaby@tasmania (11) mkdir ~/bluetooth
root will then -- on wallaby's request -- tell obexapp about it:
root@tasmania (111) ln -s ~wallaby/bluetooth
/var/spool/obex/01:02:03:04:05:06
root@tasmania (112) chown -h wallaby ~wallaby/bluetooth
/var/spool/obex/01:02:03:04:05:06
The second of the above root's lines is what will -- under my proposal
-- tell obexapp-daemon, who shall own any files uploaded by the device.
If started as root, instead of becoming 'obex', obexapp will become
'wallaby'...
Upon accepting a connection, the server will do the same lookups as
Maksim's version is doing, cd/chroot into the subdirectory, and setuid
to the proper UID (such as wallaby's in this example).
The attached patch can be dropped into /usr/ports/comms/obexapp/files/ .
The only functionality still missing from it compared to Maksim's is the
bt_gethostbyaddr(3) lookup -- only the numeric BD_ADDR is currently
considered. This is not a significant difference between proposals,
though...
My proposal has other, not so significant differences -- it allows the
BD_ADDR-entries in /var/spool/obex to be non-directories (files, broken
links a'la /etc/make.conf, even sockets). Even if a chdir into such an
entry fails, the ID of the entry's owner will still be used to
determine, which user shall own any uploaded files, etc. even though all
such files will end up in the same directory (as they do with the
current version of obexapp).
Maksim thought, offering such flexibility would be too confusing...
I agree, that chroot-ing (rather than merely chdir-ing) into such a
"virtual root" directory makes sense. The only material difference
between our proposals is my deriving the desired UID from the ownership
of the found BD_ADDR entry vs. Maksim's always using the user specified
on command-line (such as 'obex').
Yours,
-mi
permissions on files will be set to 0660.
> necessitates creation of a new UID without the security benefit of
> having the daemon run under that UID permanently (but only switching
> after accepting each connection)...
i beg to differ. main process (the one that accepts connection) is
running with elevated privileges, yes. however, the process that
handles the actual connection from the client is running with reduced
privileges. so, there is a security benefit. also, obexapp will chroot
into virtual root.
> My proposal -- discussed with Maksim at length -- would *derive the
> user-ID from the ownership of the link*. The sample set up would then be
> as follows. Suppose, user named wallaby has a device with BD_ADDR
> 01:02:03:04:05:06. The user would create a subdirectory for their
> bluetooth files (or use something existing, like ~/Desktop/):
as i tried to explain, there are few problems (imo) with your patch.
one example: what happens when remote client decides to create a
directory which matches another client's bd_addr or name? i also do
not like the fact that client are allowed to "escape" from their
virtual root directory. another thing is that you pretty much force
new behavior and not giving any control to disable it. what is worse,
new behavior is controlled by file system elements which remote
clients can potentially see, create and/or modify.
[...]
> My proposal has other, not so significant differences -- it allows the
> BD_ADDR-entries in /var/spool/obex to be non-directories (files, broken
> links a'la /etc/make.conf, even sockets). Even if a chdir into such an
> entry fails, the ID of the entry's owner will still be used to
> determine, which user shall own any uploaded files, etc. even though all
> such files will end up in the same directory (as they do with the
> current version of obexapp).
>
> Maksim thought, offering such flexibility would be too confusing...
please explain what does it buy you exactly? so, great, you can
control file ownership in the _same_ directory. like i said, unless
you set sticky bit on the directory (which is evil, imo) and make it
0777 there is still a problem with sharing files (either obexapp
running under new id won't be able to write to the root directory or
everybody will be able to delete each others files). either way, its
not that different from what obexapp does right now.
> I agree, that chroot-ing (rather than merely chdir-ing) into such a
> "virtual root" directory makes sense. The only material difference
> between our proposals is my deriving the desired UID from the ownership
> of the found BD_ADDR entry vs. Maksim's always using the user specified
> on command-line (such as 'obex').
i'm actually not feeling very strongly about this. my initial choice
is to be on a safe side. basically, what i'm trying to guard against
is when someone put a symlink owned by root into the obexapp root
folder. this is very easy thing to do, imo. i personally did it :)
basically this type of misconfiguration will make obexapp continue to
run with elevated privileges while servicing clients requests and that
is a 'bad thing (tm)' :)
i also must say that we are trying to solve the problem at the wrong
level. more specifically, for phone book back up you probably want to
use something else (like sync-ml for example) not not obexapp.
bluetooth obex profiles are just completely oblivious to the fact that
clients might need to supply credentials. its all strictly personal.
so what i did, it basically provided mechanism to extend it in a
similar manner.
thanks,
max
In any case, being owned by the actual user seems far more
straightforward...
>> necessitates creation of a new UID without the security benefit of
>> having the daemon run under that UID permanently (but only switching
>> after accepting each connection)...
>>
> i beg to differ. main process (the one that accepts connection) is
> running with elevated privileges, yes.
>From the security standpoint, this negates all/most benefits of having a
dedicated UID for the service. The security people will tell you, that,
as long as the root-owned process is always running and listening to
connections, it can some day be fooled and so they don't like it anyway.
> however, the process that
> handles the actual connection from the client is running with reduced
> privileges. so, there is a security benefit.
It will drop the root-privileges under my proposal as well. It is just
that the new UID will be that of the connecting user as determined by
the BD_ADDR match, if such a match can be found. Otherwise, yes, it
should become whatever user is specified with the -u switch.
> also, obexapp will chroot
> into virtual root.
>
Yes, I agree, this is advantageous.
> i'm actually not feeling very strongly about this. my initial choice
> is to be on a safe side. basically, what i'm trying to guard against
> is when someone put a symlink owned by root into the obexapp root
> folder. this is very easy thing to do, imo. i personally did it :)
>
The only thing I do feel strongly about, is that, when a matching
directory entry is found, the server shall perform a setuid not to the
generic 'obex' user, but to the owner of that entry (and chroot into it,
yes).
I do not think, you should give special meaning to entry named "default"
-- because that would require special handling of the case, when
somebody's BD_ADDR resolves to name "default". I'd say, it is Ok, if no
match for the device is found, to remain in the top-level directory
(after dropping the root-privileges). But, again, no strong feeling
about this.
My other ideas (such as the matching entries not necessarily being
subdirectories) came from trying to maintain compatibility with the
current operations (where everything lives in the same directory), while
still allowing the created files to belong to different, cooperating users.
> basically this type of misconfiguration will make obexapp continue to
> run with elevated privileges while servicing clients requests and that
> is a 'bad thing (tm)' :)
>
I agree, that continuing to run as root after accepting connection is
bad -- if a matching entry is not found, the server, indeed, ought to
setuid to some non-root user (as set by the -u switch or determined from
the ownership of the top-level itself). However, the above-mentioned
cooperation may still have its uses for some people. That said, they can
have all their BD_ADDR symlinks point to the same directory and
cooperate there, so I don't feel strongly about it either.
> i also must say that we are trying to solve the problem at the wrong
> level. more specifically, for phone book back up you probably want to
> use something else (like sync-ml for example) not not obexapp.
>
Not sure, what "sync-ml" is (there is no such port). But what about
dropping camera's pictures and videos? People would certainly expect to
be able to do that straight from their devices (rather than by running a
client of some sort), and find the files somewhere under their home
directories (perhaps in ~/Desktop).
So, I agree with most of your change, except the UID part -- in case a
subdirectory-entry with a matching name is found, the argument of the
setuid() (and setgid()) call should be the UID (and GID) of the entry
(as determined by lstat(2), not stat(2), though).
Yours,
-mi
> > i beg to differ. main process (the one that accepts connection) is
> > running with elevated privileges, yes.
> >From the security standpoint, this negates all/most benefits of having a
> dedicated UID for the service. The security people will tell you, that,
I agree too, its not good to run a daemon (that can be accessed over a
radio link and create/modify files no less) as root.
> I agree, that continuing to run as root after accepting connection is
> bad -- if a matching entry is not found, the server, indeed, ought to
> setuid to some non-root user (as set by the -u switch or determined from
> the ownership of the top-level itself). However, the above-mentioned
> cooperation may still have its uses for some people. That said, they can
> have all their BD_ADDR symlinks point to the same directory and
> cooperate there, so I don't feel strongly about it either.
If you did that, it would I think be better to have the bdaddr mapping in
a config file. Symlinks are too much trouble. On the other hand, I'm not
keen on config files either :)
Also, it could be better in that case to have a master daemon (along the
lines of inetd) that could accept connectins and start obex according to
the remote device address. Thats perhaps a lot of work though.
> > i also must say that we are trying to solve the problem at the wrong
> > level. more specifically, for phone book back up you probably want to
> > use something else (like sync-ml for example) not not obexapp.
> >
> Not sure, what "sync-ml" is (there is no such port).
Try "msynctool" which uses libopensync, it has a pluggable API for
different sync protocols (syncml is Nokia, synce is Windows) and is run
from the computer end so you wouldn't have any issues with incoming files.
> But what about dropping camera's pictures and videos? People would
> certainly expect to be able to do that straight from their devices
> (rather than by running a client of some sort), and find the files
> somewhere under their home directories (perhaps in ~/Desktop).
Do you want to send pictures to your account when your wife is logged in,
or does she want to when you are logged in? I don't know what prior art
is there, but it seems to me that (as I said before) the person logged in
at the console owns the machine and should receive files being sent. As
Max said, Bluetooth is not big on credentials, it is assumed that all
users (normally a only one) have equal access.
For this reason, Bluetooth cannot properly be a multi-user link unless all
the users trust each other (while Alice is sending files to the computer,
Bill could be checking her phone log) so I don't see a problem with having
all the files in a master directory owned by the same user (but setting
the default path per remote device seems a good compromise)
regards,
iain
perhaps you should take a closer look at the patch i posted? :-) in server.c
@@ -565,6 +668,15 @@
}
}
+ if (chmod(context->temp, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) < 0) {
+ log_err("%s(): Could not chmod(%s). %s (%d)",
+ __func__, context->temp,
+ strerror(errno), errno);
+
+ codes = obexapp_util_errno2response(errno);
+ goto done;
+ }
+
> because all of the bluetooth users would have to be listed in obex'
> group and so there can be no more than 20 of them (I think, that's the
> limit on a group size).
not really, as i said in my original email user's private obex
directory is owned by 'obex' user, but the group is still set to the
user's group and permissions are set to 0770.
> In any case, being owned by the actual user seems far more
> straightforward...
its all about security vs. usability to me :) please read below.
>>> necessitates creation of a new UID without the security benefit of
>>> having the daemon run under that UID permanently (but only switching
>>> after accepting each connection)...
>>>
>> i beg to differ. main process (the one that accepts connection) is
>> running with elevated privileges, yes.
>
> From the security standpoint, this negates all/most benefits of having a
> dedicated UID for the service. The security people will tell you, that,
> as long as the root-owned process is always running and listening to
> connections, it can some day be fooled and so they don't like it anyway.
i'm having a hard time follow this part of the argument. both patches
(yours and mine) will accept connection with elevated privileges.
there is absolutely no difference here. so, i'm going to dismiss this
part of the argument, sorry :)
>> however, the process that
>> handles the actual connection from the client is running with reduced
>> privileges. so, there is a security benefit.
>
> It will drop the root-privileges under my proposal as well. It is just
> that the new UID will be that of the connecting user as determined by
> the BD_ADDR match, if such a match can be found. Otherwise, yes, it
> should become whatever user is specified with the -u switch.
if you are arguing that having separate 'obex' user provides no
security benefits, then i disagree. and here is why.
to me security is about managing the risks. i have to assume that
someone will break into someone's system using obexapp as attack
vector. so, lets see what happens in this case
(1) when obexapp is running as separate user 'obex' in chroot()ed
environment, the question is: what kind of damage 'obex' user can do
in chroot()ed environment?
(2) when obexapp is running as potentially _any_ user in the system in
_unrestricted_ environment, the question is: what kind of damage _any_
user can do while roaming free?
keep in mind that 'bad guy' can populate his environment with all kind
of files before obtaining shell.
now, please put on your security person's hat and tell me honestly
which option would you choose?
>> i'm actually not feeling very strongly about this. my initial choice
>> is to be on a safe side. basically, what i'm trying to guard against
>> is when someone put a symlink owned by root into the obexapp root
>> folder. this is very easy thing to do, imo. i personally did it :)
>>
> The only thing I do feel strongly about, is that, when a matching
> directory entry is found, the server shall perform a setuid not to the
> generic 'obex' user, but to the owner of that entry (and chroot into it,
> yes).
like i said, its security vs. usability. i probably can live with
chroot()ing and changing uid to owner of the directory (and _not_
symlink).
> I do not think, you should give special meaning to entry named "default"
> -- because that would require special handling of the case, when
> somebody's BD_ADDR resolves to name "default". I'd say, it is Ok, if no
> match for the device is found, to remain in the top-level directory
> (after dropping the root-privileges). But, again, no strong feeling
> about this.
i'm willing to take my chances of this one :) its strictly local
configuration and if someone has, in fact, named his/her bluetooth
gadget 'default' then its too bad :) i'm also not keen of keeping
'default' name. it can be anything, like '00:00:00:00:00:00' or
whatever.
> My other ideas (such as the matching entries not necessarily being
> subdirectories) came from trying to maintain compatibility with the
> current operations (where everything lives in the same directory), while
> still allowing the created files to belong to different, cooperating users.
no, just put new behavior under separate option and keep it disabled
by default.
>> basically this type of misconfiguration will make obexapp continue to
>> run with elevated privileges while servicing clients requests and that
>> is a 'bad thing (tm)' :)
>>
> I agree, that continuing to run as root after accepting connection is
> bad -- if a matching entry is not found, the server, indeed, ought to
> setuid to some non-root user (as set by the -u switch or determined from
> the ownership of the top-level itself). However, the above-mentioned
> cooperation may still have its uses for some people. That said, they can
> have all their BD_ADDR symlinks point to the same directory and
> cooperate there, so I don't feel strongly about it either.
the 'default' virtual root stays. remote clients have no business to
see, know about and/or try to mess with other clients virtual roots.
not sure if you noticed, but 'default' virtual root can be also
considered as another level of access. basically, if there is no
'default' virtual root, clients without virtual root won't be able to
access the server.
broken symlinks is a bad idea, imo. i still do not get what do you
gain by changing ownership on files in the same directory. perhaps i'm
missing something here. please give me an example.
>> i also must say that we are trying to solve the problem at the wrong
>> level. more specifically, for phone book back up you probably want to
>> use something else (like sync-ml for example) not not obexapp.
>>
> Not sure, what "sync-ml" is (there is no such port). But what about
there is something called multisync (or something like that) but it
needs freebsd bluetooth plugin. basically sync-ml is a xml based
protocol that runs over obex and is used for synchronizing objects on
systems.
> dropping camera's pictures and videos? People would certainly expect to
> be able to do that straight from their devices (rather than by running a
> client of some sort), and find the files somewhere under their home
> directories (perhaps in ~/Desktop).
sure and they can do it.
> So, I agree with most of your change, except the UID part -- in case a
> subdirectory-entry with a matching name is found, the argument of the
> setuid() (and setgid()) call should be the UID (and GID) of the entry
> (as determined by lstat(2), not stat(2), though).
like i said, its probably ok to change uid to owner of the _directory_
and chroot() into it. but lstat(2) is out, sorry :)
thanks,
max
its only to call accept() and fork(). child process drops privileges
right after that. in fact, i believe, there is no network i/o
performed while child is running with elevated privileges. so, the
window is small here.
>> I agree, that continuing to run as root after accepting connection is
>> bad -- if a matching entry is not found, the server, indeed, ought to
>> setuid to some non-root user (as set by the -u switch or determined from
>> the ownership of the top-level itself). However, the above-mentioned
>> cooperation may still have its uses for some people. That said, they can
>> have all their BD_ADDR symlinks point to the same directory and
>> cooperate there, so I don't feel strongly about it either.
>
> If you did that, it would I think be better to have the bdaddr mapping in
> a config file. Symlinks are too much trouble. On the other hand, I'm not
> keen on config files either :)
as i suggested, in private email, something like apache's .htaccess
mechanism would be an ultimate solution here. however, its way too
much complicated for what obexapp is :-)
> Also, it could be better in that case to have a master daemon (along the
> lines of inetd) that could accept connectins and start obex according to
> the remote device address. Thats perhaps a lot of work though.
that's, actually, an interesting idea. i could see how it could be
applied to almost any bluetooth service. its not that much work, imo.
obexapp already can use stdin/out as file descriptors (in client
mode). configuration aspect of it is a pain though. perhaps we should
think along the lines of bluetooth inetd that maps pair (protocol,
protocol parameters) to service? something like (l2cap, 1) -> sdpd,
(rfcomm, 1) -> obexapp, (rfcomm, 3) -> rfcomm_pppd etc.?
>> But what about dropping camera's pictures and videos? People would
>> certainly expect to be able to do that straight from their devices
>> (rather than by running a client of some sort), and find the files
>> somewhere under their home directories (perhaps in ~/Desktop).
>
> Do you want to send pictures to your account when your wife is logged in,
> or does she want to when you are logged in? I don't know what prior art
> is there, but it seems to me that (as I said before) the person logged in
> at the console owns the machine and should receive files being sent. As
> Max said, Bluetooth is not big on credentials, it is assumed that all
> users (normally a only one) have equal access.
>
> For this reason, Bluetooth cannot properly be a multi-user link unless all
> the users trust each other (while Alice is sending files to the computer,
> Bill could be checking her phone log) so I don't see a problem with having
> all the files in a master directory owned by the same user (but setting
> the default path per remote device seems a good compromise)
yes, that is what i was thinking too. its pretty much like running
multiple copies of obexapp without actually running multiple copies of
obexapp :)
thanks,
max
>
> regards,
> iain
>
>
Yours,
-mi
wallaby@tasmania (11) mkdir ~/bluetooth
wallaby@tasmania (12) echo 'Please, map my ~wallaby/bluetooth to my
device' | write root
...
root@tasmania (713) ln -s ~wallaby/bluetooth
/var/spool/obex/Wallaby-Blackerry
root@tasmania (714) echo 'Done, enjoy!' | write wallaby
...
wallaby@tasmania (13) rmdir ~/bluetooth
wallaby@tasmania (14) ln -s ~wombat/bluetooth ~/bluetooh
Voila, because you trust stat(2) instead of lstat(2), Wallaby has just
gained full access to Wombat's bluetooth files -- and can switch to
anyone else's at will...
When you use lstat, you make it root's responsibility to chown the
BD_ADDR-symlinks under /var/spool/obex appropriately. Root may screw it
up (and you may want to reject connections, if a particular entry
belongs to root), but using stat(2) you give them no chance...
> broken symlinks is a bad idea, imo. i still do not get what do you
> gain by changing ownership on files in the same directory. perhaps i'm
> missing something here. please give me an example.
>
Therein lies the problem -- the "broken symlinks" are a very useful
thing, but suffer from the negative connotations of the word "broken".
There is nothing wrong with them -- and /etc/make.conf provides a great
example. They are very convenient in that they can be read and written
in a single transaction (readlink(2) and symlink(2)) -- instead of
open(2), read(2)/write(2), close(2). Their content is immediately
readable with ls, and a directory containing them can also be modified
atomically (even from scripts: with readlink(1), rm, ln) without
locking. That's why "broken symlinks" aren't bad in general...
Now, back to the topic at hand, my plan would've been an improvement
over the current situation. Whereas the existing obexapp (and the new
one, because you insist on the new behavior being optional) would dump
everything into the same directory under the same ownership, my approach
would allow different files to belong to different users, even if they
still share the same directory.
For example, a group of photographers dropping off pictures into the
common area may want to use the same server-directory. But they would
still prefer to be able to distinguish, who made which picture.
That said, under my approach such multi-user sharing is still possible,
even if you insist on BD_ADDR-entries being directories:
root@tasmania (817) mkdir /home/dropoff
root@tasmania (818) chmod 1777 /home/dropoff
root@tasmania (819) foreach cam (Wallaby Wombat Pademelon Thylacine)
foreach? ln -s /home/dropoff /var/spool/$cam-Camera
foreach? chown -h $cam /var/spool/$cam-Camera
foreach? end
Under my proposal, the dropped-off pictures will belong to the proper
users, while all residing in the same directory (for the editors to
view). Under your proposal, such sharing would be far more involved to
set up for no extra security...
So, the only thing I insist on, is that lstat be used to determine the
UID to switch to (after chroot-ing), when a matching BD_ADDR (or
bt_hostname) is found.
> like i said, its probably ok to change uid to owner of the _directory_
> and chroot() into it. but lstat(2) is out, sorry :)
>
Please, consider the above security example. stat is insecure for our
purpose, while lstat is just fine.
-mi
something's gotta give :) can't please everybody :)
[...]
ah, not exactly. its not only the files that 'bad guy' can upload into
(possibly chroot()ed) environment. its the user id. for example, what
if certain user id has access to a certain device node? 'bad guy'
could just mknod(8) device node and ...
>>> The only thing I do feel strongly about, is that, when a matching
>>> directory entry is found, the server shall perform a setuid not to the
>>> generic 'obex' user, but to the owner of that entry (and chroot into it,
>>> yes).
>>
>> like i said, its security vs. usability. i probably can live with
>> chroot()ing and changing uid to owner of the directory (and _not_
>> symlink).
>>
> This is wrong. Consider:
>
> wallaby@tasmania (11) mkdir ~/bluetooth
> wallaby@tasmania (12) echo 'Please, map my ~wallaby/bluetooth to my
> device' | write root
> ...
> root@tasmania (713) ln -s ~wallaby/bluetooth
> /var/spool/obex/Wallaby-Blackerry
> root@tasmania (714) echo 'Done, enjoy!' | write wallaby
> ...
> wallaby@tasmania (13) rmdir ~/bluetooth
> wallaby@tasmania (14) ln -s ~wombat/bluetooth ~/bluetooh
>
> Voila, because you trust stat(2) instead of lstat(2), Wallaby has just
> gained full access to Wombat's bluetooth files -- and can switch to
> anyone else's at will...
hmm.... perhaps, i'm missing something here. here is what i did
== step 1 ==
%id
uid=1004(wallaby) gid=1004(wallaby) groups=1004(wallaby)
%mkdir ~/bluetooth
%ls -l
drwxr-xr-x 2 wallaby wallaby 512 Apr 14 11:20 bluetooth
== step 2 ==
beetle# pwd
/var/spool/obex
beetle# ln -s ~wallaby/bluetooth Wallaby-Blackerry
beetle# ls -l
lrwxr-xr-x 1 root obex 23 Apr 14 11:21 Wallaby-Blackerry ->
/home/wallaby/bluetooth
beetle# stat -L Wallaby-Blackerry
99 1490343 drwxr-xr-x 2 wallaby wallaby 5953437 512 "Apr 14 11:20:37
2009" "Apr 14 11:20:37 2009" "Apr 14 11:20:37 2009" "Apr 14 11:20:37
2009" 4096 4 0 Wallaby-Blackerry
so as you can see user/group ids are correct, i.e. wallaby/wallaby
== step 3 ==
%id
uid=1005(wombat) gid=1005(wombat) groups=1005(wombat)
%mkdir ~/bluetooth
%ls -l
drwxr-xr-x 2 wombat wombat 512 Apr 14 11:22 bluetooth
== step 4 ==
%id
uid=1004(wallaby) gid=1004(wallaby) groups=1004(wallaby)
%pwd
/usr/home/wallaby
%rmdir bluetooth/
%ln -s ~wombat/bluetooth ~/bluetooth
%ls -l
lrwxr-xr-x 1 wallaby wallaby 22 Apr 14 11:29 bluetooth ->
/home/wombat/bluetooth
== step 5 ==
beetle# pwd
/var/spool/obex
beetle# stat -L Wallaby-Blackerry
99 1490434 drwxr-xr-x 2 wombat wombat 5953822 512 "Apr 14 11:22:10
2009" "Apr 14 11:22:10 2009" "Apr 14 11:22:10 2009" "Apr 14 11:22:10
2009" 4096 4 0 Wallaby-Blackerry
so, as you can see user/group ids are still correct, i.e. wombat/wombat.
also i used stat -L which makes use of stat(2) instead of lstat(2). so
from what i can see, and please feel free to correct me if i wrong,
user wallaby just intentionally 'gave up' his/her files to user
'wombat'. i do not see any problem here, do you? or am i missing
something obvious here?
> When you use lstat, you make it root's responsibility to chown the
> BD_ADDR-symlinks under /var/spool/obex appropriately. Root may screw it
> up (and you may want to reject connections, if a particular entry
> belongs to root), but using stat(2) you give them no chance...
if 'root' screws up, then game is over :) period. you can make this
argument with any piece of software out there :)
>> broken symlinks is a bad idea, imo. i still do not get what do you
>> gain by changing ownership on files in the same directory. perhaps i'm
>> missing something here. please give me an example.
>>
> Therein lies the problem -- the "broken symlinks" are a very useful
> thing, but suffer from the negative connotations of the word "broken".
> There is nothing wrong with them -- and /etc/make.conf provides a great
> example. They are very convenient in that they can be read and written
please let it go already :) i heard your point about /etc/malloc.conf
several times. you made it loud and clear. just because someone did it
this way, does not mean the the same model should be applied for
everything else. i'm sure whoever did this had good reasons for doing
it this way. keep in mind that someone else (or possibly the same
person) provided MALLOC_OPTIONS environmental variable and
_malloc_options global variable to override /etc/malloc.conf. imo, its
fine to use 'broken' symlinks to pass a few characters, however, you
suggesting to use the same model for something that is more
complicated. there probably are people who are confused about
permission on symlink vs. permissions on the directory symlink points
to. i was one of those people in not too distant past :-)
> in a single transaction (readlink(2) and symlink(2)) -- instead of
> open(2), read(2)/write(2), close(2). Their content is immediately
> readable with ls, and a directory containing them can also be modified
> atomically (even from scripts: with readlink(1), rm, ln) without
> locking. That's why "broken symlinks" aren't bad in general...
ok, 'broken' symlinks are bad idea, imo, when used as access control
mechanism :)
> Now, back to the topic at hand, my plan would've been an improvement
> over the current situation. Whereas the existing obexapp (and the new
> one, because you insist on the new behavior being optional) would dump
> everything into the same directory under the same ownership, my approach
> would allow different files to belong to different users, even if they
> still share the same directory.
>
> For example, a group of photographers dropping off pictures into the
> common area may want to use the same server-directory. But they would
> still prefer to be able to distinguish, who made which picture.
bad example - meta data in the pictures themselves tell much better story :)
> That said, under my approach such multi-user sharing is still possible,
> even if you insist on BD_ADDR-entries being directories:
>
> root@tasmania (817) mkdir /home/dropoff
> root@tasmania (818) chmod 1777 /home/dropoff
> root@tasmania (819) foreach cam (Wallaby Wombat Pademelon Thylacine)
> foreach? ln -s /home/dropoff /var/spool/$cam-Camera
> foreach? chown -h $cam /var/spool/$cam-Camera
> foreach? end
>
> Under my proposal, the dropped-off pictures will belong to the proper
> users, while all residing in the same directory (for the editors to
> view). Under your proposal, such sharing would be far more involved to
> set up for no extra security...
again, bad example, imo. all pictures will end up in /home/dropoff
owned by the same user (either 'obex' or owner of '/home/dropoff').
just point editors to /home/dropoff instead of /var/spool/obex and be
done with it. the only difference is that all the files will be owned
by the same user, but like i said, meta data in the pictures will tell
far better story then user id :) i also do not understand why 'sticky
bit' is required (its only needed in your version of the patch).
> So, the only thing I insist on, is that lstat be used to determine the
> UID to switch to (after chroot-ing), when a matching BD_ADDR (or
> bt_hostname) is found.
please see my example above.
>> like i said, its probably ok to change uid to owner of the _directory_
>> and chroot() into it. but lstat(2) is out, sorry :)
>>
> Please, consider the above security example. stat is insecure for our
> purpose, while lstat is just fine.
hmm, for my example above
beetle# stat Wallaby-Blackerry
98 47348 lrwxr-xr-x 1 root obex 1836017711 23 "Apr 14 11:21:23 2009"
"Apr 14 11:21:23 2009" "Apr 14 11:21:23 2009" "Apr 14 11:21:23 2009"
4096 0 0 Wallaby-Blackerry
and (with trailing /)
beetle# stat Wallaby-Blackerry/
99 1490343 lrwxr-xr-x 1 wallaby wallaby 1836017711 22 "Apr 14 11:29:08
2009" "Apr 14 11:29:08 2009" "Apr 14 11:29:08 2009" "Apr 14 11:29:08
2009" 4096 0 0 Wallaby-Blackerry/
stat(1) _without_ '-L' option uses lstat(2).
thanks,
max
In fact, because Wallaby is free to make their own ~/bluetooth a symlink
to ANYTHING, they may get access to ANYBODY's files, even those of
users, who don't use Bluetooth. Once root sets up
/var/spool/obex/Wallaby-Blackberry pointing at /home/wallaby/bluetooth,
user Wallaby can change that link to anything -- except, perhaps, root
themselves...
>> When you use lstat, you make it root's responsibility to chown the
>> BD_ADDR-symlinks under /var/spool/obex appropriately. Root may screw it
>> up (and you may want to reject connections, if a particular entry
>> belongs to root), but using stat(2) you give them no chance...
>>
> if 'root' screws up, then game is over :) period. you can make this argument with any piece of software out there :)
>
I agree. Which is why I keep saying, you should be using lstat (to read
info on entries created by root under /var/spool/obex), instead of stat
(which would give you info on entries maintained by the -- potentially
malicious -- users).
> there probably are people who are confused about
> permission on symlink vs. permissions on the directory symlink points
> to. i was one of those people in not too distant past :-)
>
Didn't we just agree, that root being confused is a "game-over" and
shall not be mentioned?
>> That's why "broken symlinks" aren't bad in general...
>>
> ok, 'broken' symlinks are bad idea, imo, when used as access control
> mechanism :)
>
Slow, painful, but still progress... :-)
>> For example, a group of photographers dropping off pictures into the
>> common area may want to use the same server-directory. But they would
>> still prefer to be able to distinguish, who made which picture.
>>
>
> bad example - meta data in the pictures themselves tell much better story :)
>
You are nit-picking, but no, actually. The EXIF metadata (BTW, relying
on file-format specific metadata to provide information, that filesystem
itself can/should provide, seems wrong in itsefl) will give the camera's
model and the time of the shot, but not the owner... It does not matter,
again, because multiple BD_ADDR symlinks can still point to the same
directory.
>> That said, under my approach such multi-user sharing is still possible,
>> even if you insist on BD_ADDR-entries being directories:
>>
>> root@tasmania (817) mkdir /home/dropoff
>> root@tasmania (818) chmod 1777 /home/dropoff
>> root@tasmania (819) foreach cam (Wallaby Wombat Pademelon Thylacine)
>> foreach? ln -s /home/dropoff /var/spool/$cam-Camera
>> foreach? chown -h $cam /var/spool/$cam-Camera
>> foreach? end
>>
>> Under my proposal, the dropped-off pictures will belong to the proper
>> users, while all residing in the same directory (for the editors to
>> view). Under your proposal, such sharing would be far more involved to
>> set up for no extra security...
>>
>
> again, bad example, imo. all pictures will end up in /home/dropoff
> owned by the same user (either 'obex' or owner of '/home/dropoff').
>
They will under YOUR proposal (using stat). Under mine (using lstat),
the files will have different owning UIDs... Which is good :-)
You may not like a particular example, but you have to admit, that my
proposal gives more flexibility to the admin setting up BT-access. They
can, if they want to, allow meaningful directory-sharing for the files
belonging to different users. And if they don't want to, they can keep
all symlinks pointing to /home/dropoff belong to `obex' (or whoever).
Under your proposal, there is no such flexibility and yet it is not any
more secure (sorry, mknod is too superficial). Escaping from chroot is
never easy, and for non-root users it is impossible -- without bugs in
the kernel...
> just point editors to /home/dropoff instead of /var/spool/obex and be done with it.
Of course, the editors would be looking at /home/dropoff! I don't even
understand, how what I wrote could've been read differently. The editors
will be looking at /home/dropoff (or, more likely, something like
\\dropoff\dropoff\). And in there they will be able to group files by
users (owners of the matching entries under /var/spool/obex) -- if you
take my approach (lstat). Under your approach (stat), the user would be
the same (owner of /home/dropoff)...
> i also do not understand why 'sticky bit' is required (its only needed in your version of the patch).
>
It is not required -- only to prevent people from (accidentally,
perhaps) overwriting each other's files under certain circumstances.
To summarize, you seem willing to consider the owner of the matching
entry when determining, which UID to switch to when dropping
root-privileges after chroot. The only remaining disagreement is whether
to use lstat vs. stat for the purpose. It being, literally, a
one-character change in the code, you can go ahead and begin coding the
change to match your style preferences.
In the mean time, consider the example I just gave, showing stat being a
security hole...
Yours,
-mi
1. Even when the service is not running as root to begin with (and thus
chroot is impossible), a user owning multiple devices may wish to have
separate directories for each one. Yet, the new -R switch, as proposed,
requires successful chroot into a matching entry... It does not need to.
How about:
+ case 'R': /* virtualize root for each device */
+ context.vroot = 1;
+ if (getuid() == 0)
+ context.secure = 1;
+ break;
+
chdir should be used instead of chroot in this case (-R was given, and a
matching entry is found, but we aren't running as root).
2. When going through the list of possible subdirectories-candidates,
hardcoding the number 3 is a bit dangerous. Using either
sizeof(root)/sizeof(root[0])
or simply going, until hitting NULL:
char const *root[] = { NULL, NULL, NULL, NULL }, **r;
...
foreach (r -> root; *r; r++) {
log_debug("%s(): Checking for %s/%s subdirectory",
__func__, context->root, *r);
...
would be a bit safer going forward -- what if some other parameter (such
as an environment variable) may some day be added to the list of
considerations?
3. After starting up, with the -R (or the -r) option, should/does not
the daemon chdir into the specified top-level directory? And if so,
there is no need to assemble the context->root with strlcat -- just
perform chdir into the relative root[n] (or *r in my example). The
chroot can then happen to ".". After chdir-ing, you can populate the
actual contet->root with getcwd(context->root, PATH_MAX) -- a faster
equivalent to using realpath(3).
This is not material, but the fewer cases, where a hard-coded PATH_MAX
is used instead of the POSIX-approved pathconf(2), the better...
Yours,
-mi
P.S. Thank you very much for keeping the wallabies in the manual's
examples. Better creatures are not to be found, and it is certainly
nicer to use them instead of the ubiquitous "foo" and "bar".
well, a couple of things. for now, we always have to start obexapp as
root because it needs to talk to sdpd(8) to register services. sdpd(8)
is checking credentials (passed via unix sockets) and makes sure that
the process, that is trying to register the service, has uid of 'root'
user. so, strictly speaking this change is a no-op because getuid()
will always be 0 or else obexapp will not start in server mode.
also, i'd _really_ like to keep clients "jailed" under their virtual
root folders. at least for now. as far as keeping and sharing files
under the same root folder, i just thought of a way to "break" the
latest patch: set up symlink that points to '.' under default root
folder. obviously chdir() and chroot() conditions will be satisfied
and you get your files dumped in the same directory.
> 2. When going through the list of possible subdirectories-candidates,
> hardcoding the number 3 is a bit dangerous. Using either
>
> sizeof(root)/sizeof(root[0])
>
> or simply going, until hitting NULL:
>
> char const *root[] = { NULL, NULL, NULL, NULL }, **r;
> ...
> foreach (r -> root; *r; r++) {
>
> log_debug("%s(): Checking for %s/%s subdirectory",
> __func__, context->root, *r);
> ...
>
> would be a bit safer going forward -- what if some other parameter (such
> as an environment variable) may some day be added to the list of
> considerations?
that's fine. i will fix it.
> 3. After starting up, with the -R (or the -r) option, should/does not
> the daemon chdir into the specified top-level directory? And if so,
> there is no need to assemble the context->root with strlcat -- just
> perform chdir into the relative root[n] (or *r in my example). The
> chroot can then happen to ".". After chdir-ing, you can populate the
> actual contet->root with getcwd(context->root, PATH_MAX) -- a faster
> equivalent to using realpath(3).
it does, chdir(), i.e. obexapp_server_set_initial_root() does it.
strlcat() is not that expensive, imo. it can be changed, i guess.
> This is not material, but the fewer cases, where a hard-coded PATH_MAX
> is used instead of the POSIX-approved pathconf(2), the better...
PATH_MAX comes from sys/syslimits.h, so, i thought it would be ok to
use. another alternative was MAXPATHLEN which was the same.
thanks,
max
> > Maksim Yevmenkin написав(ла):
> > because all of the bluetooth users would have to be listed in obex'
> > group and so there can be no more than 20 of them (I think, that's the
> > limit on a group size).
Just so this doesn't wind up being quoted as accurate:
There are no limits on how many people can be in a group. There is a
limit on how many groups a person can be in (or was; I haven't
verified that this hasn't been changed recently).
BSD was used at UC Berkeley (the B in BSD) on machines with thousands
of users, and groups with hundreds of members. We had to db'ify the
password file, but the groups code worked just fine.
<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.
O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
Logging the actual directory (as can be determined by getwd(NULL) after
chdir-ing, but before chroot-ing), rather than the name of the symlink
can be seen as beneficial too.
Yours,
-mi
But still, if a person can only participate in so many groups, forcing
participation in yet another one for common, non-administrative
functionality should be avoided...
Fortunately, we seem to have just agreed on a more straightforward way
anyway. Yours,
-mi
> Mike Meyer ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(ÿÿÿÿ):
> > There are no limits on how many people can be in a group. There is a
> > limit on how many groups a person can be in (or was; I haven't
> > verified that this hasn't been changed recently).
>
> Thanks for the correction, Mike. I had only a vague memory of there
> being some limits related to groups -- from years ago :-)
I don't know about FreeBSD but on NetBSD there is AFAIK no limit to the
number of groups that a user can be in. The "20 groups" limit comes from
NFS which used a fixed array in its specifications (and so is a problem on
any operating system)
iain
-mi
thanks for the ping. yes, terribly sorry, i'm completely swamped with
$realjob :( i'll try to get to it as soon as i can.
max