aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorKinglong Mee <kinglongmee@gmail.com>2013-12-31 11:35:47 -0500
committerJ. Bruce Fields <bfields@redhat.com>2014-01-06 15:33:54 -0500
commit60810e5489dffd0bd12e4f99fe9fc330c9a636e1 (patch)
tree74bb2c76dfd59abd388551c63f406bce04e6f224 /fs/nfsd/nfs4state.c
parent0fdc26785d0a5bb33d9adb572307fd2d7a406734 (diff)
NFSD: Fix a memory leak in nfsd4_create_session
If failed after calling alloc_session but before init_session, nfsd will call __free_session to free se_slots in session. But, session->se_fchannel.maxreqs is not initialized (value is zero). So that, the memory malloced for slots will be lost in free_session_slots for maxreqs is zero. This path sets the information for channel in alloc_session after mallocing slots succeed, instead in init_session. Signed-off-by: Kinglong Mee <kinglongmee@gmail.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index acb95026ae3b..5795d5f58f41 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -832,10 +832,11 @@ static void nfsd4_put_drc_mem(struct nfsd4_channel_attrs *ca)
832 spin_unlock(&nfsd_drc_lock); 832 spin_unlock(&nfsd_drc_lock);
833} 833}
834 834
835static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *attrs) 835static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs,
836 struct nfsd4_channel_attrs *battrs)
836{ 837{
837 int numslots = attrs->maxreqs; 838 int numslots = fattrs->maxreqs;
838 int slotsize = slot_bytes(attrs); 839 int slotsize = slot_bytes(fattrs);
839 struct nfsd4_session *new; 840 struct nfsd4_session *new;
840 int mem, i; 841 int mem, i;
841 842
@@ -852,6 +853,10 @@ static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *attrs)
852 if (!new->se_slots[i]) 853 if (!new->se_slots[i])
853 goto out_free; 854 goto out_free;
854 } 855 }
856
857 memcpy(&new->se_fchannel, fattrs, sizeof(struct nfsd4_channel_attrs));
858 memcpy(&new->se_bchannel, battrs, sizeof(struct nfsd4_channel_attrs));
859
855 return new; 860 return new;
856out_free: 861out_free:
857 while (i--) 862 while (i--)
@@ -997,10 +1002,7 @@ static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, stru
997 list_add(&new->se_perclnt, &clp->cl_sessions); 1002 list_add(&new->se_perclnt, &clp->cl_sessions);
998 spin_unlock(&clp->cl_lock); 1003 spin_unlock(&clp->cl_lock);
999 spin_unlock(&nn->client_lock); 1004 spin_unlock(&nn->client_lock);
1000 memcpy(&new->se_fchannel, &cses->fore_channel, 1005
1001 sizeof(struct nfsd4_channel_attrs));
1002 memcpy(&new->se_bchannel, &cses->back_channel,
1003 sizeof(struct nfsd4_channel_attrs));
1004 if (cses->flags & SESSION4_BACK_CHAN) { 1006 if (cses->flags & SESSION4_BACK_CHAN) {
1005 struct sockaddr *sa = svc_addr(rqstp); 1007 struct sockaddr *sa = svc_addr(rqstp);
1006 /* 1008 /*
@@ -1922,7 +1924,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1922 if (status) 1924 if (status)
1923 goto out_release_drc_mem; 1925 goto out_release_drc_mem;
1924 status = nfserr_jukebox; 1926 status = nfserr_jukebox;
1925 new = alloc_session(&cr_ses->fore_channel); 1927 new = alloc_session(&cr_ses->fore_channel, &cr_ses->back_channel);
1926 if (!new) 1928 if (!new)
1927 goto out_release_drc_mem; 1929 goto out_release_drc_mem;
1928 conn = alloc_conn_from_crses(rqstp, cr_ses); 1930 conn = alloc_conn_from_crses(rqstp, cr_ses);