2018-06-29 18:42:58

by Steve Dickson

[permalink] [raw]
Subject: [PATCH V2] xdrstdio_create buffers do not output encoded values on ppc

From: Daniel Sands <[email protected]>

The cause is that the xdr_putlong uses a long to store the
converted value, then passes it to fwrite as a byte buffer.
Only the first 4 bytes are written, which is okay for a LE
system after byteswapping, but writes all zeroes on BE systems.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1261738

Signed-off-by: Steve Dickson <[email protected]>
---
v2: Added bounds checking
Changed from unsigned to signed

src/xdr_stdio.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/xdr_stdio.c b/src/xdr_stdio.c
index 4410262..b902acd 100644
--- a/src/xdr_stdio.c
+++ b/src/xdr_stdio.c
@@ -103,10 +103,12 @@ xdrstdio_getlong(xdrs, lp)
XDR *xdrs;
long *lp;
{
+ int32_t mycopy;

- if (fread(lp, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
+ if (fread(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
return (FALSE);
- *lp = (long)ntohl((u_int32_t)*lp);
+
+ *lp = (long)ntohl(mycopy);
return (TRUE);
}

@@ -115,8 +117,14 @@ xdrstdio_putlong(xdrs, lp)
XDR *xdrs;
const long *lp;
{
- long mycopy = (long)htonl((u_int32_t)*lp);
+ int32_t mycopy;
+
+#if defined(_LP64)
+ if ((*lp > INT32_MAX) || (*lp < INT32_MIN))
+ return (FALSE);
+#endif

+ mycopy = (int32_t)htonl((int32_t)*lp);
if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
return (FALSE);
return (TRUE);
--
2.17.1



2018-06-29 19:19:45

by Chuck Lever III

[permalink] [raw]
Subject: Re: [Libtirpc-devel] [PATCH V2] xdrstdio_create buffers do not output encoded values on ppc



> On Jun 29, 2018, at 2:42 PM, Steve Dickson <[email protected]> wrote:
>=20
> From: Daniel Sands <[email protected]>
>=20
> The cause is that the xdr_putlong uses a long to store the
> converted value, then passes it to fwrite as a byte buffer.
> Only the first 4 bytes are written, which is okay for a LE
> system after byteswapping, but writes all zeroes on BE systems.
>=20
> Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=3D1261738
>=20
> Signed-off-by: Steve Dickson <[email protected]>
> ---
> v2: Added bounds checking
> Changed from unsigned to signed
>=20
> src/xdr_stdio.c | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 deletions(-)
>=20
> diff --git a/src/xdr_stdio.c b/src/xdr_stdio.c
> index 4410262..b902acd 100644
> --- a/src/xdr_stdio.c
> +++ b/src/xdr_stdio.c
> @@ -103,10 +103,12 @@ xdrstdio_getlong(xdrs, lp)
> XDR *xdrs;
> long *lp;
> {
> + int32_t mycopy;
>=20
> - if (fread(lp, sizeof(int32_t), 1, (FILE *)xdrs->x_private) !=3D =
1)
> + if (fread(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) =
!=3D 1)
> return (FALSE);
> - *lp =3D (long)ntohl((u_int32_t)*lp);
> +
> + *lp =3D (long)ntohl(mycopy);
> return (TRUE);
> }
>=20
> @@ -115,8 +117,14 @@ xdrstdio_putlong(xdrs, lp)
> XDR *xdrs;
> const long *lp;
> {
> - long mycopy =3D (long)htonl((u_int32_t)*lp);
> + int32_t mycopy;
> +
> +#if defined(_LP64)

I don't find an _LP64 macro defined within libtirpc or the C libraries
on my RHEL 7 system. The test really should look something like this:

#if __BITS_PER_LONG =3D=3D 64

though I'm sure that's not right either.


> + if ((*lp > INT32_MAX) || (*lp < INT32_MIN))
> + return (FALSE);
> +#endif
>=20
> + mycopy =3D (int32_t)htonl((int32_t)*lp);
> if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) =
!=3D 1)
> return (FALSE);
> return (TRUE);
> --=20
> 2.17.1
>=20
>=20
> =
--------------------------------------------------------------------------=
----
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> _______________________________________________
> Libtirpc-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/libtirpc-devel

--
Chuck Lever




2018-06-29 19:29:52

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH V2] xdrstdio_create buffers do not output encoded values on ppc

T24gRnJpLCAyMDE4LTA2LTI5IGF0IDE0OjQyIC0wNDAwLCBTdGV2ZSBEaWNrc29uIHdyb3RlOg0K
PiBGcm9tOiBEYW5pZWwgU2FuZHMgPGRuc2FuZHNAc2FuZGlhLmdvdj4NCj4gDQo+IFRoZSBjYXVz
ZSBpcyB0aGF0IHRoZSB4ZHJfcHV0bG9uZyB1c2VzIGEgbG9uZyB0byBzdG9yZSB0aGUNCj4gY29u
dmVydGVkIHZhbHVlLCB0aGVuIHBhc3NlcyBpdCB0byBmd3JpdGUgYXMgYSBieXRlIGJ1ZmZlci4N
Cj4gT25seSB0aGUgZmlyc3QgNCBieXRlcyBhcmUgd3JpdHRlbiwgd2hpY2ggaXMgb2theSBmb3Ig
YSBMRQ0KPiBzeXN0ZW0gYWZ0ZXIgYnl0ZXN3YXBwaW5nLCBidXQgd3JpdGVzIGFsbCB6ZXJvZXMg
b24gQkUgc3lzdGVtcy4NCj4gDQo+IEZpeGVzOiBodHRwczovL2J1Z3ppbGxhLnJlZGhhdC5jb20v
c2hvd19idWcuY2dpP2lkPTEyNjE3MzgNCj4gDQo+IFNpZ25lZC1vZmYtYnk6IFN0ZXZlIERpY2tz
b24gPHN0ZXZlZEByZWRoYXQuY29tPg0KPiAtLS0NCj4gdjI6IEFkZGVkIGJvdW5kcyBjaGVja2lu
Zw0KPiAgICAgQ2hhbmdlZCBmcm9tIHVuc2lnbmVkIHRvIHNpZ25lZA0KPiANCj4gIHNyYy94ZHJf
c3RkaW8uYyB8IDE0ICsrKysrKysrKysrLS0tDQo+ICAxIGZpbGUgY2hhbmdlZCwgMTEgaW5zZXJ0
aW9ucygrKSwgMyBkZWxldGlvbnMoLSkNCj4gDQo+IGRpZmYgLS1naXQgYS9zcmMveGRyX3N0ZGlv
LmMgYi9zcmMveGRyX3N0ZGlvLmMNCj4gaW5kZXggNDQxMDI2Mi4uYjkwMmFjZCAxMDA2NDQNCj4g
LS0tIGEvc3JjL3hkcl9zdGRpby5jDQo+ICsrKyBiL3NyYy94ZHJfc3RkaW8uYw0KPiBAQCAtMTAz
LDEwICsxMDMsMTIgQEAgeGRyc3RkaW9fZ2V0bG9uZyh4ZHJzLCBscCkNCj4gIAlYRFIgKnhkcnM7
DQo+ICAJbG9uZyAqbHA7DQo+ICB7DQo+ICsJaW50MzJfdCBteWNvcHk7DQo+ICANCj4gLQlpZiAo
ZnJlYWQobHAsIHNpemVvZihpbnQzMl90KSwgMSwgKEZJTEUgKil4ZHJzLT54X3ByaXZhdGUpDQo+
ICE9IDEpDQo+ICsJaWYgKGZyZWFkKCZteWNvcHksIHNpemVvZihpbnQzMl90KSwgMSwgKEZJTEUg
Kil4ZHJzLQ0KPiA+eF9wcml2YXRlKSAhPSAxKQ0KPiAgCQlyZXR1cm4gKEZBTFNFKTsNCj4gLQkq
bHAgPSAobG9uZyludG9obCgodV9pbnQzMl90KSpscCk7DQo+ICsNCj4gKwkqbHAgPSAobG9uZylu
dG9obChteWNvcHkpOw0KPiAgCXJldHVybiAoVFJVRSk7DQo+ICB9DQo+ICANCj4gQEAgLTExNSw4
ICsxMTcsMTQgQEAgeGRyc3RkaW9fcHV0bG9uZyh4ZHJzLCBscCkNCj4gIAlYRFIgKnhkcnM7DQo+
ICAJY29uc3QgbG9uZyAqbHA7DQo+ICB7DQo+IC0JbG9uZyBteWNvcHkgPSAobG9uZylodG9ubCgo
dV9pbnQzMl90KSpscCk7DQo+ICsJaW50MzJfdCBteWNvcHk7DQo+ICsNCj4gKyNpZiBkZWZpbmVk
KF9MUDY0KQ0KPiArCWlmICgoKmxwID4gSU5UMzJfTUFYKSB8fCAoKmxwIDwgSU5UMzJfTUlOKSkN
Cj4gKwkJcmV0dXJuIChGQUxTRSk7DQoNClRoZSB3aWxsIHdvcmsganVzdCBmaW5lIGlmIHlvdXIg
Y2FzdCBpczoNCglpbnQgYTsNCg0KCWxwID0gKGxvbmcpYTsNCg0KLi4uYnV0IGl0IHdvbid0IGRv
IHRoZSByaWdodCB0aGluZyBmb3INCg0KCXVuc2lnbmVkIGludCBiID0gVUlOVDMyX01BWDsNCg0K
CWxwID0gKGxvbmcpYjsJLyogc2V0IGxwIHRvIFVJTlQzMl9NQVggKi8NCg0KU2luY2UgdGhlcmUg
dXMgbm8gZGVkaWNhdGVkIHhkcnN0ZGlvX3B1dHVsb25nKCkgdG8gdXNlIGZvciB1bnNpZ25lZA0K
aW50ZWdlcnMsIHdlIG5lZWQgdGhlIGNoZWNrIHRvIHdvcmsgZm9yIGJvdGggY2FzZXMuDQpGb3Ig
dGhhdCByZWFzb24sIEkgdGhpbmsgdGhlIGFib3ZlIGNoZWNrIGVpdGhlciBoYXMgdG8gYmU6DQoN
CglpZiAoKmxwID09IChsb25nKSgodV9pbnQzMl90KSpscCkpDQoJCXJldHVybiAoRkFMU0UpOw0K
DQouLi5vciBzb21ldGhpbmcgdWdsaWVyIGxpa2UNCg0KCWlmICgqbHAgPiBVSU5UMzJfTUFYIHx8
ICpscCA8IElOVDMyX01JTikNCgkJcmV0dXJuIChGQUxTRSk7DQoNCj4gKyNlbmRpZg0KPiAgDQo+
ICsJbXljb3B5ID0gKGludDMyX3QpaHRvbmwoKGludDMyX3QpKmxwKTsNCj4gIAlpZiAoZndyaXRl
KCZteWNvcHksIHNpemVvZihpbnQzMl90KSwgMSwgKEZJTEUgKil4ZHJzLQ0KPiA+eF9wcml2YXRl
KSAhPSAxKQ0KPiAgCQlyZXR1cm4gKEZBTFNFKTsNCj4gIAlyZXR1cm4gKFRSVUUpOw0KLS0gDQpU
cm9uZCBNeWtsZWJ1c3QNCkNUTywgSGFtbWVyc3BhY2UgSW5jDQo0MzAwIEVsIENhbWlubyBSZWFs
LCBTdWl0ZSAxMDUNCkxvcyBBbHRvcywgQ0EgOTQwMjINCnd3dy5oYW1tZXIuc3BhY2UNCg0K

2018-06-29 19:33:27

by Chuck Lever III

[permalink] [raw]
Subject: Re: [PATCH V2] xdrstdio_create buffers do not output encoded values on ppc



> On Jun 29, 2018, at 3:29 PM, Trond Myklebust <[email protected]> =
wrote:
>=20
> On Fri, 2018-06-29 at 14:42 -0400, Steve Dickson wrote:
>> From: Daniel Sands <[email protected]>
>>=20
>> The cause is that the xdr_putlong uses a long to store the
>> converted value, then passes it to fwrite as a byte buffer.
>> Only the first 4 bytes are written, which is okay for a LE
>> system after byteswapping, but writes all zeroes on BE systems.
>>=20
>> Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=3D1261738
>>=20
>> Signed-off-by: Steve Dickson <[email protected]>
>> ---
>> v2: Added bounds checking
>> Changed from unsigned to signed
>>=20
>> src/xdr_stdio.c | 14 +++++++++++---
>> 1 file changed, 11 insertions(+), 3 deletions(-)
>>=20
>> diff --git a/src/xdr_stdio.c b/src/xdr_stdio.c
>> index 4410262..b902acd 100644
>> --- a/src/xdr_stdio.c
>> +++ b/src/xdr_stdio.c
>> @@ -103,10 +103,12 @@ xdrstdio_getlong(xdrs, lp)
>> XDR *xdrs;
>> long *lp;
>> {
>> + int32_t mycopy;
>>=20
>> - if (fread(lp, sizeof(int32_t), 1, (FILE *)xdrs->x_private)
>> !=3D 1)
>> + if (fread(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs-
>>> x_private) !=3D 1)
>> return (FALSE);
>> - *lp =3D (long)ntohl((u_int32_t)*lp);
>> +
>> + *lp =3D (long)ntohl(mycopy);
>> return (TRUE);
>> }
>>=20
>> @@ -115,8 +117,14 @@ xdrstdio_putlong(xdrs, lp)
>> XDR *xdrs;
>> const long *lp;
>> {
>> - long mycopy =3D (long)htonl((u_int32_t)*lp);
>> + int32_t mycopy;
>> +
>> +#if defined(_LP64)
>> + if ((*lp > INT32_MAX) || (*lp < INT32_MIN))
>> + return (FALSE);
>=20
> The will work just fine if your cast is:
> int a;
>=20
> lp =3D (long)a;
>=20
> ...but it won't do the right thing for
>=20
> unsigned int b =3D UINT32_MAX;
>=20
> lp =3D (long)b; /* set lp to UINT32_MAX */

mycopy is an int32_t now. Does that help?


> Since there us no dedicated xdrstdio_putulong() to use for unsigned
> integers, we need the check to work for both cases.
> For that reason, I think the above check either has to be:
>=20
> if (*lp =3D=3D (long)((u_int32_t)*lp))
> return (FALSE);
>=20
> ...or something uglier like
>=20
> if (*lp > UINT32_MAX || *lp < INT32_MIN)
> return (FALSE);
>=20
>> +#endif
>>=20
>> + mycopy =3D (int32_t)htonl((int32_t)*lp);
>> if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs-
>>> x_private) !=3D 1)
>> return (FALSE);
>> return (TRUE);
> --=20
> Trond Myklebust
> CTO, Hammerspace Inc
> 4300 El Camino Real, Suite 105
> Los Altos, CA 94022
> http://www.hammer.space
>=20
> =
N=C2=8B=C2=A7=C4=93=C3=A6=C4=97r=C4=BC=C2=9By=C3=BA=C4=8D=C2=9A=C3=98b=C4=93=
X=C5=BD=C4=B7=C4=AE=C2=A7v=C3=98^=C2=96)=C3=9E=C5=A1{.n=C4=AE+=C2=89=C2=B7=
=C4=A8=C2=8A{=C4=85=C2=9D=C3=BB"=C2=9E=C3=98^n=C2=87r=C4=84=C3=B6=C4=B6z=C3=
=8B=1A=C2=81=C3=ABh=C2=99=C4=BB=C4=8D=C2=AD=C3=9A&=C4=92=C3=B8=1E=C5=AAG=C5=
=A6=C2=9D=C3=A9h=C5=AA=03(=C2=AD=C3=A9=C2=9A=C2=8E=C2=8A=C3=9D=C4=92j"=C2=9D=
=C3=BA=1A=C4=B7=1Bm=C2=A7=C4=B8=C3=AF=C2=81=C4=99=C3=A4z=C4=91=C3=9E=C2=96=
=C2=8A=C4=81=C3=BEf=C4=A2=C4=92=C2=B7h=C2=9A=C2=88=C2=A7~=C2=88m

--
Chuck Lever




2018-06-29 19:49:01

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH V2] xdrstdio_create buffers do not output encoded values on ppc

T24gRnJpLCAyMDE4LTA2LTI5IGF0IDE1OjMzIC0wNDAwLCBDaHVjayBMZXZlciB3cm90ZToNCj4g
PiBPbiBKdW4gMjksIDIwMTgsIGF0IDM6MjkgUE0sIFRyb25kIE15a2xlYnVzdCA8dHJvbmRteUBo
YW1tZXJzcGFjZS5jDQo+ID4gb20+IHdyb3RlOg0KPiA+IA0KPiA+IE9uIEZyaSwgMjAxOC0wNi0y
OSBhdCAxNDo0MiAtMDQwMCwgU3RldmUgRGlja3NvbiB3cm90ZToNCj4gPiA+IEZyb206IERhbmll
bCBTYW5kcyA8ZG5zYW5kc0BzYW5kaWEuZ292Pg0KPiA+ID4gDQo+ID4gPiBUaGUgY2F1c2UgaXMg
dGhhdCB0aGUgeGRyX3B1dGxvbmcgdXNlcyBhIGxvbmcgdG8gc3RvcmUgdGhlDQo+ID4gPiBjb252
ZXJ0ZWQgdmFsdWUsIHRoZW4gcGFzc2VzIGl0IHRvIGZ3cml0ZSBhcyBhIGJ5dGUgYnVmZmVyLg0K
PiA+ID4gT25seSB0aGUgZmlyc3QgNCBieXRlcyBhcmUgd3JpdHRlbiwgd2hpY2ggaXMgb2theSBm
b3IgYSBMRQ0KPiA+ID4gc3lzdGVtIGFmdGVyIGJ5dGVzd2FwcGluZywgYnV0IHdyaXRlcyBhbGwg
emVyb2VzIG9uIEJFIHN5c3RlbXMuDQo+ID4gPiANCj4gPiA+IEZpeGVzOiBodHRwczovL2J1Z3pp
bGxhLnJlZGhhdC5jb20vc2hvd19idWcuY2dpP2lkPTEyNjE3MzgNCj4gPiA+IA0KPiA+ID4gU2ln
bmVkLW9mZi1ieTogU3RldmUgRGlja3NvbiA8c3RldmVkQHJlZGhhdC5jb20+DQo+ID4gPiAtLS0N
Cj4gPiA+IHYyOiBBZGRlZCBib3VuZHMgY2hlY2tpbmcNCj4gPiA+ICAgIENoYW5nZWQgZnJvbSB1
bnNpZ25lZCB0byBzaWduZWQNCj4gPiA+IA0KPiA+ID4gc3JjL3hkcl9zdGRpby5jIHwgMTQgKysr
KysrKysrKystLS0NCj4gPiA+IDEgZmlsZSBjaGFuZ2VkLCAxMSBpbnNlcnRpb25zKCspLCAzIGRl
bGV0aW9ucygtKQ0KPiA+ID4gDQo+ID4gPiBkaWZmIC0tZ2l0IGEvc3JjL3hkcl9zdGRpby5jIGIv
c3JjL3hkcl9zdGRpby5jDQo+ID4gPiBpbmRleCA0NDEwMjYyLi5iOTAyYWNkIDEwMDY0NA0KPiA+
ID4gLS0tIGEvc3JjL3hkcl9zdGRpby5jDQo+ID4gPiArKysgYi9zcmMveGRyX3N0ZGlvLmMNCj4g
PiA+IEBAIC0xMDMsMTAgKzEwMywxMiBAQCB4ZHJzdGRpb19nZXRsb25nKHhkcnMsIGxwKQ0KPiA+
ID4gCVhEUiAqeGRyczsNCj4gPiA+IAlsb25nICpscDsNCj4gPiA+IHsNCj4gPiA+ICsJaW50MzJf
dCBteWNvcHk7DQo+ID4gPiANCj4gPiA+IC0JaWYgKGZyZWFkKGxwLCBzaXplb2YoaW50MzJfdCks
IDEsIChGSUxFICopeGRycy0NCj4gPiA+ID54X3ByaXZhdGUpDQo+ID4gPiAhPSAxKQ0KPiA+ID4g
KwlpZiAoZnJlYWQoJm15Y29weSwgc2l6ZW9mKGludDMyX3QpLCAxLCAoRklMRSAqKXhkcnMtDQo+
ID4gPiA+IHhfcHJpdmF0ZSkgIT0gMSkNCj4gPiA+IA0KPiA+ID4gCQlyZXR1cm4gKEZBTFNFKTsN
Cj4gPiA+IC0JKmxwID0gKGxvbmcpbnRvaGwoKHVfaW50MzJfdCkqbHApOw0KPiA+ID4gKw0KPiA+
ID4gKwkqbHAgPSAobG9uZyludG9obChteWNvcHkpOw0KPiA+ID4gCXJldHVybiAoVFJVRSk7DQo+
ID4gPiB9DQo+ID4gPiANCj4gPiA+IEBAIC0xMTUsOCArMTE3LDE0IEBAIHhkcnN0ZGlvX3B1dGxv
bmcoeGRycywgbHApDQo+ID4gPiAJWERSICp4ZHJzOw0KPiA+ID4gCWNvbnN0IGxvbmcgKmxwOw0K
PiA+ID4gew0KPiA+ID4gLQlsb25nIG15Y29weSA9IChsb25nKWh0b25sKCh1X2ludDMyX3QpKmxw
KTsNCj4gPiA+ICsJaW50MzJfdCBteWNvcHk7DQo+ID4gPiArDQo+ID4gPiArI2lmIGRlZmluZWQo
X0xQNjQpDQo+ID4gPiArCWlmICgoKmxwID4gSU5UMzJfTUFYKSB8fCAoKmxwIDwgSU5UMzJfTUlO
KSkNCj4gPiA+ICsJCXJldHVybiAoRkFMU0UpOw0KPiA+IA0KPiA+IFRoZSB3aWxsIHdvcmsganVz
dCBmaW5lIGlmIHlvdXIgY2FzdCBpczoNCj4gPiAJaW50IGE7DQo+ID4gDQo+ID4gCWxwID0gKGxv
bmcpYTsNCj4gPiANCj4gPiAuLi5idXQgaXQgd29uJ3QgZG8gdGhlIHJpZ2h0IHRoaW5nIGZvcg0K
PiA+IA0KPiA+IAl1bnNpZ25lZCBpbnQgYiA9IFVJTlQzMl9NQVg7DQo+ID4gDQo+ID4gCWxwID0g
KGxvbmcpYjsJLyogc2V0IGxwIHRvIFVJTlQzMl9NQVggKi8NCj4gDQo+IG15Y29weSBpcyBhbiBp
bnQzMl90IG5vdy4gRG9lcyB0aGF0IGhlbHA/DQoNCk5vdCByZWFsbHkuICdteWNvcHknIGlzbid0
IGludm9sdmVkIGluIHRoZSBjaGVjayBhYm92ZSwgYW5kICpscCA9PQ0KVUlOVDMyX01BWCBzaG91
bGQgaW4gZWl0aGVyIGNhc2UgZ2V0IGNhc3QgdG8gdGhlIHNhbWUgMzItYml0IGJpdA0KcGF0dGVy
biB3aGV0aGVyIG15Y29weSBpcyBhbiBpbnQzMl90IG9yIGEgdV9pbnQzMl90Lg0KDQpJdCdzIHdo
ZW4geW91IHRyeSB0byBjYXN0IGJhY2sgZnJvbSAnbXljb3B5JyB0byBhIGxvbmcgdHlwZSB0aGF0
IHRoZQ0KdHdvIGNhbiBlbmQgdXAgZGlmZmVyaW5nIChhbiBpbnQzMl90IG1pZ2h0IGdldCBzaWdu
IGV4dGVuZGVkKS4NCg0KPiANCj4gPiBTaW5jZSB0aGVyZSB1cyBubyBkZWRpY2F0ZWQgeGRyc3Rk
aW9fcHV0dWxvbmcoKSB0byB1c2UgZm9yIHVuc2lnbmVkDQo+ID4gaW50ZWdlcnMsIHdlIG5lZWQg
dGhlIGNoZWNrIHRvIHdvcmsgZm9yIGJvdGggY2FzZXMuDQo+ID4gRm9yIHRoYXQgcmVhc29uLCBJ
IHRoaW5rIHRoZSBhYm92ZSBjaGVjayBlaXRoZXIgaGFzIHRvIGJlOg0KPiA+IA0KPiA+IAlpZiAo
KmxwID09IChsb25nKSgodV9pbnQzMl90KSpscCkpDQo+ID4gCQlyZXR1cm4gKEZBTFNFKTsNCj4g
PiANCj4gPiAuLi5vciBzb21ldGhpbmcgdWdsaWVyIGxpa2UNCj4gPiANCj4gPiAJaWYgKCpscCA+
IFVJTlQzMl9NQVggfHwgKmxwIDwgSU5UMzJfTUlOKQ0KPiA+IAkJcmV0dXJuIChGQUxTRSk7DQo+
ID4gDQo+ID4gPiArI2VuZGlmDQo+ID4gPiANCj4gPiA+ICsJbXljb3B5ID0gKGludDMyX3QpaHRv
bmwoKGludDMyX3QpKmxwKTsNCj4gPiA+IAlpZiAoZndyaXRlKCZteWNvcHksIHNpemVvZihpbnQz
Ml90KSwgMSwgKEZJTEUgKil4ZHJzLQ0KPiA+ID4gPiB4X3ByaXZhdGUpICE9IDEpDQo+ID4gPiAN
Cj4gPiA+IAkJcmV0dXJuIChGQUxTRSk7DQo+ID4gPiAJcmV0dXJuIChUUlVFKTsNCj4gPiANCj4g
PiAtLSANCj4gPiBUcm9uZCBNeWtsZWJ1c3QNCj4gPiBDVE8sIEhhbW1lcnNwYWNlIEluYw0KPiA+
IDQzMDAgRWwgQ2FtaW5vIFJlYWwsIFN1aXRlIDEwNQ0KPiA+IExvcyBBbHRvcywgQ0EgOTQwMjIN
Cj4gPiB3d3cuaGFtbWVyLnNwYWNlDQo+ID4gDQo+ID4gTuKAucKnxJPDpsSXcsS84oC6ecO6xI3F
ocOYYsSTWMW9xLfErsKndsOYXuKAkynDnsWhey5uxK4r4oCwwrfEqMWge8SFwp3DuyLFvsOYXm7i
gKFyxITDtsS2esOLGsKBw6to4oSixLvEjcKtw5omxJLDuB7Fqg0KPiA+IEfFpsKdw6loxaoDKMKt
w6nFocW9xaDDncSSaiLCncO6GsS3G23Cp8S4w6/CgcSZw6R6xJHDnuKAk8WgxIHDvmbEosSSwrdo
xaHLhsKnfsuGbQ0KPiANCj4gLS0NCj4gQ2h1Y2sgTGV2ZXINCj4gDQo+IA0KPiANCi0tIA0KVHJv
bmQgTXlrbGVidXN0DQpMaW51eCBORlMgY2xpZW50IG1haW50YWluZXIsIEhhbW1lcnNwYWNlDQp0
cm9uZC5teWtsZWJ1c3RAaGFtbWVyc3BhY2UuY29tDQoNCg==

2018-06-29 20:02:44

by Chuck Lever III

[permalink] [raw]
Subject: Re: [PATCH V2] xdrstdio_create buffers do not output encoded values on ppc



> On Jun 29, 2018, at 3:48 PM, Trond Myklebust <[email protected]> =
wrote:
>=20
> On Fri, 2018-06-29 at 15:33 -0400, Chuck Lever wrote:
>>> On Jun 29, 2018, at 3:29 PM, Trond Myklebust <[email protected]
>>> om> wrote:
>>>=20
>>> On Fri, 2018-06-29 at 14:42 -0400, Steve Dickson wrote:
>>>> From: Daniel Sands <[email protected]>
>>>>=20
>>>> The cause is that the xdr_putlong uses a long to store the
>>>> converted value, then passes it to fwrite as a byte buffer.
>>>> Only the first 4 bytes are written, which is okay for a LE
>>>> system after byteswapping, but writes all zeroes on BE systems.
>>>>=20
>>>> Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=3D1261738
>>>>=20
>>>> Signed-off-by: Steve Dickson <[email protected]>
>>>> ---
>>>> v2: Added bounds checking
>>>> Changed from unsigned to signed
>>>>=20
>>>> src/xdr_stdio.c | 14 +++++++++++---
>>>> 1 file changed, 11 insertions(+), 3 deletions(-)
>>>>=20
>>>> diff --git a/src/xdr_stdio.c b/src/xdr_stdio.c
>>>> index 4410262..b902acd 100644
>>>> --- a/src/xdr_stdio.c
>>>> +++ b/src/xdr_stdio.c
>>>> @@ -103,10 +103,12 @@ xdrstdio_getlong(xdrs, lp)
>>>> XDR *xdrs;
>>>> long *lp;
>>>> {
>>>> + int32_t mycopy;
>>>>=20
>>>> - if (fread(lp, sizeof(int32_t), 1, (FILE *)xdrs-
>>>>> x_private)
>>>> !=3D 1)
>>>> + if (fread(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs-
>>>>> x_private) !=3D 1)
>>>>=20
>>>> return (FALSE);
>>>> - *lp =3D (long)ntohl((u_int32_t)*lp);
>>>> +
>>>> + *lp =3D (long)ntohl(mycopy);
>>>> return (TRUE);
>>>> }
>>>>=20
>>>> @@ -115,8 +117,14 @@ xdrstdio_putlong(xdrs, lp)
>>>> XDR *xdrs;
>>>> const long *lp;
>>>> {
>>>> - long mycopy =3D (long)htonl((u_int32_t)*lp);
>>>> + int32_t mycopy;
>>>> +
>>>> +#if defined(_LP64)
>>>> + if ((*lp > INT32_MAX) || (*lp < INT32_MIN))
>>>> + return (FALSE);
>>>=20
>>> The will work just fine if your cast is:
>>> int a;
>>>=20
>>> lp =3D (long)a;
>>>=20
>>> ...but it won't do the right thing for
>>>=20
>>> unsigned int b =3D UINT32_MAX;
>>>=20
>>> lp =3D (long)b; /* set lp to UINT32_MAX */
>>=20
>> mycopy is an int32_t now. Does that help?
>=20
> Not really. 'mycopy' isn't involved in the check above, and *lp =3D=3D
> UINT32_MAX should in either case get cast to the same 32-bit bit
> pattern whether mycopy is an int32_t or a u_int32_t.

> It's when you try to cast back from 'mycopy' to a long type that the
> two can end up differing (an int32_t might get sign extended).

AFAICT we are casting *lp to an int32_t in this function. mycopy
is not being cast to a long here.

Do you mean xdrstdio_GETlong needs further protection? Could be,
there is a cast of an int32_t to a long there.

I agree that we should vet xdrstdio_getlong and xdrstdio_putlong for
sign-extension issues very carefully.


>>> Since there us no dedicated xdrstdio_putulong() to use for unsigned
>>> integers, we need the check to work for both cases.
>>> For that reason, I think the above check either has to be:
>>>=20
>>> if (*lp =3D=3D (long)((u_int32_t)*lp))
>>> return (FALSE);
>>>=20
>>> ...or something uglier like
>>>=20
>>> if (*lp > UINT32_MAX || *lp < INT32_MIN)
>>> return (FALSE);
>>>=20
>>>> +#endif
>>>>=20
>>>> + mycopy =3D (int32_t)htonl((int32_t)*lp);
>>>> if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs-
>>>>> x_private) !=3D 1)
>>>>=20
>>>> return (FALSE);
>>>> return (TRUE);
>>>=20
>>> --=20
>>> Trond Myklebust
>>> CTO, Hammerspace Inc
>>> 4300 El Camino Real, Suite 105
>>> Los Altos, CA 94022
>>> http://www.hammer.space
>>>=20
>>> =
N=E2=80=B9=C2=A7=C4=93=C3=A6=C4=97r=C4=BC=E2=80=BAy=C3=BA=C4=8D=C5=A1=C3=98=
b=C4=93X=C5=BD=C4=B7=C4=AE=C2=A7v=C3=98^=E2=80=93)=C3=9E=C5=A1{.n=C4=AE+=E2=
=80=B0=C2=B7=C4=A8=C5=A0{=C4=85=C2=9D=C3=BB"=C5=BE=C3=98^n=E2=80=A1r=C4=84=
=C3=B6=C4=B6z=C3=8B=1A=C2=81=C3=ABh=E2=84=A2=C4=BB=C4=8D=C2=AD=C3=9A&=C4=92=
=C3=B8=1E=C5=AA
>>> =
G=C5=A6=C2=9D=C3=A9h=C5=AA=03(=C2=AD=C3=A9=C5=A1=C5=BD=C5=A0=C3=9D=C4=92j"=
=C2=9D=C3=BA=1A=C4=B7=1Bm=C2=A7=C4=B8=C3=AF=C2=81=C4=99=C3=A4z=C4=91=C3=9E=
=E2=80=93=C5=A0=C4=81=C3=BEf=C4=A2=C4=92=C2=B7h=C5=A1=CB=86=C2=A7~=CB=86m
>>=20
>> --
>> Chuck Lever
>>=20
>>=20
>>=20
> --=20
> Trond Myklebust
> Linux NFS client maintainer, Hammerspace
> [email protected]

--
Chuck Lever




2018-06-29 20:15:13

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH V2] xdrstdio_create buffers do not output encoded values on ppc

T24gRnJpLCAyMDE4LTA2LTI5IGF0IDE2OjAyIC0wNDAwLCBDaHVjayBMZXZlciB3cm90ZToNCj4g
PiBPbiBKdW4gMjksIDIwMTgsIGF0IDM6NDggUE0sIFRyb25kIE15a2xlYnVzdCA8dHJvbmRteUBo
YW1tZXJzcGFjZS5jDQo+ID4gb20+IHdyb3RlOg0KPiA+IA0KPiA+IE9uIEZyaSwgMjAxOC0wNi0y
OSBhdCAxNTozMyAtMDQwMCwgQ2h1Y2sgTGV2ZXIgd3JvdGU6DQo+ID4gPiA+IE9uIEp1biAyOSwg
MjAxOCwgYXQgMzoyOSBQTSwgVHJvbmQgTXlrbGVidXN0IDx0cm9uZG15QGhhbW1lcnNwYQ0KPiA+
ID4gPiBjZS5jDQo+ID4gPiA+IG9tPiB3cm90ZToNCj4gPiA+ID4gDQo+ID4gPiA+IE9uIEZyaSwg
MjAxOC0wNi0yOSBhdCAxNDo0MiAtMDQwMCwgU3RldmUgRGlja3NvbiB3cm90ZToNCj4gPiA+ID4g
PiBGcm9tOiBEYW5pZWwgU2FuZHMgPGRuc2FuZHNAc2FuZGlhLmdvdj4NCj4gPiA+ID4gPiANCj4g
PiA+ID4gPiBUaGUgY2F1c2UgaXMgdGhhdCB0aGUgeGRyX3B1dGxvbmcgdXNlcyBhIGxvbmcgdG8g
c3RvcmUgdGhlDQo+ID4gPiA+ID4gY29udmVydGVkIHZhbHVlLCB0aGVuIHBhc3NlcyBpdCB0byBm
d3JpdGUgYXMgYSBieXRlIGJ1ZmZlci4NCj4gPiA+ID4gPiBPbmx5IHRoZSBmaXJzdCA0IGJ5dGVz
IGFyZSB3cml0dGVuLCB3aGljaCBpcyBva2F5IGZvciBhIExFDQo+ID4gPiA+ID4gc3lzdGVtIGFm
dGVyIGJ5dGVzd2FwcGluZywgYnV0IHdyaXRlcyBhbGwgemVyb2VzIG9uIEJFDQo+ID4gPiA+ID4g
c3lzdGVtcy4NCj4gPiA+ID4gPiANCj4gPiA+ID4gPiBGaXhlczogaHR0cHM6Ly9idWd6aWxsYS5y
ZWRoYXQuY29tL3Nob3dfYnVnLmNnaT9pZD0xMjYxNzM4DQo+ID4gPiA+ID4gDQo+ID4gPiA+ID4g
U2lnbmVkLW9mZi1ieTogU3RldmUgRGlja3NvbiA8c3RldmVkQHJlZGhhdC5jb20+DQo+ID4gPiA+
ID4gLS0tDQo+ID4gPiA+ID4gdjI6IEFkZGVkIGJvdW5kcyBjaGVja2luZw0KPiA+ID4gPiA+ICAg
Q2hhbmdlZCBmcm9tIHVuc2lnbmVkIHRvIHNpZ25lZA0KPiA+ID4gPiA+IA0KPiA+ID4gPiA+IHNy
Yy94ZHJfc3RkaW8uYyB8IDE0ICsrKysrKysrKysrLS0tDQo+ID4gPiA+ID4gMSBmaWxlIGNoYW5n
ZWQsIDExIGluc2VydGlvbnMoKyksIDMgZGVsZXRpb25zKC0pDQo+ID4gPiA+ID4gDQo+ID4gPiA+
ID4gZGlmZiAtLWdpdCBhL3NyYy94ZHJfc3RkaW8uYyBiL3NyYy94ZHJfc3RkaW8uYw0KPiA+ID4g
PiA+IGluZGV4IDQ0MTAyNjIuLmI5MDJhY2QgMTAwNjQ0DQo+ID4gPiA+ID4gLS0tIGEvc3JjL3hk
cl9zdGRpby5jDQo+ID4gPiA+ID4gKysrIGIvc3JjL3hkcl9zdGRpby5jDQo+ID4gPiA+ID4gQEAg
LTEwMywxMCArMTAzLDEyIEBAIHhkcnN0ZGlvX2dldGxvbmcoeGRycywgbHApDQo+ID4gPiA+ID4g
CVhEUiAqeGRyczsNCj4gPiA+ID4gPiAJbG9uZyAqbHA7DQo+ID4gPiA+ID4gew0KPiA+ID4gPiA+
ICsJaW50MzJfdCBteWNvcHk7DQo+ID4gPiA+ID4gDQo+ID4gPiA+ID4gLQlpZiAoZnJlYWQobHAs
IHNpemVvZihpbnQzMl90KSwgMSwgKEZJTEUgKil4ZHJzLQ0KPiA+ID4gPiA+ID4geF9wcml2YXRl
KQ0KPiA+ID4gPiA+IA0KPiA+ID4gPiA+ICE9IDEpDQo+ID4gPiA+ID4gKwlpZiAoZnJlYWQoJm15
Y29weSwgc2l6ZW9mKGludDMyX3QpLCAxLCAoRklMRSAqKXhkcnMtDQo+ID4gPiA+ID4gPiB4X3By
aXZhdGUpICE9IDEpDQo+ID4gPiA+ID4gDQo+ID4gPiA+ID4gCQlyZXR1cm4gKEZBTFNFKTsNCj4g
PiA+ID4gPiAtCSpscCA9IChsb25nKW50b2hsKCh1X2ludDMyX3QpKmxwKTsNCj4gPiA+ID4gPiAr
DQo+ID4gPiA+ID4gKwkqbHAgPSAobG9uZyludG9obChteWNvcHkpOw0KPiA+ID4gPiA+IAlyZXR1
cm4gKFRSVUUpOw0KPiA+ID4gPiA+IH0NCj4gPiA+ID4gPiANCj4gPiA+ID4gPiBAQCAtMTE1LDgg
KzExNywxNCBAQCB4ZHJzdGRpb19wdXRsb25nKHhkcnMsIGxwKQ0KPiA+ID4gPiA+IAlYRFIgKnhk
cnM7DQo+ID4gPiA+ID4gCWNvbnN0IGxvbmcgKmxwOw0KPiA+ID4gPiA+IHsNCj4gPiA+ID4gPiAt
CWxvbmcgbXljb3B5ID0gKGxvbmcpaHRvbmwoKHVfaW50MzJfdCkqbHApOw0KPiA+ID4gPiA+ICsJ
aW50MzJfdCBteWNvcHk7DQo+ID4gPiA+ID4gKw0KPiA+ID4gPiA+ICsjaWYgZGVmaW5lZChfTFA2
NCkNCj4gPiA+ID4gPiArCWlmICgoKmxwID4gSU5UMzJfTUFYKSB8fCAoKmxwIDwgSU5UMzJfTUlO
KSkNCj4gPiA+ID4gPiArCQlyZXR1cm4gKEZBTFNFKTsNCj4gPiA+ID4gDQo+ID4gPiA+IFRoZSB3
aWxsIHdvcmsganVzdCBmaW5lIGlmIHlvdXIgY2FzdCBpczoNCj4gPiA+ID4gCWludCBhOw0KPiA+
ID4gPiANCj4gPiA+ID4gCWxwID0gKGxvbmcpYTsNCj4gPiA+ID4gDQo+ID4gPiA+IC4uLmJ1dCBp
dCB3b24ndCBkbyB0aGUgcmlnaHQgdGhpbmcgZm9yDQo+ID4gPiA+IA0KPiA+ID4gPiAJdW5zaWdu
ZWQgaW50IGIgPSBVSU5UMzJfTUFYOw0KPiA+ID4gPiANCj4gPiA+ID4gCWxwID0gKGxvbmcpYjsJ
Lyogc2V0IGxwIHRvIFVJTlQzMl9NQVggKi8NCj4gPiA+IA0KPiA+ID4gbXljb3B5IGlzIGFuIGlu
dDMyX3Qgbm93LiBEb2VzIHRoYXQgaGVscD8NCj4gPiANCj4gPiBOb3QgcmVhbGx5LiAnbXljb3B5
JyBpc24ndCBpbnZvbHZlZCBpbiB0aGUgY2hlY2sgYWJvdmUsIGFuZCAqbHAgPT0NCj4gPiBVSU5U
MzJfTUFYIHNob3VsZCBpbiBlaXRoZXIgY2FzZSBnZXQgY2FzdCB0byB0aGUgc2FtZSAzMi1iaXQg
Yml0DQo+ID4gcGF0dGVybiB3aGV0aGVyIG15Y29weSBpcyBhbiBpbnQzMl90IG9yIGEgdV9pbnQz
Ml90Lg0KPiA+IEl0J3Mgd2hlbiB5b3UgdHJ5IHRvIGNhc3QgYmFjayBmcm9tICdteWNvcHknIHRv
IGEgbG9uZyB0eXBlIHRoYXQNCj4gPiB0aGUNCj4gPiB0d28gY2FuIGVuZCB1cCBkaWZmZXJpbmcg
KGFuIGludDMyX3QgbWlnaHQgZ2V0IHNpZ24gZXh0ZW5kZWQpLg0KPiANCj4gQUZBSUNUIHdlIGFy
ZSBjYXN0aW5nICpscCB0byBhbiBpbnQzMl90IGluIHRoaXMgZnVuY3Rpb24uIG15Y29weQ0KPiBp
cyBub3QgYmVpbmcgY2FzdCB0byBhIGxvbmcgaGVyZS4NCj4gDQo+IERvIHlvdSBtZWFuIHhkcnN0
ZGlvX0dFVGxvbmcgbmVlZHMgZnVydGhlciBwcm90ZWN0aW9uPyBDb3VsZCBiZSwNCj4gdGhlcmUg
aXMgYSBjYXN0IG9mIGFuIGludDMyX3QgdG8gYSBsb25nIHRoZXJlLg0KPiANCj4gSSBhZ3JlZSB0
aGF0IHdlIHNob3VsZCB2ZXQgeGRyc3RkaW9fZ2V0bG9uZyBhbmQgeGRyc3RkaW9fcHV0bG9uZyBm
b3INCj4gc2lnbi1leHRlbnNpb24gaXNzdWVzIHZlcnkgY2FyZWZ1bGx5Lg0KPiANCg0KVGhlIHdv
cnJ5IGZvciB4ZHJzdGRpb19wdXRsb25nKCkgc2hvdWxkIGJlIGhvdyB3ZSBoYW5kbGUgdGhlIHRy
dW5jYXRpb24NCndoZW4gZ29pbmcgZnJvbSAobG9uZyktPiBiaWcgZW5kaWFuIChpbnQzMl90L3Vf
aW50MzJfdCkuIFdlIGRvbid0IHdhbnQNCnRvIHNpbGVudGx5IGxvc2UgaW5mb3JtYXRpb24uDQoN
CkFGQUlDUywgd2hlbiBjYXN0aW5nIGZyb20gYSAnbG9uZycgdHlwZSwgd2hldGhlciAnbXljb3B5
JyBpcyBzaWduZWQgb3INCnVuc2lnbmVkIGRvZXNuJ3QgcmVhbGx5IG1hdHRlciB3aGVuIGNvbnNp
ZGVyaW5nIHdoYXQgZW5kcyB1cCBnZXR0aW5nDQplbmNvZGVkLCBhcyBsb25nIGFzIGl0IGlzIG9m
IHNpemUgMzItYml0cy4gVGhlIGV4Y2VwdGlvbiB3b3VsZCBiZSBpZg0Kc2l6ZW9mKGxvbmcpIDwg
NCwgYnV0IGxpYnRpcnBjIGlzIGJyb2tlbiBmb3IgdGhhdCBjYXNlIGFueXdheS4uLg0KDQo+ID4g
PiA+IFNpbmNlIHRoZXJlIHVzIG5vIGRlZGljYXRlZCB4ZHJzdGRpb19wdXR1bG9uZygpIHRvIHVz
ZSBmb3INCj4gPiA+ID4gdW5zaWduZWQNCj4gPiA+ID4gaW50ZWdlcnMsIHdlIG5lZWQgdGhlIGNo
ZWNrIHRvIHdvcmsgZm9yIGJvdGggY2FzZXMuDQo+ID4gPiA+IEZvciB0aGF0IHJlYXNvbiwgSSB0
aGluayB0aGUgYWJvdmUgY2hlY2sgZWl0aGVyIGhhcyB0byBiZToNCj4gPiA+ID4gDQo+ID4gPiA+
IAlpZiAoKmxwID09IChsb25nKSgodV9pbnQzMl90KSpscCkpDQo+ID4gPiA+IAkJcmV0dXJuIChG
QUxTRSk7DQo+ID4gPiA+IA0KPiA+ID4gPiAuLi5vciBzb21ldGhpbmcgdWdsaWVyIGxpa2UNCj4g
PiA+ID4gDQo+ID4gPiA+IAlpZiAoKmxwID4gVUlOVDMyX01BWCB8fCAqbHAgPCBJTlQzMl9NSU4p
DQo+ID4gPiA+IAkJcmV0dXJuIChGQUxTRSk7DQo+ID4gPiA+IA0KPiA+ID4gPiA+ICsjZW5kaWYN
Cj4gPiA+ID4gPiANCj4gPiA+ID4gPiArCW15Y29weSA9IChpbnQzMl90KWh0b25sKChpbnQzMl90
KSpscCk7DQo+ID4gPiA+ID4gCWlmIChmd3JpdGUoJm15Y29weSwgc2l6ZW9mKGludDMyX3QpLCAx
LCAoRklMRSAqKXhkcnMtDQo+ID4gPiA+ID4gPiB4X3ByaXZhdGUpICE9IDEpDQo+ID4gPiA+ID4g
DQo+ID4gPiA+ID4gCQlyZXR1cm4gKEZBTFNFKTsNCj4gPiA+ID4gPiAJcmV0dXJuIChUUlVFKTsN
Cj4gPiA+ID4gDQo+ID4gPiA+IC0tIA0KPiA+ID4gPiBUcm9uZCBNeWtsZWJ1c3QNCj4gPiA+ID4g
Q1RPLCBIYW1tZXJzcGFjZSBJbmMNCj4gPiA+ID4gNDMwMCBFbCBDYW1pbm8gUmVhbCwgU3VpdGUg
MTA1DQo+ID4gPiA+IExvcyBBbHRvcywgQ0EgOTQwMjINCj4gPiA+ID4gd3d3LmhhbW1lci5zcGFj
ZQ0KPiA+ID4gPiANCj4gPiA+ID4gTuKAucKnxJPDpsSXcsS84oC6ecO6xI3FocOYYsSTWMW9xLfE
rsKndsOYXuKAkynDnsWhey5uxK4r4oCwwrfEqMWge8SFwp3DuyLFvsOYXm7igKFyxITDtsS2esOL
GsKBw6to4oSixLvEjcKtw5omDQo+ID4gPiA+IMSSw7gexaoNCj4gPiA+ID4gR8Wmwp3DqWjFqgMo
wq3DqcWhxb3FoMOdxJJqIsKdw7oaxLcbbcKnxLjDr8KBxJnDpHrEkcOe4oCTxaDEgcO+ZsSixJLC
t2jFocuGwqd+y4ZtDQo+ID4gPiANCj4gPiA+IC0tDQo+ID4gPiBDaHVjayBMZXZlcg0KPiA+ID4g
DQo+ID4gPiANCj4gPiA+IA0KPiA+IA0KPiA+IC0tIA0KPiA+IFRyb25kIE15a2xlYnVzdA0KPiA+
IExpbnV4IE5GUyBjbGllbnQgbWFpbnRhaW5lciwgSGFtbWVyc3BhY2UNCj4gPiB0cm9uZC5teWts
ZWJ1c3RAaGFtbWVyc3BhY2UuY29tDQo+IA0KPiAtLQ0KPiBDaHVjayBMZXZlcg0KPiANCj4gDQo+
IA0KLS0gDQpUcm9uZCBNeWtsZWJ1c3QNCkNUTywgSGFtbWVyc3BhY2UgSW5jDQo0MzAwIEVsIENh
bWlubyBSZWFsLCBTdWl0ZSAxMDUNCkxvcyBBbHRvcywgQ0EgOTQwMjINCnd3dy5oYW1tZXIuc3Bh
Y2UNCg0K

2018-06-29 20:41:20

by Chuck Lever III

[permalink] [raw]
Subject: Re: [PATCH V2] xdrstdio_create buffers do not output encoded values on ppc



> On Jun 29, 2018, at 4:15 PM, Trond Myklebust <[email protected]> =
wrote:
>=20
> On Fri, 2018-06-29 at 16:02 -0400, Chuck Lever wrote:
>>> On Jun 29, 2018, at 3:48 PM, Trond Myklebust <[email protected]
>>> om> wrote:
>>>=20
>>> On Fri, 2018-06-29 at 15:33 -0400, Chuck Lever wrote:
>>>>> On Jun 29, 2018, at 3:29 PM, Trond Myklebust <trondmy@hammerspa
>>>>> ce.c
>>>>> om> wrote:
>>>>>=20
>>>>> On Fri, 2018-06-29 at 14:42 -0400, Steve Dickson wrote:
>>>>>> From: Daniel Sands <[email protected]>
>>>>>>=20
>>>>>> The cause is that the xdr_putlong uses a long to store the
>>>>>> converted value, then passes it to fwrite as a byte buffer.
>>>>>> Only the first 4 bytes are written, which is okay for a LE
>>>>>> system after byteswapping, but writes all zeroes on BE
>>>>>> systems.
>>>>>>=20
>>>>>> Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=3D1261738
>>>>>>=20
>>>>>> Signed-off-by: Steve Dickson <[email protected]>
>>>>>> ---
>>>>>> v2: Added bounds checking
>>>>>> Changed from unsigned to signed
>>>>>>=20
>>>>>> src/xdr_stdio.c | 14 +++++++++++---
>>>>>> 1 file changed, 11 insertions(+), 3 deletions(-)
>>>>>>=20
>>>>>> diff --git a/src/xdr_stdio.c b/src/xdr_stdio.c
>>>>>> index 4410262..b902acd 100644
>>>>>> --- a/src/xdr_stdio.c
>>>>>> +++ b/src/xdr_stdio.c
>>>>>> @@ -103,10 +103,12 @@ xdrstdio_getlong(xdrs, lp)
>>>>>> XDR *xdrs;
>>>>>> long *lp;
>>>>>> {
>>>>>> + int32_t mycopy;
>>>>>>=20
>>>>>> - if (fread(lp, sizeof(int32_t), 1, (FILE *)xdrs-
>>>>>>> x_private)
>>>>>>=20
>>>>>> !=3D 1)
>>>>>> + if (fread(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs-
>>>>>>> x_private) !=3D 1)
>>>>>>=20
>>>>>> return (FALSE);
>>>>>> - *lp =3D (long)ntohl((u_int32_t)*lp);
>>>>>> +
>>>>>> + *lp =3D (long)ntohl(mycopy);
>>>>>> return (TRUE);
>>>>>> }
>>>>>>=20
>>>>>> @@ -115,8 +117,14 @@ xdrstdio_putlong(xdrs, lp)
>>>>>> XDR *xdrs;
>>>>>> const long *lp;
>>>>>> {
>>>>>> - long mycopy =3D (long)htonl((u_int32_t)*lp);
>>>>>> + int32_t mycopy;
>>>>>> +
>>>>>> +#if defined(_LP64)
>>>>>> + if ((*lp > INT32_MAX) || (*lp < INT32_MIN))
>>>>>> + return (FALSE);
>>>>>=20
>>>>> The will work just fine if your cast is:
>>>>> int a;
>>>>>=20
>>>>> lp =3D (long)a;
>>>>>=20
>>>>> ...but it won't do the right thing for
>>>>>=20
>>>>> unsigned int b =3D UINT32_MAX;
>>>>>=20
>>>>> lp =3D (long)b; /* set lp to UINT32_MAX */
>>>>=20
>>>> mycopy is an int32_t now. Does that help?
>>>=20
>>> Not really. 'mycopy' isn't involved in the check above, and *lp =3D=3D=

>>> UINT32_MAX should in either case get cast to the same 32-bit bit
>>> pattern whether mycopy is an int32_t or a u_int32_t.
>>> It's when you try to cast back from 'mycopy' to a long type that
>>> the
>>> two can end up differing (an int32_t might get sign extended).
>>=20
>> AFAICT we are casting *lp to an int32_t in this function. mycopy
>> is not being cast to a long here.
>>=20
>> Do you mean xdrstdio_GETlong needs further protection? Could be,
>> there is a cast of an int32_t to a long there.
>>=20
>> I agree that we should vet xdrstdio_getlong and xdrstdio_putlong for
>> sign-extension issues very carefully.
>>=20
>=20
> The worry for xdrstdio_putlong() should be how we handle the =
truncation
> when going from (long)-> big endian (int32_t/u_int32_t). We don't want
> to silently lose information.

To put it in terms of an API contract:

If the value in *lp cannot be expressed in 32 bits, xdrstdio_putlong
returns FALSE.


> AFAICS, when casting from a 'long' type, whether 'mycopy' is signed or
> unsigned doesn't really matter when considering what ends up getting
> encoded, as long as it is of size 32-bits. The exception would be if
> sizeof(long) < 4, but libtirpc is broken for that case anyway...
>=20
>>>>> Since there us no dedicated xdrstdio_putulong() to use for
>>>>> unsigned
>>>>> integers, we need the check to work for both cases.
>>>>> For that reason, I think the above check either has to be:
>>>>>=20
>>>>> if (*lp =3D=3D (long)((u_int32_t)*lp))
>>>>> return (FALSE);
>>>>>=20
>>>>> ...or something uglier like
>>>>>=20
>>>>> if (*lp > UINT32_MAX || *lp < INT32_MIN)
>>>>> return (FALSE);

On 32 bit systems, long ranges between INT32_MIN and INT32_MAX.
The more narrow range seems to me to be the most portable, as it
guarantees that this API works for exactly the same set of values on
both 32- and 64-bit systems.

Thus I would prefer to exclude the range between INT32_MAX and
UINT32_MAX.


>>>>>> +#endif
>>>>>>=20
>>>>>> + mycopy =3D (int32_t)htonl((int32_t)*lp);
>>>>>> if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs-
>>>>>>> x_private) !=3D 1)
>>>>>>=20
>>>>>> return (FALSE);
>>>>>> return (TRUE);
>>>>>=20
>>>>> --=20
>>>>> Trond Myklebust
>>>>> CTO, Hammerspace Inc
>>>>> 4300 El Camino Real, Suite 105
>>>>> Los Altos, CA 94022
>>>>> http://www.hammer.space
>>>>>=20
>>>>> =
N=E2=80=B9=C2=A7=C4=93=C3=A6=C4=97r=C4=BC=E2=80=BAy=C3=BA=C4=8D=C5=A1=C3=98=
b=C4=93X=C5=BD=C4=B7=C4=AE=C2=A7v=C3=98^=E2=80=93)=C3=9E=C5=A1{.n=C4=AE+=E2=
=80=B0=C2=B7=C4=A8=C5=A0{=C4=85=C2=9D=C3=BB"=C5=BE=C3=98^n=E2=80=A1r=C4=84=
=C3=B6=C4=B6z=C3=8B=1A=C2=81=C3=ABh=E2=84=A2=C4=BB=C4=8D=C2=AD=C3=9A&
>>>>> =C4=92=C3=B8=1E=C5=AA
>>>>> =
G=C5=A6=C2=9D=C3=A9h=C5=AA=03(=C2=AD=C3=A9=C5=A1=C5=BD=C5=A0=C3=9D=C4=92j"=
=C2=9D=C3=BA=1A=C4=B7=1Bm=C2=A7=C4=B8=C3=AF=C2=81=C4=99=C3=A4z=C4=91=C3=9E=
=E2=80=93=C5=A0=C4=81=C3=BEf=C4=A2=C4=92=C2=B7h=C5=A1=CB=86=C2=A7~=CB=86m
>>>>=20
>>>> --
>>>> Chuck Lever
>>>>=20
>>>>=20
>>>>=20
>>>=20
>>> --=20
>>> Trond Myklebust
>>> Linux NFS client maintainer, Hammerspace
>>> [email protected]
>>=20
>> --
>> Chuck Lever
>>=20
>>=20
>>=20
> --=20
> Trond Myklebust
> CTO, Hammerspace Inc
> 4300 El Camino Real, Suite 105
> Los Altos, CA 94022
> http://www.hammer.space

--
Chuck Lever




2018-06-29 20:58:46

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH V2] xdrstdio_create buffers do not output encoded values on ppc

T24gRnJpLCAyMDE4LTA2LTI5IGF0IDE2OjQwIC0wNDAwLCBDaHVjayBMZXZlciB3cm90ZToNCj4g
PiBPbiBKdW4gMjksIDIwMTgsIGF0IDQ6MTUgUE0sIFRyb25kIE15a2xlYnVzdCA8dHJvbmRteUBo
YW1tZXJzcGFjZS5jDQo+ID4gb20+IHdyb3RlOg0KPiA+IA0KPiA+IE9uIEZyaSwgMjAxOC0wNi0y
OSBhdCAxNjowMiAtMDQwMCwgQ2h1Y2sgTGV2ZXIgd3JvdGU6DQo+ID4gPiA+IE9uIEp1biAyOSwg
MjAxOCwgYXQgMzo0OCBQTSwgVHJvbmQgTXlrbGVidXN0IDx0cm9uZG15QGhhbW1lcnNwYQ0KPiA+
ID4gPiBjZS5jDQo+ID4gPiA+IG9tPiB3cm90ZToNCj4gPiA+ID4gDQo+ID4gPiA+IE9uIEZyaSwg
MjAxOC0wNi0yOSBhdCAxNTozMyAtMDQwMCwgQ2h1Y2sgTGV2ZXIgd3JvdGU6DQo+ID4gPiA+ID4g
PiBPbiBKdW4gMjksIDIwMTgsIGF0IDM6MjkgUE0sIFRyb25kIE15a2xlYnVzdCA8dHJvbmRteUBo
YW1tZQ0KPiA+ID4gPiA+ID4gcnNwYQ0KPiA+ID4gPiA+ID4gY2UuYw0KPiA+ID4gPiA+ID4gb20+
IHdyb3RlOg0KPiA+ID4gPiA+ID4gDQo+ID4gPiA+ID4gPiBPbiBGcmksIDIwMTgtMDYtMjkgYXQg
MTQ6NDIgLTA0MDAsIFN0ZXZlIERpY2tzb24gd3JvdGU6DQo+ID4gPiA+ID4gPiA+IEZyb206IERh
bmllbCBTYW5kcyA8ZG5zYW5kc0BzYW5kaWEuZ292Pg0KPiA+ID4gPiA+ID4gPiANCj4gPiA+ID4g
PiA+ID4gVGhlIGNhdXNlIGlzIHRoYXQgdGhlIHhkcl9wdXRsb25nIHVzZXMgYSBsb25nIHRvIHN0
b3JlDQo+ID4gPiA+ID4gPiA+IHRoZQ0KPiA+ID4gPiA+ID4gPiBjb252ZXJ0ZWQgdmFsdWUsIHRo
ZW4gcGFzc2VzIGl0IHRvIGZ3cml0ZSBhcyBhIGJ5dGUNCj4gPiA+ID4gPiA+ID4gYnVmZmVyLg0K
PiA+ID4gPiA+ID4gPiBPbmx5IHRoZSBmaXJzdCA0IGJ5dGVzIGFyZSB3cml0dGVuLCB3aGljaCBp
cyBva2F5IGZvciBhDQo+ID4gPiA+ID4gPiA+IExFDQo+ID4gPiA+ID4gPiA+IHN5c3RlbSBhZnRl
ciBieXRlc3dhcHBpbmcsIGJ1dCB3cml0ZXMgYWxsIHplcm9lcyBvbiBCRQ0KPiA+ID4gPiA+ID4g
PiBzeXN0ZW1zLg0KPiA+ID4gPiA+ID4gPiANCj4gPiA+ID4gPiA+ID4gRml4ZXM6IGh0dHBzOi8v
YnVnemlsbGEucmVkaGF0LmNvbS9zaG93X2J1Zy5jZ2k/aWQ9MTI2MTczDQo+ID4gPiA+ID4gPiA+
IDgNCj4gPiA+ID4gPiA+ID4gDQo+ID4gPiA+ID4gPiA+IFNpZ25lZC1vZmYtYnk6IFN0ZXZlIERp
Y2tzb24gPHN0ZXZlZEByZWRoYXQuY29tPg0KPiA+ID4gPiA+ID4gPiAtLS0NCj4gPiA+ID4gPiA+
ID4gdjI6IEFkZGVkIGJvdW5kcyBjaGVja2luZw0KPiA+ID4gPiA+ID4gPiAgQ2hhbmdlZCBmcm9t
IHVuc2lnbmVkIHRvIHNpZ25lZA0KPiA+ID4gPiA+ID4gPiANCj4gPiA+ID4gPiA+ID4gc3JjL3hk
cl9zdGRpby5jIHwgMTQgKysrKysrKysrKystLS0NCj4gPiA+ID4gPiA+ID4gMSBmaWxlIGNoYW5n
ZWQsIDExIGluc2VydGlvbnMoKyksIDMgZGVsZXRpb25zKC0pDQo+ID4gPiA+ID4gPiA+IA0KPiA+
ID4gPiA+ID4gPiBkaWZmIC0tZ2l0IGEvc3JjL3hkcl9zdGRpby5jIGIvc3JjL3hkcl9zdGRpby5j
DQo+ID4gPiA+ID4gPiA+IGluZGV4IDQ0MTAyNjIuLmI5MDJhY2QgMTAwNjQ0DQo+ID4gPiA+ID4g
PiA+IC0tLSBhL3NyYy94ZHJfc3RkaW8uYw0KPiA+ID4gPiA+ID4gPiArKysgYi9zcmMveGRyX3N0
ZGlvLmMNCj4gPiA+ID4gPiA+ID4gQEAgLTEwMywxMCArMTAzLDEyIEBAIHhkcnN0ZGlvX2dldGxv
bmcoeGRycywgbHApDQo+ID4gPiA+ID4gPiA+IAlYRFIgKnhkcnM7DQo+ID4gPiA+ID4gPiA+IAls
b25nICpscDsNCj4gPiA+ID4gPiA+ID4gew0KPiA+ID4gPiA+ID4gPiArCWludDMyX3QgbXljb3B5
Ow0KPiA+ID4gPiA+ID4gPiANCj4gPiA+ID4gPiA+ID4gLQlpZiAoZnJlYWQobHAsIHNpemVvZihp
bnQzMl90KSwgMSwgKEZJTEUgKil4ZHJzLQ0KPiA+ID4gPiA+ID4gPiA+IHhfcHJpdmF0ZSkNCj4g
PiA+ID4gPiA+ID4gDQo+ID4gPiA+ID4gPiA+ICE9IDEpDQo+ID4gPiA+ID4gPiA+ICsJaWYgKGZy
ZWFkKCZteWNvcHksIHNpemVvZihpbnQzMl90KSwgMSwgKEZJTEUNCj4gPiA+ID4gPiA+ID4gKil4
ZHJzLQ0KPiA+ID4gPiA+ID4gPiA+IHhfcHJpdmF0ZSkgIT0gMSkNCj4gPiA+ID4gPiA+ID4gDQo+
ID4gPiA+ID4gPiA+IAkJcmV0dXJuIChGQUxTRSk7DQo+ID4gPiA+ID4gPiA+IC0JKmxwID0gKGxv
bmcpbnRvaGwoKHVfaW50MzJfdCkqbHApOw0KPiA+ID4gPiA+ID4gPiArDQo+ID4gPiA+ID4gPiA+
ICsJKmxwID0gKGxvbmcpbnRvaGwobXljb3B5KTsNCj4gPiA+ID4gPiA+ID4gCXJldHVybiAoVFJV
RSk7DQo+ID4gPiA+ID4gPiA+IH0NCj4gPiA+ID4gPiA+ID4gDQo+ID4gPiA+ID4gPiA+IEBAIC0x
MTUsOCArMTE3LDE0IEBAIHhkcnN0ZGlvX3B1dGxvbmcoeGRycywgbHApDQo+ID4gPiA+ID4gPiA+
IAlYRFIgKnhkcnM7DQo+ID4gPiA+ID4gPiA+IAljb25zdCBsb25nICpscDsNCj4gPiA+ID4gPiA+
ID4gew0KPiA+ID4gPiA+ID4gPiAtCWxvbmcgbXljb3B5ID0gKGxvbmcpaHRvbmwoKHVfaW50MzJf
dCkqbHApOw0KPiA+ID4gPiA+ID4gPiArCWludDMyX3QgbXljb3B5Ow0KPiA+ID4gPiA+ID4gPiAr
DQo+ID4gPiA+ID4gPiA+ICsjaWYgZGVmaW5lZChfTFA2NCkNCj4gPiA+ID4gPiA+ID4gKwlpZiAo
KCpscCA+IElOVDMyX01BWCkgfHwgKCpscCA8IElOVDMyX01JTikpDQo+ID4gPiA+ID4gPiA+ICsJ
CXJldHVybiAoRkFMU0UpOw0KPiA+ID4gPiA+ID4gDQo+ID4gPiA+ID4gPiBUaGUgd2lsbCB3b3Jr
IGp1c3QgZmluZSBpZiB5b3VyIGNhc3QgaXM6DQo+ID4gPiA+ID4gPiAJaW50IGE7DQo+ID4gPiA+
ID4gPiANCj4gPiA+ID4gPiA+IAlscCA9IChsb25nKWE7DQo+ID4gPiA+ID4gPiANCj4gPiA+ID4g
PiA+IC4uLmJ1dCBpdCB3b24ndCBkbyB0aGUgcmlnaHQgdGhpbmcgZm9yDQo+ID4gPiA+ID4gPiAN
Cj4gPiA+ID4gPiA+IAl1bnNpZ25lZCBpbnQgYiA9IFVJTlQzMl9NQVg7DQo+ID4gPiA+ID4gPiAN
Cj4gPiA+ID4gPiA+IAlscCA9IChsb25nKWI7CS8qIHNldCBscCB0byBVSU5UMzJfTUFYICovDQo+
ID4gPiA+ID4gDQo+ID4gPiA+ID4gbXljb3B5IGlzIGFuIGludDMyX3Qgbm93LiBEb2VzIHRoYXQg
aGVscD8NCj4gPiA+ID4gDQo+ID4gPiA+IE5vdCByZWFsbHkuICdteWNvcHknIGlzbid0IGludm9s
dmVkIGluIHRoZSBjaGVjayBhYm92ZSwgYW5kICpscA0KPiA+ID4gPiA9PQ0KPiA+ID4gPiBVSU5U
MzJfTUFYIHNob3VsZCBpbiBlaXRoZXIgY2FzZSBnZXQgY2FzdCB0byB0aGUgc2FtZSAzMi1iaXQN
Cj4gPiA+ID4gYml0DQo+ID4gPiA+IHBhdHRlcm4gd2hldGhlciBteWNvcHkgaXMgYW4gaW50MzJf
dCBvciBhIHVfaW50MzJfdC4NCj4gPiA+ID4gSXQncyB3aGVuIHlvdSB0cnkgdG8gY2FzdCBiYWNr
IGZyb20gJ215Y29weScgdG8gYSBsb25nIHR5cGUNCj4gPiA+ID4gdGhhdA0KPiA+ID4gPiB0aGUN
Cj4gPiA+ID4gdHdvIGNhbiBlbmQgdXAgZGlmZmVyaW5nIChhbiBpbnQzMl90IG1pZ2h0IGdldCBz
aWduIGV4dGVuZGVkKS4NCj4gPiA+IA0KPiA+ID4gQUZBSUNUIHdlIGFyZSBjYXN0aW5nICpscCB0
byBhbiBpbnQzMl90IGluIHRoaXMgZnVuY3Rpb24uIG15Y29weQ0KPiA+ID4gaXMgbm90IGJlaW5n
IGNhc3QgdG8gYSBsb25nIGhlcmUuDQo+ID4gPiANCj4gPiA+IERvIHlvdSBtZWFuIHhkcnN0ZGlv
X0dFVGxvbmcgbmVlZHMgZnVydGhlciBwcm90ZWN0aW9uPyBDb3VsZCBiZSwNCj4gPiA+IHRoZXJl
IGlzIGEgY2FzdCBvZiBhbiBpbnQzMl90IHRvIGEgbG9uZyB0aGVyZS4NCj4gPiA+IA0KPiA+ID4g
SSBhZ3JlZSB0aGF0IHdlIHNob3VsZCB2ZXQgeGRyc3RkaW9fZ2V0bG9uZyBhbmQgeGRyc3RkaW9f
cHV0bG9uZw0KPiA+ID4gZm9yDQo+ID4gPiBzaWduLWV4dGVuc2lvbiBpc3N1ZXMgdmVyeSBjYXJl
ZnVsbHkuDQo+ID4gPiANCj4gPiANCj4gPiBUaGUgd29ycnkgZm9yIHhkcnN0ZGlvX3B1dGxvbmco
KSBzaG91bGQgYmUgaG93IHdlIGhhbmRsZSB0aGUNCj4gPiB0cnVuY2F0aW9uDQo+ID4gd2hlbiBn
b2luZyBmcm9tIChsb25nKS0+IGJpZyBlbmRpYW4gKGludDMyX3QvdV9pbnQzMl90KS4gV2UgZG9u
J3QNCj4gPiB3YW50DQo+ID4gdG8gc2lsZW50bHkgbG9zZSBpbmZvcm1hdGlvbi4NCj4gDQo+IFRv
IHB1dCBpdCBpbiB0ZXJtcyBvZiBhbiBBUEkgY29udHJhY3Q6DQo+IA0KPiBJZiB0aGUgdmFsdWUg
aW4gKmxwIGNhbm5vdCBiZSBleHByZXNzZWQgaW4gMzIgYml0cywgeGRyc3RkaW9fcHV0bG9uZw0K
PiByZXR1cm5zIEZBTFNFLg0KDQpBY2suLi4NCg0KPiANCj4gDQo+ID4gQUZBSUNTLCB3aGVuIGNh
c3RpbmcgZnJvbSBhICdsb25nJyB0eXBlLCB3aGV0aGVyICdteWNvcHknIGlzIHNpZ25lZA0KPiA+
IG9yDQo+ID4gdW5zaWduZWQgZG9lc24ndCByZWFsbHkgbWF0dGVyIHdoZW4gY29uc2lkZXJpbmcg
d2hhdCBlbmRzIHVwDQo+ID4gZ2V0dGluZw0KPiA+IGVuY29kZWQsIGFzIGxvbmcgYXMgaXQgaXMg
b2Ygc2l6ZSAzMi1iaXRzLiBUaGUgZXhjZXB0aW9uIHdvdWxkIGJlDQo+ID4gaWYNCj4gPiBzaXpl
b2YobG9uZykgPCA0LCBidXQgbGlidGlycGMgaXMgYnJva2VuIGZvciB0aGF0IGNhc2UgYW55d2F5
Li4uDQo+ID4gDQo+ID4gPiA+ID4gPiBTaW5jZSB0aGVyZSB1cyBubyBkZWRpY2F0ZWQgeGRyc3Rk
aW9fcHV0dWxvbmcoKSB0byB1c2UgZm9yDQo+ID4gPiA+ID4gPiB1bnNpZ25lZA0KPiA+ID4gPiA+
ID4gaW50ZWdlcnMsIHdlIG5lZWQgdGhlIGNoZWNrIHRvIHdvcmsgZm9yIGJvdGggY2FzZXMuDQo+
ID4gPiA+ID4gPiBGb3IgdGhhdCByZWFzb24sIEkgdGhpbmsgdGhlIGFib3ZlIGNoZWNrIGVpdGhl
ciBoYXMgdG8gYmU6DQo+ID4gPiA+ID4gPiANCj4gPiA+ID4gPiA+IAlpZiAoKmxwID09IChsb25n
KSgodV9pbnQzMl90KSpscCkpDQo+ID4gPiA+ID4gPiAJCXJldHVybiAoRkFMU0UpOw0KPiA+ID4g
PiA+ID4gDQo+ID4gPiA+ID4gPiAuLi5vciBzb21ldGhpbmcgdWdsaWVyIGxpa2UNCj4gPiA+ID4g
PiA+IA0KPiA+ID4gPiA+ID4gCWlmICgqbHAgPiBVSU5UMzJfTUFYIHx8ICpscCA8IElOVDMyX01J
TikNCj4gPiA+ID4gPiA+IAkJcmV0dXJuIChGQUxTRSk7DQo+IA0KPiBPbiAzMiBiaXQgc3lzdGVt
cywgbG9uZyByYW5nZXMgYmV0d2VlbiBJTlQzMl9NSU4gYW5kIElOVDMyX01BWC4NCj4gVGhlIG1v
cmUgbmFycm93IHJhbmdlIHNlZW1zIHRvIG1lIHRvIGJlIHRoZSBtb3N0IHBvcnRhYmxlLCBhcyBp
dA0KPiBndWFyYW50ZWVzIHRoYXQgdGhpcyBBUEkgd29ya3MgZm9yIGV4YWN0bHkgdGhlIHNhbWUg
c2V0IG9mIHZhbHVlcyBvbg0KPiBib3RoIDMyLSBhbmQgNjQtYml0IHN5c3RlbXMuDQo+IA0KPiBU
aHVzIEkgd291bGQgcHJlZmVyIHRvIGV4Y2x1ZGUgdGhlIHJhbmdlIGJldHdlZW4gSU5UMzJfTUFY
IGFuZA0KPiBVSU5UMzJfTUFYLg0KPiANCj4gDQo+ID4gPiA+ID4gPiA+ICsjZW5kaWYNCj4gPiA+
ID4gPiA+ID4gDQo+ID4gPiA+ID4gPiA+ICsJbXljb3B5ID0gKGludDMyX3QpaHRvbmwoKGludDMy
X3QpKmxwKTsNCj4gPiA+ID4gPiA+ID4gCWlmIChmd3JpdGUoJm15Y29weSwgc2l6ZW9mKGludDMy
X3QpLCAxLCAoRklMRSAqKXhkcnMtDQo+ID4gPiA+ID4gPiA+ID4geF9wcml2YXRlKSAhPSAxKQ0K
PiA+ID4gPiA+ID4gPiANCj4gPiA+ID4gPiA+ID4gCQlyZXR1cm4gKEZBTFNFKTsNCj4gPiA+ID4g
PiA+ID4gCXJldHVybiAoVFJVRSk7DQo+ID4gPiA+ID4gPiANCj4gPiA+ID4gPiA+IC0tIA0KPiA+
ID4gPiA+ID4gVHJvbmQgTXlrbGVidXN0DQo+ID4gPiA+ID4gPiBDVE8sIEhhbW1lcnNwYWNlIElu
Yw0KPiA+ID4gPiA+ID4gNDMwMCBFbCBDYW1pbm8gUmVhbCwgU3VpdGUgMTA1DQo+ID4gPiA+ID4g
PiBMb3MgQWx0b3MsIENBIDk0MDIyDQo+ID4gPiA+ID4gPiB3d3cuaGFtbWVyLnNwYWNlDQo+ID4g
PiA+ID4gPiANCj4gPiA+ID4gPiA+IE7igLnCp8STw6bEl3LEvOKAunnDusSNxaHDmGLEk1jFvcS3
xK7Cp3bDmF7igJMpw57FoXsubsSuK+KAsMK3xKjFoHvEhcKdw7sixb7DmF5u4oChcsSEw7bEtnrD
ixrCgcOraOKEosS7DQo+ID4gPiA+ID4gPiDEjcKtw5omDQo+ID4gPiA+ID4gPiDEksO4HsWqDQo+
ID4gPiA+ID4gPiBHxabCncOpaMWqAyjCrcOpxaHFvcWgw53Ekmoiwp3DuhrEtxttwqfEuMOvwoHE
mcOkesSRw57igJPFoMSBw75mxKLEksK3aMWhy4bCp37Lhm0NCj4gPiA+ID4gPiANCj4gPiA+ID4g
PiAtLQ0KPiA+ID4gPiA+IENodWNrIExldmVyDQo+ID4gPiA+ID4gDQo+ID4gPiA+ID4gDQo+ID4g
PiA+ID4gDQo+ID4gPiA+IA0KPiA+ID4gPiAtLSANCj4gPiA+ID4gVHJvbmQgTXlrbGVidXN0DQo+
ID4gPiA+IExpbnV4IE5GUyBjbGllbnQgbWFpbnRhaW5lciwgSGFtbWVyc3BhY2UNCj4gPiA+ID4g
dHJvbmQubXlrbGVidXN0QGhhbW1lcnNwYWNlLmNvbQ0KPiA+ID4gDQo+ID4gPiAtLQ0KPiA+ID4g
Q2h1Y2sgTGV2ZXINCj4gPiA+IA0KPiA+ID4gDQo+ID4gPiANCj4gPiANCj4gPiAtLSANCj4gPiBU
cm9uZCBNeWtsZWJ1c3QNCj4gPiBDVE8sIEhhbW1lcnNwYWNlIEluYw0KPiA+IDQzMDAgRWwgQ2Ft
aW5vIFJlYWwsIFN1aXRlIDEwNQ0KPiA+IExvcyBBbHRvcywgQ0EgOTQwMjINCj4gPiB3d3cuaGFt
bWVyLnNwYWNlDQo+IA0KPiAtLQ0KPiBDaHVjayBMZXZlcg0KPiANCj4gDQo+IA0KLS0gDQpUcm9u
ZCBNeWtsZWJ1c3QNCkNUTywgSGFtbWVyc3BhY2UgSW5jDQo0MzAwIEVsIENhbWlubyBSZWFsLCBT
dWl0ZSAxMDUNCkxvcyBBbHRvcywgQ0EgOTQwMjINCnd3dy5oYW1tZXIuc3BhY2UNCg0K