2012-09-06 19:54:32

by Weston Andros Adamson

[permalink] [raw]
Subject: [PATCH 1/2] NFS: return error from decode_getfh in decode open

If decode_getfh failed, nfs4_xdr_dec_open would return 0 since the last
decode_* call must have succeeded.

Cc: [email protected]
Signed-off-by: Weston Andros Adamson <[email protected]>
---
fs/nfs/nfs4xdr.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 1bfbd67..f505726 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -6229,7 +6229,8 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_open(xdr, res);
if (status)
goto out;
- if (decode_getfh(xdr, &res->fh) != 0)
+ status = decode_getfh(xdr, &res->fh);
+ if (status)
goto out;
decode_getfattr(xdr, res->f_attr, res->server);
out:
--
1.7.9.6 (Apple Git-31.1)



2012-09-06 19:54:34

by Weston Andros Adamson

[permalink] [raw]
Subject: [PATCH 2/2] NFSv4: Add ACCESS operation to OPEN compound

The OPEN operation has no way to differentiate an open for read and an
open for execution - both look like read to the server. This allowed
users to read files that didn't have READ access but did have EXEC access,
which is obviously wrong.

This patch adds an ACCESS call to the OPEN compound to handle the
difference between OPENs for reading and execution. Since we're going
through the trouble of calling ACCESS, we check all possible access bits
and cache the results hopefully avoiding an ACCESS call in the future.

Signed-off-by: Weston Andros Adamson <[email protected]>
---
fs/nfs/dir.c | 3 ++-
fs/nfs/nfs4proc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-
fs/nfs/nfs4xdr.c | 8 ++++++++
include/linux/nfs_fs.h | 1 +
include/linux/nfs_xdr.h | 18 +++++++++--------
5 files changed, 71 insertions(+), 10 deletions(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 627f108..92ae147 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2072,7 +2072,7 @@ found:
nfs_access_free_entry(entry);
}

-static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
+void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
{
struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL);
if (cache == NULL)
@@ -2098,6 +2098,7 @@ static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *s
spin_unlock(&nfs_access_lru_lock);
}
}
+EXPORT_SYMBOL_GPL(nfs_access_add_cache);

static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
{
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6352741..ba362d8 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -104,6 +104,8 @@ static int nfs4_map_errors(int err)
return -EACCES;
case -NFS4ERR_MINOR_VERS_MISMATCH:
return -EPROTONOSUPPORT;
+ case -NFS4ERR_ACCESS:
+ return -EACCES;
default:
dprintk("%s could not handle NFSv4 error %d\n",
__func__, -err);
@@ -860,6 +862,14 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
p->o_arg.fh = NFS_FH(dir);
p->o_arg.open_flags = flags;
p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
+ /* ask server to check for all possible rights as results are cached */
+ if (flags & O_DIRECTORY)
+ p->o_arg.access = NFS4_ACCESS_READ | NFS4_ACCESS_MODIFY |
+ NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE |
+ NFS4_ACCESS_LOOKUP;
+ else
+ p->o_arg.access = NFS4_ACCESS_READ | NFS4_ACCESS_MODIFY |
+ NFS4_ACCESS_EXTEND | NFS4_ACCESS_EXECUTE;
p->o_arg.clientid = server->nfs_client->cl_clientid;
p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time);
p->o_arg.id.uniquifier = sp->so_seqid.owner_id;
@@ -1643,6 +1653,41 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
return status;
}

