Nicolai Johannes writes:
> Concerning the new privileges:
> If you have a better suggestion concerning naming and
> responsibility, please do not hesitate to tell me, I am open for
> every idea.

I wasn't trying to design it for you; I wanted to find out what
problem you were intending to solve, or how you thought the new
feature would be used.

(This might well be the right breakdown of privileges; I can't tell.)

> As I have understand the PRIV_NET_* proposal, the two privileges should do 
> the following:
> 
> PRIV_NET_ACCEPT: Should restrict accept() and listen() and for recv* for not 
> connected sockets (that are possible for UDP as well). I caused confusion 
> with mentioning bind(), this is not part of the privilege.

OK.

> PRIV_NET_INITIATE: Should cover connect() and send* for not connected sockets.
> 
> Please note that both privileges should not cover Unix Domain
> Sockets (these should be restricted according to the proposal with
> future capabilities (PRIV_IPC_*) together with doors, message
> queues, semaphores, files, ...) 

I see.  Are connections via loopback special as well, or just Unix
Domain?

What about the TLI loopback transport, which is distinct from both
TCP/IP loopback addresses and Unix Domain sockets?

> To your problems mentioned with this approach:
> Something like limiting the set of ports and
> protocols available is at least very hard if you chose to do this with new 
> privileges (I know RSBAC, a set of Linux kernel patches, where it is possible 
> to associate a kind of network protocol/operation and port template with a 
> process, role or user).

Indeed; it's hard.  I'm not sure what the privileges would do without
a feature like that.  Is, for example, breaking libraries that open
their own internal sockets an acceptable result?

> The privileges should only be dropped by processes that really want to 
> disable new network activity at all, that various problems will occur if one 
> drop these was already discussed on the list.

It's not just "new" network activity.  In order to use sendto on an
unconnected socket, an application must retain PRIV_NET_INITIATE, even
if it's not going to be starting any "new" conversations.

> Personally I am not really sure whether one should differentiate between 
> PRIV_NET_INITIATE and PRIV_NET_ACCEPT or should merge them together.
> I interpreted the proposal that incoming traffic should be queued (perhaps as 
> long as the privilege reappears in the effective set).

That's probably the right answer, as it's possible the application
could regain the privileges or even exec something else that does have
the right privileges.

> Concerning the syslog/SNMP and inetd issue: I am not involved deep
> enough in both daemons that I understand how the privileges would
> break conformity. Is syslog TCP/IP related (thought of Unix domain
> sockets).

Actually, normal syslog in Solaris goes via the log driver, so that's
perhaps ok.  I was more concerned here with SNMP, which has no such
facility.

But more generally: if you revoke the ability to send and receive
network packets from what appears to be a "non-networking"
application, this will also revoke network access from libraries that
this application calls.  Figuring out what's affected by this seems to
me to be a big part of figuring out how the feature could be used (and
what it must do in order to be useful).

As for inetd, a wait-type service must issue its own accept() (for
TCP) or recvfrom() (for UDP).  It sounds like there'll at least need
to be extra documentation for these sorts of applications.

> Concerning the SCTP operatioons: For me it looks as if sctp supports
> all operations, the new privileges should restrict. Please correct
> me if I'm wrong.

My question is whether (and how) the special functions in SCTP map to
any security-related behaviors here.

Is sctp_peeloff() similar enough to accept() that it's restricted by
PRIV_NET_ACCEPT?  Or is it just an internal bit of connection juggling
that doesn't warrant restriction?

What about sctp_bindx()?  Unlike a regular bind() call, SCTP's version
allows more addresses and ports to be associated with an existing
endpoint.

What do SCTP associations represent?  Are they subject to
restrictions?

> The biggest problem I have is that I am only familiar to the the
> traditional socket operations but not (yet) with things like
> XTI/TLI.

The opengroup.org documents may be helpful.

> I think I have already found the correct place for the connect()
> checks (seems as if I have to do the checks on module level in order
> not to miss a possibility how connecting is possible in Solaris):

Yes, I think that's so.

> udp_connect in udp.c (should I return TACCES with udp_err_ack in case of 
> unsufficiant privileges?)

That action seems reasonable, though I don't quite understand how
udp_connect itself would involve privileges of any sort.  (See the
state discussion below.)

> tcp_connect in tcp.c (should I return TAproCCES with tcp_err_ack?)

Yes.

> sctp_connect in sctp_conn.c (this check would be at layer 2 (sockfs)
> and not on STREAM module layer(is there a sctp STREAM module?

Not really.

> How to deal with SOCK_SEQPACKET type sctp sockets?)

This relates to the association question above.  I don't know what the
answer is.

> icmp_connect in icmp.c (should I handle this protocol at all?)

This where raw sockets are implemented.  I'm not sure how this relates
to the work you're doing.  Does PRIV_NET_RAWACCESS automatically imply
the privileges you're adding?  Or could an application have one but
not the other?

> Up to this point, I have not focused my investigations on NCA, so I will add 
> suggestions concerning this protocol later.

OK.

> According to the proposals on the list, I should not restrict bind() at all. 
> This first sounds strange to me but after I have realized, that every connect 
> requires a bind this makes sense.

Yes, at least an implicit bind.

> For the sendv* method for unconnected UDP, I think the correct place is
> udp_output in udp.c

That sounds reasonable.  (Don't forget about v6 as well ...)

> To my mind, I have to check for  udp->udp_state != TS_DATA_XFER in order to 
> find out whether I had to deal with connected or unconnected UDP. The checks 
> have to be done for M_DATA and for T_UNIT_DATA_REQ also I am not totally sure 
> why one have to differentiate both message types.

I'm not sure why UDP connected state matters here.

Doing connect() on a UDP socket doesn't involve any sort of security
issue that I can see.  It's very much unlike connect() on TCP, in that
all it does is record a peer address for later use by send(), and
enable reception of ICMP errors.

> Currently, I have no clue how to restrict unconnected udp from receiving 
> datagrams.

Nor do I.  For XTI/TLI, I'd expect any such restriction to be in the
stream head, which is likely to be messy.  That's why I was asking
about what happens with inbound packets.

> Of course I could block sotpi_recvmsg in case of unconnected sockets or even 
> introduce checks in socksyscalls.c but the STREAM API still allows to receive 
> messages via getmsg. Both code only reads from a message queue that is filled 
> by UDP. I am not sure whether I should additonally change sock_getmsg or 
> strgetmsg.

_If_ it's reasonable to block UDP from receiving data, then that
(modifying the stream head) seems to me like the right way to do it.

But I'm not sure that it's reasonable to block UDP in this way.
"Inbound" and "outbound" connections have a lot more meaning with
something like TCP than with UDP.

The core distinction that bothers me is that you've equated
connect/accept in TCP with sendto/recvfrom in UDP.  The two seem
utterly different to me.  If, for example, I'm permitted to do
connect() in TCP but blocked from doing accept(), then on my connected
TCP sockets, I can freely do read/write to that peer, but I can only
write to my peers via UDP and never read.

Why?  That doesn't seem consistent.  Part of the problem here, I
think, is that UDP lacks the sort of "intent" information that's
available with TCP.  Except in the behavior and intended operation of
the application protocol itself, UDP doesn't have a notion of
"inbound" or "outbound" connections that can be mapped directly into
"accept" or "initiate."  Instead, it deals in input and output
packets, which is a greatly different set of mechanisms.

> If I understood the code, listen is only defined as an operation that changes 
> the backlog of a bound socket. There is only sotpi_listen for UDP and IP and 
> no equivalent at STREAM module layer (here one can find only bind). Should I 
> modify sotpi_listen so that it checks the permission when the flag 
> _SOBIND_LISTEN is set? For SCTP I would change sosctp_listen in socksctp.c
> I am not sure whether other mechanism may intercept the layer where I intend 
> to introduce the checks.

If you introduce the check into sotpi_listen, then where will you do
the check for XTI/TLI?

In XTI/TLI (and thus in TCP itself), the listener establishment is
done as part of T_BIND_REQ processing.

> To restrict accepting new connections, I have only found sotpi_accept in 
> socktpi.c for UDP and TCP and sosctp_accept for SCTP. I am not sure whether 
> one could bypass these functions with another API (XTI/TLI), perhaps I should 
> intercept accept calls one layer deeper in sowaitconnind in sockstr.c?

I don't think that's the correct place to do this.  If you did, then
(as I read it) applications without the right privilege could still
open listening sockets to capture new connections, but just would be
unable to accept() them.

I suspect that you need to modify both O_T_BIND_REQ/T_BIND_REQ
processing as well as the accept path.  (The latter for applications
that received a listen socket as part of the exec.)

-- 
James Carlson, KISS Network                    <[EMAIL PROTECTED]>
Sun Microsystems / 1 Network Drive         71.232W   Vox +1 781 442 2084
MS UBUR02-212 / Burlington MA 01803-2757   42.496N   Fax +1 781 442 1677
_______________________________________________
networking-discuss mailing list
[email protected]

Reply via email to