From nobody Mon Jan 06 16:22:27 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YRfbS1k4cz5jntN; Mon, 06 Jan 2025 16:22:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YRfbS12WHz41b9; Mon, 6 Jan 2025 16:22:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1736180548; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=kR1FXyRfsKISjeN4ZDACDxnDYG0I5V+QgXzhZFlD1d0=; b=RdbbeV0lL8CKXBE0pskGiRWkMi9eC7/ondveeyRd9NsHIgDeSeH2/+jKlSUBxr5FKeTyrl /e/bJlw4FVMwyIA/t+WRGQpDEz4p1ximCpa2Kpb7gPqO9JbEjNjSLW1BvVzyGRjceEdHmz p4NYIe7BMWdowFMKz+qrSjs6EwXf/SYo8R8h0zsM8qshmGMr9CZRlxvXv0jYZds5uFzH2U avwdgeTQJTXQmtkzPDRhAHnE14o60D56ujm09yvbj8VrTVRyExro0SMRWp05w7gd2k1rdJ VL3EAFXt559NxmJi0XuUZqGdfp7P6cuJ12/fKsb6qy13oCDt9nPs/kaIeUzftA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1736180548; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=kR1FXyRfsKISjeN4ZDACDxnDYG0I5V+QgXzhZFlD1d0=; b=PeAtN26u0yso653/x4jp483jgAo+fXJQlmnPTN5MwgFvVugu7sJk6XYVa+MWeaLpRofXU5 KZW1ibglU9aePWJJOgJHBV2Nhjv1Q0T6dHScsCGD7CMaLsl3YDxEAmyGboKeZ+oBN7r3X7 dmT59CF7g8WX8cxGG4iEiv0REbax6VMThIxrXdso1PKyXQYG6VAt/J2O0YfUf20XbZiYoL LhigauE+MIdnQDXHHCgfqJTHDNkMVK0GOXQpY2GGN2Rvw12rv6ezczdn1P+495Javt5kjS iN6unkFoobNAiulZGh+FWC8c64WeBfrcxoFBwT/AqGzuM7JCzsFVdpyn0/S64A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1736180548; a=rsa-sha256; cv=none; b=Nqg50dQq5uiv5cF1cGlX10WGiX7/pOZZ50lKPxMlBLsvq1N/XnE1oUPtr5SjlbP+ufnAEx RrA5aaDdtYKpJcGt1ZJ4rviaHsDuShD6B/TTFOMm6RQTjV1t9OhhXk5NA67k10fmERDY+w 1+11h4gmYc4r6A/at1Otmuzjz5NPwTDxgcTRBTokE/5DNfDNkN88Xp20hRBzTi+7ymF9S3 x16WGwnV+Jdbs4tlV21N7m/6a8Kjx6v3QD5gCSuwNsRXwkPUBPR9cXavnVm4Lfhs59DCvK ymOGfF0BkLGI927R44WSiGDiSmPKG9BuVjzWG+K0F3LaH4goIZJJCwafv1mBCQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YRfbS0d49zXX9; Mon, 06 Jan 2025 16:22:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 506GMRH2018926; Mon, 6 Jan 2025 16:22:27 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 506GMR6U018923; Mon, 6 Jan 2025 16:22:27 GMT (envelope-from git) Date: Mon, 6 Jan 2025 16:22:27 GMT Message-Id: <202501061622.506GMR6U018923@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: 7f39f03c4d9a - main - libc/xdr: remove bogus lseek(2) for xdr streams List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7f39f03c4d9a138f84a08931b2a6c016521cacf5 Auto-Submitted: auto-generated The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=7f39f03c4d9a138f84a08931b2a6c016521cacf5 commit 7f39f03c4d9a138f84a08931b2a6c016521cacf5 Author: Gleb Smirnoff AuthorDate: 2025-01-06 16:22:14 +0000 Commit: Gleb Smirnoff CommitDate: 2025-01-06 16:22:14 +0000 libc/xdr: remove bogus lseek(2) for xdr streams Doing some debugging I noticed that applications using rpc(3) would often make lseek(2) on a totally bogus file descriptor, that looks more like a pointer. So, what happens here is that xdrrec type xdr doesn't keep a track of how many bytes were sent/received on the stream and tries to obtain this number via lseek(2). Then it adds/subtracts the offset in the internal buffer from the obtained number. This code originates from the original Sun RPC import in 1994. However, it was not a working code even if Solaris would support lseek(2) on a socket, because it was passing not the file descriptor, but a pointer to opaque data from upper RPC layer. It could be that previously (before import to FreeBSD) code was correct, but the Solaris 8 documentation says that lseek(2) on socket isn't supported [1]. Maybe supported on older Solaris? Anyway, this lseek(2) never worked and xdr_getpos() would always fail on xdrrec object, until 8f55a568f69c5 in 2008 it was slightly fixed to tolerate failure of lseek(2) and return a correct value within the small internal buffer for XDR_ENCODE mode and a an incorrect (negative to unsigned) result for XDR_DECODE. It seems no consumer ever calls xdr_getpos()/xdr_setpos() on this kind of descriptor when in XDR_DECODE mode. So, remove this lseek(2) and preserve operation within the small buffer only. Supposedly fix the operation for XDR_DECODE mode. Note that there is no use and no test coverage for the XDR_DECODE. Note that xdr(3) manual page already documents limitations for xdr_getpos() and xdr_setpos() for the stream type objects. [1] https://docs.oracle.com/cd/E19109-01/tsolaris8/835-8003/6ruu1b0or/index.html Reviewed by: asomers, markj Differential Revision: https://reviews.freebsd.org/D48205 --- lib/libc/xdr/xdr_rec.c | 69 +++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/lib/libc/xdr/xdr_rec.c b/lib/libc/xdr/xdr_rec.c index f1167fdeaa65..7dc9bbb31ec3 100644 --- a/lib/libc/xdr/xdr_rec.c +++ b/lib/libc/xdr/xdr_rec.c @@ -318,27 +318,30 @@ xdrrec_putbytes(XDR *xdrs, const char *addr, u_int len) return (TRUE); } +/* + * XXX: xdrrec operates on a TCP stream and doesn't keep record of how many + * bytes were sent/received overall. Thus, the XDR_GETPOS() and XDR_SETPOS() + * can operate only within small internal buffer. So far, the limited set of + * consumers of this xdr are fine with that. It also seems that methods are + * never called in the XDR_DECODE mode. + */ static u_int xdrrec_getpos(XDR *xdrs) { RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; - off_t pos; + ptrdiff_t pos; - pos = lseek((int)(u_long)rstrm->tcp_handle, (off_t)0, 1); - if (pos == -1) - pos = 0; switch (xdrs->x_op) { - case XDR_ENCODE: - pos += rstrm->out_finger - rstrm->out_base; + pos = rstrm->out_finger - rstrm->out_base; break; case XDR_DECODE: - pos -= rstrm->in_boundry - rstrm->in_finger; + pos = rstrm->in_finger - rstrm->in_base; break; - default: - pos = (off_t) -1; + case XDR_FREE: + pos = -1; break; } return ((u_int) pos); @@ -352,32 +355,30 @@ xdrrec_setpos(XDR *xdrs, u_int pos) int delta = currpos - pos; char *newpos; - if ((int)currpos != -1) - switch (xdrs->x_op) { - - case XDR_ENCODE: - newpos = rstrm->out_finger - delta; - if ((newpos > (char *)(void *)(rstrm->frag_header)) && - (newpos < rstrm->out_boundry)) { - rstrm->out_finger = newpos; - return (TRUE); - } - break; - - case XDR_DECODE: - newpos = rstrm->in_finger - delta; - if ((delta < (int)(rstrm->fbtbc)) && - (newpos <= rstrm->in_boundry) && - (newpos >= rstrm->in_base)) { - rstrm->in_finger = newpos; - rstrm->fbtbc -= delta; - return (TRUE); - } - break; - - case XDR_FREE: - break; + switch (xdrs->x_op) { + case XDR_ENCODE: + newpos = rstrm->out_finger - delta; + if ((newpos > (char *)(void *)(rstrm->frag_header)) && + (newpos < rstrm->out_boundry)) { + rstrm->out_finger = newpos; + return (TRUE); } + break; + + case XDR_DECODE: + newpos = rstrm->in_finger - delta; + if ((delta < (int)(rstrm->fbtbc)) && + (newpos <= rstrm->in_boundry) && + (newpos >= rstrm->in_base)) { + rstrm->in_finger = newpos; + rstrm->fbtbc -= delta; + return (TRUE); + } + break; + + case XDR_FREE: + break; + } return (FALSE); }