From b85c5f9339e20d3de9b1316217dadbea41ad537e Mon Sep 17 00:00:00 2001 From: Benjamin Kaduk Date: Sun, 13 Mar 2016 12:56:24 -0500 Subject: [PATCH 1/1] OPENAFS-SA-2016-002 AFSStoreStatus information leak Marc Dionne reported that portions of the AFSStoreStatus structure were not written to before being sent over the network for operations such as create, symlink, etc., leaking the contents of the kernel stack to observers. Which fields in the request are used are controlled by a flags field, and so if a field was not going to be used by the server, it was sometimes left uninitialized. Fix the information leak by zeroing out the structure before use. FIXES 132847 Change-Id: I84a5a10442732ebbcb5d5067ca22030fb795168b --- src/WINNT/afsd/cm_dcache.c | 1 + src/afs/VNOPS/afs_vnop_attrs.c | 3 +++ src/afs/VNOPS/afs_vnop_create.c | 1 + src/afs/VNOPS/afs_vnop_dirops.c | 1 + src/afs/VNOPS/afs_vnop_symlink.c | 1 + src/afs/afs_disconnected.c | 1 + src/afs/afs_segments.c | 1 + src/libafscp/afscp_file.c | 1 + src/venus/afsio.c | 1 + 9 files changed, 11 insertions(+) diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 6da6153..cd73158 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -460,6 +460,7 @@ long cm_StoreMini(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) int call_was_64bit = 0; memset(&volSync, 0, sizeof(volSync)); + memset(&inStatus, 0, sizeof(inStatus); osi_Log2(afsd_logp, "cm_StoreMini scp 0x%p userp 0x%p", scp, userp); diff --git a/src/afs/VNOPS/afs_vnop_attrs.c b/src/afs/VNOPS/afs_vnop_attrs.c index cc1fd32..3b065fd 100644 --- a/src/afs/VNOPS/afs_vnop_attrs.c +++ b/src/afs/VNOPS/afs_vnop_attrs.c @@ -358,6 +358,7 @@ afs_VAttrToAS(struct vcache *avc, struct vattr *av, { int mask; mask = 0; + AFS_STATCNT(afs_VAttrToAS); #if defined(AFS_DARWIN80_ENV) if (VATTR_IS_ACTIVE(av, va_mode)) { @@ -483,6 +484,8 @@ afs_setattr(OSI_VC_DECL(avc), struct vattr *attrs, if ((code = afs_CreateReq(&treq, acred))) return code; + memset(&astat, 0, sizeof(astat)); + AFS_DISCON_LOCK(); afs_InitFakeStat(&fakestate); diff --git a/src/afs/VNOPS/afs_vnop_create.c b/src/afs/VNOPS/afs_vnop_create.c index 5f8819f..a2d600d 100644 --- a/src/afs/VNOPS/afs_vnop_create.c +++ b/src/afs/VNOPS/afs_vnop_create.c @@ -64,6 +64,7 @@ afs_create(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, OutFidStatus = osi_AllocSmallSpace(sizeof(struct AFSFetchStatus)); OutDirStatus = osi_AllocSmallSpace(sizeof(struct AFSFetchStatus)); + memset(&InStatus, 0, sizeof(InStatus)); if ((code = afs_CreateReq(&treq, acred))) goto done2; diff --git a/src/afs/VNOPS/afs_vnop_dirops.c b/src/afs/VNOPS/afs_vnop_dirops.c index 9365563..d1d2ab2 100644 --- a/src/afs/VNOPS/afs_vnop_dirops.c +++ b/src/afs/VNOPS/afs_vnop_dirops.c @@ -61,6 +61,7 @@ afs_mkdir(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, OutFidStatus = osi_AllocSmallSpace(sizeof(struct AFSFetchStatus)); OutDirStatus = osi_AllocSmallSpace(sizeof(struct AFSFetchStatus)); + memset(&InStatus, 0, sizeof(InStatus)); if ((code = afs_CreateReq(&treq, acred))) goto done2; diff --git a/src/afs/VNOPS/afs_vnop_symlink.c b/src/afs/VNOPS/afs_vnop_symlink.c index 14026ef..f608b2b 100644 --- a/src/afs/VNOPS/afs_vnop_symlink.c +++ b/src/afs/VNOPS/afs_vnop_symlink.c @@ -94,6 +94,7 @@ afs_symlink(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, OutFidStatus = osi_AllocSmallSpace(sizeof(struct AFSFetchStatus)); OutDirStatus = osi_AllocSmallSpace(sizeof(struct AFSFetchStatus)); + memset(&InStatus, 0, sizeof(InStatus)); if ((code = afs_CreateReq(&treq, acred))) goto done2; diff --git a/src/afs/afs_disconnected.c b/src/afs/afs_disconnected.c index 62712b9..a83d076 100644 --- a/src/afs/afs_disconnected.c +++ b/src/afs/afs_disconnected.c @@ -671,6 +671,7 @@ afs_ProcessOpCreate(struct vcache *avc, struct vrequest *areq, tname = afs_osi_Alloc(AFSNAMEMAX); if (!tname) return ENOMEM; + memset(&InStatus, 0, sizeof(InStatus)); code = afs_GetParentVCache(avc, 0, &pdir_fid, tname, &tdp); if (code) diff --git a/src/afs/afs_segments.c b/src/afs/afs_segments.c index c921746..69f7445 100644 --- a/src/afs/afs_segments.c +++ b/src/afs/afs_segments.c @@ -55,6 +55,7 @@ afs_StoreMini(struct vcache *avc, struct vrequest *areq) tlen = avc->f.truncPos; avc->f.truncPos = AFS_NOTRUNC; avc->f.states &= ~CExtendedFile; + memset(&InStatus, 0, sizeof(InStatus)); do { tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn); diff --git a/src/libafscp/afscp_file.c b/src/libafscp/afscp_file.c index 8bc3ed4..767099e 100644 --- a/src/libafscp/afscp_file.c +++ b/src/libafscp/afscp_file.c @@ -126,6 +126,7 @@ afscp_PWrite(const struct afscp_venusfid * fid, const void *buffer, off_t filesize; time_t now; + memset(&sst, 0, sizeof(sst)); vol = afscp_VolumeById(fid->cell, fid->fid.Volume); if (vol == NULL) { afscp_errno = ENOENT; diff --git a/src/venus/afsio.c b/src/venus/afsio.c index 9e3b1e5..c9b04f2 100644 --- a/src/venus/afsio.c +++ b/src/venus/afsio.c @@ -882,6 +882,7 @@ writeFile(struct cmd_syndesc *as, void *unused) /* stdin on Windows defaults to _O_TEXT mode */ _setmode(0, _O_BINARY); #endif + memset(&InStatus, 0, sizeof(InStatus)); CmdProlog(as, &cell, &realm, &fname, &sSynthLen); afscp_AnonymousAuth(1); -- 1.9.4