Re: [HACKERS] Query cancel and OOB data

From: Bruce Momjian <maillist(at)candle(dot)pha(dot)pa(dot)us>
To: tgl(at)sss(dot)pgh(dot)pa(dot)us (Tom Lane)
Cc: byronn(at)insightdist(dot)com, hackers(at)postgreSQL(dot)org
Subject: Re: [HACKERS] Query cancel and OOB data
Date: 1998-05-24 05:06:46
Message-ID: 199805240506.BAA28851@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


I have taken some time to think about this some more.

> Bruce Momjian <maillist(at)candle(dot)pha(dot)pa(dot)us> writes:
> > OK, I think I have a solution. I recommend we pass the backend pid to
> > the client as part of connection startup. Then, when the client wants
> > to cancel a query, it sends a cancel packet to its backend (new packet
> > type), and then sends that pid to the postmaster with a new packet type.
>
> > When the postmaster receives the packet with the pid, it sends a signal
> > to that pid/backend. The backend does a recv(MSG_PEEK) to see if it has
> > a pending packet with a cancel request. If it does, it cancels, if not,
> > it ignores it. In the read loop of the backend, all cancel requests are
> > ignored.
>
> OK, I guess the point of sending the normal-channel packet is to
> authenticate the cancel request? Otherwise anyone could send a cancel
> request to the postmaster, if they know the backend PID.

Yes, that is the intent of the normal-channel packet.

>
> I see a few flaws however:
>
> 1. What if the postmaster/signal/backend path is completed before the
> normal-channel cancel packet arrives? The backend looks, sees no
> packet, and ignores the request. Oops. This scenario is not at all
> implausible across a remote connection, since the first transmission
> of the normal-channel packet might be lost to a data glitch. By the
> time the client-side TCP stack decides to retransmit, it's too late.

Yes, this could happen, but it is only a cancel request. Another way to
proceed is to have the server query the client after it receives the
request from the postmaster, but that seems odd.

>
> 2. I don't think you could use this to abort out of a COPY IN transfer,
> because the confirmation packet would be impossible to distinguish
> from data reliably. In general there's a risk of confusion if the
> server might be looking for the confirmation packet when the client
> thinks it's in the middle of sending a regular request.

Yes, that is a good point.

>
> 3. There's still a possibility of a denial-of-service attack.
> A bad guy could send a flood of cancel requests with the right PID,
> and he'd slow down the server substantially even if nothing ever gets
> cancelled. (Also, because of point 2, some of the forged cancels
> might succeed...)

Yes, but does this increase our denial-of-service vulnerability, or just
give the person one more way to slow things down?

>
>
> > This does a few things for us. It allows us to use cancel in unix
> > domain sockets, and in Java or anything that can't support OOB. In
> > fact, I would recommend discarding OOB in favor of this method.
>
> The real advantage of OOB for this purpose is that there's no
> possibility of confusing the cancel request with normal data.

Yes, that is true. I just am grasping for a unix domain and
java/non-oob solution.

>
>
> I still like the idea I floated a couple days ago: have the initial
> handshake provide both the PID of the backend and a "secret code"
> randomly generated by the server for that connection. The client
> must transmit both the PID and the code to the postmaster for the
> cancel request to be accepted. That method has all the advantages:
>
> 1. The client doesn't have to supply a password; libpq will retain
> all the necessary info internally.
>
> 2. The probability of defeating the scheme can be made arbitrarily
> small (much smaller than guessing a password, say) with a long enough
> secret code. 8 or so random bytes ought to do.
>
> 3. There's no problem with synchronization between the client/postmaster
> and client/backend data paths, because no data need be sent across the
> client/backend path. This is just as good as using OOB to keep the
> cancel separate from normal traffic.
>
> 4. Don't have to depend on having OOB facility.
>
> The only disadvantage I can see is having to open a new postmaster
> connection every time you want to cancel; but hopefully that won't
> be very often, so performance shouldn't be much of an issue.

Yes, the overhead of opening a new postmaster connection is very small,
especially because no backend is started. I was trying to avoid the
'magic cookie' solution for a few reasons:

1) generating a random secret codes can be slow (I may be wrong)

2) the random key is sent across the network with a cancel
request, so once it is used, it can be used by a malcontent to cancel
any query for that backend. He doesn't need to spoof any packets to
insert it into the TCP/IP stream, he just connects to the postmaster and
sends the secret key. For long-running queries, that may be a problem.
Not sure how much of a vulnerability that is.

3) I hesitate to add the bookkeeping in the postmaster and libpq
of that pid/secret key combination. Seems like some bloat we could do
without.

4) You have to store the secret key in the client address space,
possibly open to snooping.

However, in thinking about it, I don't think there is any way to avoid
your solution of pid/secret key. The postmaster, on receiving the
secret key, can send a signal to the backend, and the query will be
cancelled. Nothing will be sent along the backend/client channel. All
other interfaces that want cancel handling will have to add some code
for this too.

This basically simulates OOB by sending a message to the postmaster,
which is always listening, and having it send a signal, which is
possible because they are owned by the same user.

Actually, in:

ConnCreate()

I see a call to:

RandomSalt(port->salt);

Any idea what that is used for? Maybe we can use that? And why is it
being generated for non-crypt connections? Seems like a waste if
random() is an expensive function. He calls it twice, once for each of
the two salt characters. Looks like a cheap function on BSDI from the
looks of the library code.

--
Bruce Momjian | 830 Blythe Avenue
maillist(at)candle(dot)pha(dot)pa(dot)us | Drexel Hill, Pennsylvania 19026
+ If your life is a hard drive, | (610) 353-9879(w)
+ Christ can be your backup. | (610) 853-3000(h)

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Ivar Helbekkmo 1998-05-24 09:13:14 Re: [HACKERS] Current sources?
Previous Message The Hermit Hacker 1998-05-24 04:08:41 Just a test...