+static int nfs4_opendata_access(struct rpc_cred *cred,
+ struct nfs4_opendata *opendata,
+ struct nfs4_state *state, fmode_t fmode)
+{
+ struct nfs_access_entry cache;
+ u32 mask = 0;
+ u32 a_res = opendata->o_res.access_res.access;
+
+ if (fmode & FMODE_READ)
+ mask |= MAY_READ;
+ if (fmode & FMODE_WRITE)
+ mask |= MAY_WRITE;
+ if (fmode & FMODE_EXEC)
+ mask |= MAY_EXEC;
+
+ cache.mask = 0;
+ cache.cred = cred;
+ cache.jiffies = jiffies;
+
+ if (a_res & NFS4_ACCESS_READ)
+ cache.mask |= MAY_READ;
+ if (a_res & (NFS4_ACCESS_MODIFY|NFS4_ACCESS_EXTEND|NFS4_ACCESS_DELETE))
+ cache.mask |= MAY_WRITE;
+ if (a_res & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
+ cache.mask |= MAY_EXEC;
+ nfs_access_add_cache(state->inode, &cache);
+
+ if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
+ return 0;
+
+ /* even though OPEN succeeded, access is denied. Close the file */
+ nfs4_close_state(state, fmode);
+ return -NFS4ERR_ACCESS;
+}
+
/*
* Note: On error, nfs4_proc_open will free the struct nfs4_opendata
*/
@@ -1896,6 +1941,10 @@ static int _nfs4_do_open(struct inode *dir,
if (server->caps & NFS_CAP_POSIX_LOCK)
set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);

+ status = nfs4_opendata_access(cred, opendata, state, fmode);
+ if (status != 0)
+ goto err_opendata_put;
+
if (opendata->o_arg.open_flags & O_EXCL) {
nfs4_exclusive_attrset(opendata, sattr);

@@ -1941,7 +1990,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
struct nfs4_state *res;
int status;

- fmode &= FMODE_READ|FMODE_WRITE;
+ fmode &= FMODE_READ|FMODE_WRITE|FMODE_EXEC;
do {
status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred,
&res, ctx_th);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index f505726..6d31888 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -2216,6 +2216,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_putfh(xdr, args->fh, &hdr);
encode_open(xdr, args, &hdr);
encode_getfh(xdr, &hdr);
+ encode_access(xdr, args->access, &hdr);
encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
encode_nops(&hdr);
}
@@ -2252,6 +2253,7 @@ static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req,
encode_sequence(xdr, &args->seq_args, &hdr);
encode_putfh(xdr, args->fh, &hdr);
encode_open(xdr, args, &hdr);
+ encode_access(xdr, args->access, &hdr);
encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
}
@@ -6232,6 +6234,9 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_getfh(xdr, &res->fh);
if (status)
goto out;
+ status = decode_access(xdr, &res->access_res);
+ if (status)
+ goto out;
decode_getfattr(xdr, res->f_attr, res->server);
out:
return status;
@@ -6280,6 +6285,9 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp,
status = decode_open(xdr, res);
if (status)
goto out;
+ status = decode_access(xdr, &res->access_res);
+ if (status)
+ goto out;
decode_getfattr(xdr, res->f_attr, res->server);
out:
return status;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 1f8fc7f..b944280 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -360,6 +360,7 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *);
extern int nfs_permission(struct inode *, int);
extern int nfs_open(struct inode *, struct file *);
extern int nfs_release(struct inode *, struct file *);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index ac7c8ae..c7435ae 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -335,6 +335,7 @@ struct nfs_openargs {
struct nfs_seqid * seqid;
int open_flags;
fmode_t fmode;
+ u32 access;
__u64 clientid;
struct stateowner_id id;
union {
@@ -353,6 +354,14 @@ struct nfs_openargs {
struct nfs4_sequence_args seq_args;
};

+struct nfs4_accessres {
+ const struct nfs_server *server;
+ struct nfs_fattr *fattr;
+ u32 supported;
+ u32 access;
+ struct nfs4_sequence_res seq_res;
+};
+
struct nfs_openres {
nfs4_stateid stateid;
struct nfs_fh fh;
@@ -369,6 +378,7 @@ struct nfs_openres {
struct nfs4_string *owner;
struct nfs4_string *group_owner;
struct nfs4_sequence_res seq_res;
+ struct nfs4_accessres access_res;
};

/*
@@ -835,14 +845,6 @@ struct nfs4_accessargs {
struct nfs4_sequence_args seq_args;
};

-struct nfs4_accessres {
- const struct nfs_server * server;
- struct nfs_fattr * fattr;
- u32 supported;
- u32 access;
- struct nfs4_sequence_res seq_res;
-};
-
struct nfs4_create_arg {
u32 ftype;
union {
--
1.7.9.6 (Apple Git-31.1)


2012-09-07 20:44:14

by Myklebust, Trond

[permalink] [raw]
Subject: Re: [PATCH 2/2] NFSv4: Add ACCESS operation to OPEN compound

SGkgRHJvcywNCg0KU2VlIGlubGluZWQgY29tbWVudHMuDQoNCk9uIFRodSwgMjAxMi0wOS0wNiBh
dCAxNTo1NCAtMDQwMCwgV2VzdG9uIEFuZHJvcyBBZGFtc29uIHdyb3RlOg0KPiBUaGUgT1BFTiBv
cGVyYXRpb24gaGFzIG5vIHdheSB0byBkaWZmZXJlbnRpYXRlIGFuIG9wZW4gZm9yIHJlYWQgYW5k
IGFuDQo+IG9wZW4gZm9yIGV4ZWN1dGlvbiAtIGJvdGggbG9vayBsaWtlIHJlYWQgdG8gdGhlIHNl
cnZlci4gVGhpcyBhbGxvd2VkDQo+IHVzZXJzIHRvIHJlYWQgZmlsZXMgdGhhdCBkaWRuJ3QgaGF2
ZSBSRUFEIGFjY2VzcyBidXQgZGlkIGhhdmUgRVhFQyBhY2Nlc3MsDQo+IHdoaWNoIGlzIG9idmlv
dXNseSB3cm9uZy4NCj4gDQo+IFRoaXMgcGF0Y2ggYWRkcyBhbiBBQ0NFU1MgY2FsbCB0byB0aGUg
T1BFTiBjb21wb3VuZCB0byBoYW5kbGUgdGhlDQo+IGRpZmZlcmVuY2UgYmV0d2VlbiBPUEVOcyBm
b3IgcmVhZGluZyBhbmQgZXhlY3V0aW9uLiAgU2luY2Ugd2UncmUgZ29pbmcNCj4gdGhyb3VnaCB0
aGUgdHJvdWJsZSBvZiBjYWxsaW5nIEFDQ0VTUywgd2UgY2hlY2sgYWxsIHBvc3NpYmxlIGFjY2Vz
cyBiaXRzDQo+IGFuZCBjYWNoZSB0aGUgcmVzdWx0cyBob3BlZnVsbHkgYXZvaWRpbmcgYW4gQUND
RVNTIGNhbGwgaW4gdGhlIGZ1dHVyZS4NCj4gDQo+IFNpZ25lZC1vZmYtYnk6IFdlc3RvbiBBbmRy
b3MgQWRhbXNvbiA8ZHJvc0BuZXRhcHAuY29tPg0KPiAtLS0NCj4gIGZzL25mcy9kaXIuYyAgICAg
ICAgICAgIHwgICAgMyArKy0NCj4gIGZzL25mcy9uZnM0cHJvYy5jICAgICAgIHwgICA1MSArKysr
KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLQ0KPiAgZnMvbmZzL25m
czR4ZHIuYyAgICAgICAgfCAgICA4ICsrKysrKysrDQo+ICBpbmNsdWRlL2xpbnV4L25mc19mcy5o
ICB8ICAgIDEgKw0KPiAgaW5jbHVkZS9saW51eC9uZnNfeGRyLmggfCAgIDE4ICsrKysrKysrKy0t
LS0tLS0tDQo+ICA1IGZpbGVzIGNoYW5nZWQsIDcxIGluc2VydGlvbnMoKyksIDEwIGRlbGV0aW9u
cygtKQ0KPiANCj4gZGlmZiAtLWdpdCBhL2ZzL25mcy9kaXIuYyBiL2ZzL25mcy9kaXIuYw0KPiBp
bmRleCA2MjdmMTA4Li45MmFlMTQ3IDEwMDY0NA0KPiAtLS0gYS9mcy9uZnMvZGlyLmMNCj4gKysr
IGIvZnMvbmZzL2Rpci5jDQo+IEBAIC0yMDcyLDcgKzIwNzIsNyBAQCBmb3VuZDoNCj4gIAluZnNf
YWNjZXNzX2ZyZWVfZW50cnkoZW50cnkpOw0KPiAgfQ0KPiAgDQo+IC1zdGF0aWMgdm9pZCBuZnNf
YWNjZXNzX2FkZF9jYWNoZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgbmZzX2FjY2Vzc19l
bnRyeSAqc2V0KQ0KPiArdm9pZCBuZnNfYWNjZXNzX2FkZF9jYWNoZShzdHJ1Y3QgaW5vZGUgKmlu
b2RlLCBzdHJ1Y3QgbmZzX2FjY2Vzc19lbnRyeSAqc2V0KQ0KPiAgew0KPiAgCXN0cnVjdCBuZnNf
YWNjZXNzX2VudHJ5ICpjYWNoZSA9IGttYWxsb2Moc2l6ZW9mKCpjYWNoZSksIEdGUF9LRVJORUwp
Ow0KPiAgCWlmIChjYWNoZSA9PSBOVUxMKQ0KPiBAQCAtMjA5OCw2ICsyMDk4LDcgQEAgc3RhdGlj
IHZvaWQgbmZzX2FjY2Vzc19hZGRfY2FjaGUoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IG5m
c19hY2Nlc3NfZW50cnkgKnMNCj4gIAkJc3Bpbl91bmxvY2soJm5mc19hY2Nlc3NfbHJ1X2xvY2sp
Ow0KPiAgCX0NCj4gIH0NCj4gK0VYUE9SVF9TWU1CT0xfR1BMKG5mc19hY2Nlc3NfYWRkX2NhY2hl
KTsNCj4gIA0KPiAgc3RhdGljIGludCBuZnNfZG9fYWNjZXNzKHN0cnVjdCBpbm9kZSAqaW5vZGUs
IHN0cnVjdCBycGNfY3JlZCAqY3JlZCwgaW50IG1hc2spDQo+ICB7DQo+IGRpZmYgLS1naXQgYS9m
cy9uZnMvbmZzNHByb2MuYyBiL2ZzL25mcy9uZnM0cHJvYy5jDQo+IGluZGV4IDYzNTI3NDEuLmJh
MzYyZDggMTAwNjQ0DQo+IC0tLSBhL2ZzL25mcy9uZnM0cHJvYy5jDQo+ICsrKyBiL2ZzL25mcy9u
ZnM0cHJvYy5jDQo+IEBAIC0xMDQsNiArMTA0LDggQEAgc3RhdGljIGludCBuZnM0X21hcF9lcnJv
cnMoaW50IGVycikNCj4gIAkJcmV0dXJuIC1FQUNDRVM7DQo+ICAJY2FzZSAtTkZTNEVSUl9NSU5P
Ul9WRVJTX01JU01BVENIOg0KPiAgCQlyZXR1cm4gLUVQUk9UT05PU1VQUE9SVDsNCj4gKwljYXNl
IC1ORlM0RVJSX0FDQ0VTUzoNCj4gKwkJcmV0dXJuIC1FQUNDRVM7DQo+ICAJZGVmYXVsdDoNCj4g
IAkJZHByaW50aygiJXMgY291bGQgbm90IGhhbmRsZSBORlN2NCBlcnJvciAlZFxuIiwNCj4gIAkJ
CQlfX2Z1bmNfXywgLWVycik7DQo+IEBAIC04NjAsNiArODYyLDE0IEBAIHN0YXRpYyBzdHJ1Y3Qg
bmZzNF9vcGVuZGF0YSAqbmZzNF9vcGVuZGF0YV9hbGxvYyhzdHJ1Y3QgZGVudHJ5ICpkZW50cnks
DQo+ICAJcC0+b19hcmcuZmggPSBORlNfRkgoZGlyKTsNCj4gIAlwLT5vX2FyZy5vcGVuX2ZsYWdz
ID0gZmxhZ3M7DQo+ICAJcC0+b19hcmcuZm1vZGUgPSBmbW9kZSAmIChGTU9ERV9SRUFEfEZNT0RF
X1dSSVRFKTsNCj4gKwkvKiBhc2sgc2VydmVyIHRvIGNoZWNrIGZvciBhbGwgcG9zc2libGUgcmln
aHRzIGFzIHJlc3VsdHMgYXJlIGNhY2hlZCAqLw0KPiArCWlmIChmbGFncyAmIE9fRElSRUNUT1JZ
KQ0KPiArCQlwLT5vX2FyZy5hY2Nlc3MgPSBORlM0X0FDQ0VTU19SRUFEIHwgTkZTNF9BQ0NFU1Nf
TU9ESUZZIHwNCj4gKwkJCQkgIE5GUzRfQUNDRVNTX0VYVEVORCB8IE5GUzRfQUNDRVNTX0RFTEVU
RSB8DQo+ICsJCQkJICBORlM0X0FDQ0VTU19MT09LVVA7DQoNCldlIHNob3VsZG4ndCBldmVyIGdl
dCBoZXJlIHdpdGggKGZsYWdzICYgT19ESVJFQ1RPUlkpLiBJZiB3ZSBkbywgdGhlbg0KdGhhdCB3
b3VsZCBiZSBhIGJ1ZyBpbiB0aGUgY2FsbGVycywgc2luY2UgTkZTdjQgZG9lc24ndCBzdXBwb3J0
IE9QRU4gb24NCmEgZGlyZWN0b3J5Lg0KDQo+ICsJZWxzZQ0KPiArCQlwLT5vX2FyZy5hY2Nlc3Mg
PSBORlM0X0FDQ0VTU19SRUFEIHwgTkZTNF9BQ0NFU1NfTU9ESUZZIHwNCj4gKwkJCQkgIE5GUzRf
QUNDRVNTX0VYVEVORCB8IE5GUzRfQUNDRVNTX0VYRUNVVEU7DQo+ICAJcC0+b19hcmcuY2xpZW50
aWQgPSBzZXJ2ZXItPm5mc19jbGllbnQtPmNsX2NsaWVudGlkOw0KPiAgCXAtPm9fYXJnLmlkLmNy
ZWF0ZV90aW1lID0ga3RpbWVfdG9fbnMoc3AtPnNvX3NlcWlkLmNyZWF0ZV90aW1lKTsNCj4gIAlw
LT5vX2FyZy5pZC51bmlxdWlmaWVyID0gc3AtPnNvX3NlcWlkLm93bmVyX2lkOw0KPiBAQCAtMTY0
Myw2ICsxNjUzLDQxIEBAIHN0YXRpYyBpbnQgX25mczRfcmVjb3Zlcl9wcm9jX29wZW4oc3RydWN0
IG5mczRfb3BlbmRhdGEgKmRhdGEpDQo+ICAJcmV0dXJuIHN0YXR1czsNCj4gIH0NCj4gIA0KPiAr
c3RhdGljIGludCBuZnM0X29wZW5kYXRhX2FjY2VzcyhzdHJ1Y3QgcnBjX2NyZWQgKmNyZWQsDQo+
ICsJCQkJc3RydWN0IG5mczRfb3BlbmRhdGEgKm9wZW5kYXRhLA0KPiArCQkJCXN0cnVjdCBuZnM0
X3N0YXRlICpzdGF0ZSwgZm1vZGVfdCBmbW9kZSkNCj4gK3sNCj4gKwlzdHJ1Y3QgbmZzX2FjY2Vz
c19lbnRyeSBjYWNoZTsNCj4gKwl1MzIgbWFzayA9IDA7DQo+ICsJdTMyIGFfcmVzID0gb3BlbmRh
dGEtPm9fcmVzLmFjY2Vzc19yZXMuYWNjZXNzOw0KPiArDQo+ICsJaWYgKGZtb2RlICYgRk1PREVf
UkVBRCkNCj4gKwkJbWFzayB8PSBNQVlfUkVBRDsNCj4gKwlpZiAoZm1vZGUgJiBGTU9ERV9XUklU
RSkNCj4gKwkJbWFzayB8PSBNQVlfV1JJVEU7DQo+ICsJaWYgKGZtb2RlICYgRk1PREVfRVhFQykN
Cj4gKwkJbWFzayB8PSBNQVlfRVhFQzsNCj4gKw0KPiArCWNhY2hlLm1hc2sgPSAwOw0KPiArCWNh
Y2hlLmNyZWQgPSBjcmVkOw0KPiArCWNhY2hlLmppZmZpZXMgPSBqaWZmaWVzOw0KPiArDQo+ICsJ
aWYgKGFfcmVzICYgTkZTNF9BQ0NFU1NfUkVBRCkNCj4gKwkJY2FjaGUubWFzayB8PSBNQVlfUkVB
RDsNCj4gKwlpZiAoYV9yZXMgJiAoTkZTNF9BQ0NFU1NfTU9ESUZZfE5GUzRfQUNDRVNTX0VYVEVO
RHxORlM0X0FDQ0VTU19ERUxFVEUpKQ0KPiArCQljYWNoZS5tYXNrIHw9IE1BWV9XUklURTsNCj4g
KwlpZiAoYV9yZXMgJiAoTkZTNF9BQ0NFU1NfTE9PS1VQfE5GUzRfQUNDRVNTX0VYRUNVVEUpKQ0K
PiArCQljYWNoZS5tYXNrIHw9IE1BWV9FWEVDOw0KDQpIbW0uLi4gV2Ugc2hvdWxkIGp1c3QgbWFr
ZSBhIGhlbHBlciBmb3IgdGhlIGFib3ZlIHNvIHRoYXQgd2UgY2FuIHNoYXJlDQp3aXRoIF9uZnM0
X3Byb2NfYWNjZXNzKCkuDQoNCj4gKwluZnNfYWNjZXNzX2FkZF9jYWNoZShzdGF0ZS0+aW5vZGUs
ICZjYWNoZSk7DQo+ICsNCj4gKwlpZiAoKG1hc2sgJiB+Y2FjaGUubWFzayAmIChNQVlfUkVBRCB8
IE1BWV9XUklURSB8IE1BWV9FWEVDKSkgPT0gMCkNCj4gKwkJcmV0dXJuIDA7DQo+ICsNCj4gKwkv
KiBldmVuIHRob3VnaCBPUEVOIHN1Y2NlZWRlZCwgYWNjZXNzIGlzIGRlbmllZC4gQ2xvc2UgdGhl
IGZpbGUgKi8NCj4gKwluZnM0X2Nsb3NlX3N0YXRlKHN0YXRlLCBmbW9kZSk7DQo+ICsJcmV0dXJu
IC1ORlM0RVJSX0FDQ0VTUzsNCj4gK30NCj4gKw0KPiAgLyoNCj4gICAqIE5vdGU6IE9uIGVycm9y
LCBuZnM0X3Byb2Nfb3BlbiB3aWxsIGZyZWUgdGhlIHN0cnVjdCBuZnM0X29wZW5kYXRhDQo+ICAg
Ki8NCj4gQEAgLTE4OTYsNiArMTk0MSwxMCBAQCBzdGF0aWMgaW50IF9uZnM0X2RvX29wZW4oc3Ry
dWN0IGlub2RlICpkaXIsDQo+ICAJaWYgKHNlcnZlci0+Y2FwcyAmIE5GU19DQVBfUE9TSVhfTE9D
SykNCj4gIAkJc2V0X2JpdChORlNfU1RBVEVfUE9TSVhfTE9DS1MsICZzdGF0ZS0+ZmxhZ3MpOw0K
PiAgDQo+ICsJc3RhdHVzID0gbmZzNF9vcGVuZGF0YV9hY2Nlc3MoY3JlZCwgb3BlbmRhdGEsIHN0
YXRlLCBmbW9kZSk7DQo+ICsJaWYgKHN0YXR1cyAhPSAwKQ0KPiArCQlnb3RvIGVycl9vcGVuZGF0
YV9wdXQ7DQo+ICsNCj4gIAlpZiAob3BlbmRhdGEtPm9fYXJnLm9wZW5fZmxhZ3MgJiBPX0VYQ0wp
IHsNCj4gIAkJbmZzNF9leGNsdXNpdmVfYXR0cnNldChvcGVuZGF0YSwgc2F0dHIpOw0KPiAgDQo+
IEBAIC0xOTQxLDcgKzE5OTAsNyBAQCBzdGF0aWMgc3RydWN0IG5mczRfc3RhdGUgKm5mczRfZG9f
b3BlbihzdHJ1Y3QgaW5vZGUgKmRpciwNCj4gIAlzdHJ1Y3QgbmZzNF9zdGF0ZSAqcmVzOw0KPiAg
CWludCBzdGF0dXM7DQo+ICANCj4gLQlmbW9kZSAmPSBGTU9ERV9SRUFEfEZNT0RFX1dSSVRFOw0K
PiArCWZtb2RlICY9IEZNT0RFX1JFQUR8Rk1PREVfV1JJVEV8Rk1PREVfRVhFQzsNCj4gIAlkbyB7
DQo+ICAJCXN0YXR1cyA9IF9uZnM0X2RvX29wZW4oZGlyLCBkZW50cnksIGZtb2RlLCBmbGFncywg
c2F0dHIsIGNyZWQsDQo+ICAJCQkJICAgICAgICZyZXMsIGN0eF90aCk7DQo+IGRpZmYgLS1naXQg
YS9mcy9uZnMvbmZzNHhkci5jIGIvZnMvbmZzL25mczR4ZHIuYw0KPiBpbmRleCBmNTA1NzI2Li42
ZDMxODg4IDEwMDY0NA0KPiAtLS0gYS9mcy9uZnMvbmZzNHhkci5jDQo+ICsrKyBiL2ZzL25mcy9u
ZnM0eGRyLmMNCg0KTWlzc2luZyB1cGRhdGVzIHRvIE5GUzRfZW5jX29wZW5fc3ogYW5kIE5GUzRf
ZGVjX29wZW5fc3oNCg0KPiBAQCAtMjIxNiw2ICsyMjE2LDcgQEAgc3RhdGljIHZvaWQgbmZzNF94
ZHJfZW5jX29wZW4oc3RydWN0IHJwY19ycXN0ICpyZXEsIHN0cnVjdCB4ZHJfc3RyZWFtICp4ZHIs
DQo+ICAJZW5jb2RlX3B1dGZoKHhkciwgYXJncy0+ZmgsICZoZHIpOw0KPiAgCWVuY29kZV9vcGVu
KHhkciwgYXJncywgJmhkcik7DQo+ICAJZW5jb2RlX2dldGZoKHhkciwgJmhkcik7DQo+ICsJZW5j
b2RlX2FjY2Vzcyh4ZHIsIGFyZ3MtPmFjY2VzcywgJmhkcik7DQo+ICAJZW5jb2RlX2dldGZhdHRy
X29wZW4oeGRyLCBhcmdzLT5iaXRtYXNrLCBhcmdzLT5vcGVuX2JpdG1hcCwgJmhkcik7DQo+ICAJ
ZW5jb2RlX25vcHMoJmhkcik7DQo+ICB9DQo+IEBAIC0yMjUyLDYgKzIyNTMsNyBAQCBzdGF0aWMg
dm9pZCBuZnM0X3hkcl9lbmNfb3Blbl9ub2F0dHIoc3RydWN0IHJwY19ycXN0ICpyZXEsDQo+ICAJ
ZW5jb2RlX3NlcXVlbmNlKHhkciwgJmFyZ3MtPnNlcV9hcmdzLCAmaGRyKTsNCj4gIAllbmNvZGVf
cHV0ZmgoeGRyLCBhcmdzLT5maCwgJmhkcik7DQo+ICAJZW5jb2RlX29wZW4oeGRyLCBhcmdzLCAm
aGRyKTsNCj4gKwllbmNvZGVfYWNjZXNzKHhkciwgYXJncy0+YWNjZXNzLCAmaGRyKTsNCj4gIAll
bmNvZGVfZ2V0ZmF0dHIoeGRyLCBhcmdzLT5iaXRtYXNrLCAmaGRyKTsNCj4gIAllbmNvZGVfbm9w
cygmaGRyKTsNCj4gIH0NCj4gQEAgLTYyMzIsNiArNjIzNCw5IEBAIHN0YXRpYyBpbnQgbmZzNF94
ZHJfZGVjX29wZW4oc3RydWN0IHJwY19ycXN0ICpycXN0cCwgc3RydWN0IHhkcl9zdHJlYW0gKnhk
ciwNCj4gIAlzdGF0dXMgPSBkZWNvZGVfZ2V0ZmgoeGRyLCAmcmVzLT5maCk7DQo+ICAJaWYgKHN0
YXR1cykNCj4gIAkJZ290byBvdXQ7DQo+ICsJc3RhdHVzID0gZGVjb2RlX2FjY2Vzcyh4ZHIsICZy
ZXMtPmFjY2Vzc19yZXMpOw0KPiArCWlmIChzdGF0dXMpDQo+ICsJCWdvdG8gb3V0Ow0KDQpUaGlz
IHdpbGwgY2F1c2UgdGhlIE9QRU4gdG8gZmFpbCBpZiB0aGUgYWNjZXNzIGNhbGwgZmFpbGVkLiBJ
ZiBzbywgdGhlDQpjYWxsZXJzIHdpbGwgZmFpbCB0byBDTE9TRSB0aGUgZmlsZSBzaW5jZSB0aGV5
IHdpbGwgYXNzdW1lIHRoYXQgdGhlDQphY3R1YWwgT1BFTiAob3IgR0VURkgpIGZhaWxlZC4uLg0K
DQpJIHRoaW5rIHdlIHNob3VsZCByYXRoZXIgdHJlYXQgdGhlIGFjY2VzcyBtb2RlcyBhcyBiZWlu
ZyBsaWtlIHRoZQ0KYXR0cmlidXRlczogaW5mb3JtYXRpb24gdGhhdCB3ZSBjYW4gZmlsbCBpbiBs
YXRlciBpZiB0aGlzIHBhcnRpY3VsYXINCm9wZXJhdGlvbiBmYWlscy4NCg0KPiAgCWRlY29kZV9n
ZXRmYXR0cih4ZHIsIHJlcy0+Zl9hdHRyLCByZXMtPnNlcnZlcik7DQo+ICBvdXQ6DQo+ICAJcmV0
dXJuIHN0YXR1czsNCj4gQEAgLTYyODAsNiArNjI4NSw5IEBAIHN0YXRpYyBpbnQgbmZzNF94ZHJf
ZGVjX29wZW5fbm9hdHRyKHN0cnVjdCBycGNfcnFzdCAqcnFzdHAsDQo+ICAJc3RhdHVzID0gZGVj
b2RlX29wZW4oeGRyLCByZXMpOw0KPiAgCWlmIChzdGF0dXMpDQo+ICAJCWdvdG8gb3V0Ow0KPiAr
CXN0YXR1cyA9IGRlY29kZV9hY2Nlc3MoeGRyLCAmcmVzLT5hY2Nlc3NfcmVzKTsNCj4gKwlpZiAo
c3RhdHVzKQ0KPiArCQlnb3RvIG91dDsNCg0KU2VlIGFib3ZlLg0KDQo+ICAJZGVjb2RlX2dldGZh
dHRyKHhkciwgcmVzLT5mX2F0dHIsIHJlcy0+c2VydmVyKTsNCj4gIG91dDoNCj4gIAlyZXR1cm4g
c3RhdHVzOw0KPiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51eC9uZnNfZnMuaCBiL2luY2x1ZGUv
bGludXgvbmZzX2ZzLmgNCj4gaW5kZXggMWY4ZmM3Zi4uYjk0NDI4MCAxMDA2NDQNCj4gLS0tIGEv
aW5jbHVkZS9saW51eC9uZnNfZnMuaA0KPiArKysgYi9pbmNsdWRlL2xpbnV4L25mc19mcy5oDQo+
IEBAIC0zNjAsNiArMzYwLDcgQEAgZXh0ZXJuIGludCBuZnNfcmVmcmVzaF9pbm9kZShzdHJ1Y3Qg
aW5vZGUgKiwgc3RydWN0IG5mc19mYXR0ciAqKTsNCj4gIGV4dGVybiBpbnQgbmZzX3Bvc3Rfb3Bf
dXBkYXRlX2lub2RlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBuZnNfZmF0dHIgKmZhdHRy
KTsNCj4gIGV4dGVybiBpbnQgbmZzX3Bvc3Rfb3BfdXBkYXRlX2lub2RlX2ZvcmNlX3djYyhzdHJ1
Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgbmZzX2ZhdHRyICpmYXR0cik7DQo+ICBleHRlcm4gaW50
IG5mc19nZXRhdHRyKHN0cnVjdCB2ZnNtb3VudCAqLCBzdHJ1Y3QgZGVudHJ5ICosIHN0cnVjdCBr
c3RhdCAqKTsNCj4gK2V4dGVybiB2b2lkIG5mc19hY2Nlc3NfYWRkX2NhY2hlKHN0cnVjdCBpbm9k
ZSAqLCBzdHJ1Y3QgbmZzX2FjY2Vzc19lbnRyeSAqKTsNCj4gIGV4dGVybiBpbnQgbmZzX3Blcm1p
c3Npb24oc3RydWN0IGlub2RlICosIGludCk7DQo+ICBleHRlcm4gaW50IG5mc19vcGVuKHN0cnVj
dCBpbm9kZSAqLCBzdHJ1Y3QgZmlsZSAqKTsNCj4gIGV4dGVybiBpbnQgbmZzX3JlbGVhc2Uoc3Ry
dWN0IGlub2RlICosIHN0cnVjdCBmaWxlICopOw0KPiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51
eC9uZnNfeGRyLmggYi9pbmNsdWRlL2xpbnV4L25mc194ZHIuaA0KPiBpbmRleCBhYzdjOGFlLi5j
NzQzNWFlIDEwMDY0NA0KPiAtLS0gYS9pbmNsdWRlL2xpbnV4L25mc194ZHIuaA0KPiArKysgYi9p
bmNsdWRlL2xpbnV4L25mc194ZHIuaA0KPiBAQCAtMzM1LDYgKzMzNSw3IEBAIHN0cnVjdCBuZnNf
b3BlbmFyZ3Mgew0KPiAgCXN0cnVjdCBuZnNfc2VxaWQgKglzZXFpZDsNCj4gIAlpbnQJCQlvcGVu
X2ZsYWdzOw0KPiAgCWZtb2RlX3QJCQlmbW9kZTsNCj4gKwl1MzIJCQlhY2Nlc3M7DQo+ICAJX191
NjQgICAgICAgICAgICAgICAgICAgY2xpZW50aWQ7DQo+ICAJc3RydWN0IHN0YXRlb3duZXJfaWQJ
aWQ7DQo+ICAJdW5pb24gew0KPiBAQCAtMzUzLDYgKzM1NCwxNCBAQCBzdHJ1Y3QgbmZzX29wZW5h
cmdzIHsNCj4gIAlzdHJ1Y3QgbmZzNF9zZXF1ZW5jZV9hcmdzCXNlcV9hcmdzOw0KPiAgfTsNCj4g
IA0KPiArc3RydWN0IG5mczRfYWNjZXNzcmVzIHsNCj4gKwljb25zdCBzdHJ1Y3QgbmZzX3NlcnZl
cgkJKnNlcnZlcjsNCj4gKwlzdHJ1Y3QgbmZzX2ZhdHRyCQkqZmF0dHI7DQo+ICsJdTMyCQkJCXN1
cHBvcnRlZDsNCj4gKwl1MzIJCQkJYWNjZXNzOw0KPiArCXN0cnVjdCBuZnM0X3NlcXVlbmNlX3Jl
cwlzZXFfcmVzOw0KPiArfTsNCg0KSG1tLi4uIEl0IHdvdWxkIGJlIG5pY2UgdG8gYXZvaWQgcGFj
a2luZyBhbGwgdGhlc2UgcmVkdW5kYW50IG5mc19zZXJ2ZXIsDQpuZnNfYXR0ciBhbmQgbmZzNF9z
ZXF1ZW5jZV9yZXMgZmllbGRzIGludG8gdGhlIHN0cnVjdCBuZnNfb3BlbnJlczoNCnBhcnRpY3Vs
YXJseSBzaW5jZSBtb3N0IG9mIHRoZW0gd2lsbCBuZXZlciBiZSBpbml0aWFsaXNlZC4NCg0KQ2Fu
IHdlIGluc3RlYWQgY2hhbmdlIHRoZSBwcm90b3R5cGUgZm9yIGRlY29kZV9hY2Nlc3MoKSB0byBz
b21ldGhpbmcNCmFsb25nIHRoZSBsaW5lcyBvZg0KDQpzdGF0aWMgaW50IGRlY29kZV9hY2Nlc3Mo
c3RydWN0IHhkcl9zdHJlYW0gKnhkciwgdTMyICpzdXBwb3J0ZWQsIHUzMiAqYWNjZXNzKTsNCg0K
PiArDQo+ICBzdHJ1Y3QgbmZzX29wZW5yZXMgew0KPiAgCW5mczRfc3RhdGVpZCAgICAgICAgICAg
IHN0YXRlaWQ7DQo+ICAJc3RydWN0IG5mc19maCAgICAgICAgICAgZmg7DQo+IEBAIC0zNjksNiAr
Mzc4LDcgQEAgc3RydWN0IG5mc19vcGVucmVzIHsNCj4gIAlzdHJ1Y3QgbmZzNF9zdHJpbmcJKm93
bmVyOw0KPiAgCXN0cnVjdCBuZnM0X3N0cmluZwkqZ3JvdXBfb3duZXI7DQo+ICAJc3RydWN0IG5m
czRfc2VxdWVuY2VfcmVzCXNlcV9yZXM7DQo+ICsJc3RydWN0IG5mczRfYWNjZXNzcmVzCWFjY2Vz
c19yZXM7DQo+ICB9Ow0KPiAgDQo+ICAvKg0KPiBAQCAtODM1LDE0ICs4NDUsNiBAQCBzdHJ1Y3Qg
bmZzNF9hY2Nlc3NhcmdzIHsNCj4gIAlzdHJ1Y3QgbmZzNF9zZXF1ZW5jZV9hcmdzCXNlcV9hcmdz
Ow0KPiAgfTsNCj4gIA0KPiAtc3RydWN0IG5mczRfYWNjZXNzcmVzIHsNCj4gLQljb25zdCBzdHJ1
Y3QgbmZzX3NlcnZlciAqCXNlcnZlcjsNCj4gLQlzdHJ1Y3QgbmZzX2ZhdHRyICoJCWZhdHRyOw0K
PiAtCXUzMgkJCQlzdXBwb3J0ZWQ7DQo+IC0JdTMyCQkJCWFjY2VzczsNCj4gLQlzdHJ1Y3QgbmZz
NF9zZXF1ZW5jZV9yZXMJc2VxX3JlczsNCj4gLX07DQo+IC0NCj4gIHN0cnVjdCBuZnM0X2NyZWF0
ZV9hcmcgew0KPiAgCXUzMgkJCQlmdHlwZTsNCj4gIAl1bmlvbiB7DQoNCi0tIA0KVHJvbmQgTXlr
bGVidXN0DQpMaW51eCBORlMgY2xpZW50IG1haW50YWluZXINCg0KTmV0QXBwDQpUcm9uZC5NeWts
ZWJ1c3RAbmV0YXBwLmNvbQ0Kd3d3Lm5ldGFwcC5jb20NCg0K