From patchwork Wed Dec 2 14:59:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andy Whitcroft X-Patchwork-Id: 551398 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 8855E140306; Thu, 3 Dec 2015 02:00:09 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1a48t5-000114-AB; Wed, 02 Dec 2015 15:00:07 +0000 Received: from mail-wm0-f54.google.com ([74.125.82.54]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1a48sq-0000ty-7k for kernel-team@lists.ubuntu.com; Wed, 02 Dec 2015 14:59:52 +0000 Received: by wmec201 with SMTP id c201so61698101wme.1 for ; Wed, 02 Dec 2015 06:59:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; bh=QFT6FbZbGwQ/So0TpDnXuM5LVYemzPAWROEBGwlXTSk=; b=ajw7O6t38zuEGbs/tyPNEkH7kmJ9ZQFxjjpbcDL1kYvDlCVtkT07jJn+zVOmH28g84 VN97vImz99MS2qxpE0dOTwi/FJTRPEWdHhChKX4N90e3xFLPc3CnPKiMt3shdJWR6Lhd DCcWDZ4uEfBN+i+ybUeXYOLBvkV2mc0+pIe8593lPFa9xH4fPEQDkV84lxkSlrK39pO6 JOokHkyCJDCckEIeJsmm3ESiU9GGzGxS73sXF5owBv6CuKrOElMdVR3pU/rDNeki/Jdk NC2agTCkmFLZsRcjrc1pWvhQh5jixwftY6TwjTIGXxB2uwxejkJfG6WLO+Amez+iYcPj zL0g== X-Gm-Message-State: ALoCoQkxURSaDBs1pPAzSPhIWfSaR2xfvyJgtAvNeNg4fPmAUWd+4u7+1ugySyGx7sK9WkB/kFx2 X-Received: by 10.194.63.46 with SMTP id d14mr5264749wjs.34.1449068392080; Wed, 02 Dec 2015 06:59:52 -0800 (PST) Received: from localhost ([2001:470:6973:2:55ab:1437:1293:1d55]) by smtp.gmail.com with ESMTPSA id bg10sm3123247wjb.46.2015.12.02.06.59.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Dec 2015 06:59:51 -0800 (PST) From: Andy Whitcroft To: kernel-team@lists.ubuntu.com Subject: [wily/master-next 7/7] ppp, slip: Validate VJ compression slot parameters completely Date: Wed, 2 Dec 2015 14:59:37 +0000 Message-Id: <1449068377-21867-8-git-send-email-apw@canonical.com> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1449068377-21867-1-git-send-email-apw@canonical.com> References: <1449068377-21867-1-git-send-email-apw@canonical.com> MIME-Version: 1.0 Cc: Andy Whitcroft X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: Ben Hutchings Currently slhc_init() treats out-of-range values of rslots and tslots as equivalent to 0, except that if tslots is too large it will dereference a null pointer (CVE-2015-7799). Add a range-check at the top of the function and make it return an ERR_PTR() on error instead of NULL. Change the callers accordingly. Compile-tested only. Reported-by: 郭永刚 References: http://article.gmane.org/gmane.comp.security.oss.general/17908 Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller (cherry picked from commit 4ab42d78e37a294ac7bc56901d563c642e03c4ae) CVE-2015-7799 BugLink: http://bugs.launchpad.net/bugs/1508329 Signed-off-by: Andy Whitcroft --- drivers/isdn/i4l/isdn_ppp.c | 10 ++++------ drivers/net/ppp/ppp_generic.c | 6 ++---- drivers/net/slip/slhc.c | 12 ++++++++---- drivers/net/slip/slip.c | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 86f9abe..9c1e8ad 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -322,9 +322,9 @@ isdn_ppp_open(int min, struct file *file) * VJ header compression init */ is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */ - if (!is->slcomp) { + if (IS_ERR(is->slcomp)) { isdn_ppp_ccp_reset_free(is); - return -ENOMEM; + return PTR_ERR(is->slcomp); } #endif #ifdef CONFIG_IPPP_FILTER @@ -573,10 +573,8 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg) is->maxcid = val; #ifdef CONFIG_ISDN_PPP_VJ sltmp = slhc_init(16, val); - if (!sltmp) { - printk(KERN_ERR "ippp, can't realloc slhc struct\n"); - return -ENOMEM; - } + if (IS_ERR(sltmp)) + return PTR_ERR(sltmp); if (is->slcomp) slhc_free(is->slcomp); is->slcomp = sltmp; diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 487be20..3f3bda8 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -719,10 +719,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) val &= 0xffff; } vj = slhc_init(val2+1, val+1); - if (!vj) { - netdev_err(ppp->dev, - "PPP: no memory (VJ compressor)\n"); - err = -ENOMEM; + if (IS_ERR(vj)) { + err = PTR_ERR(vj); break; } ppp_lock(ppp); diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c index 079f7ad..27ed252 100644 --- a/drivers/net/slip/slhc.c +++ b/drivers/net/slip/slhc.c @@ -84,8 +84,9 @@ static long decode(unsigned char **cpp); static unsigned char * put16(unsigned char *cp, unsigned short x); static unsigned short pull16(unsigned char **cpp); -/* Initialize compression data structure +/* Allocate compression data structure * slots must be in range 0 to 255 (zero meaning no compression) + * Returns pointer to structure or ERR_PTR() on error. */ struct slcompress * slhc_init(int rslots, int tslots) @@ -94,11 +95,14 @@ slhc_init(int rslots, int tslots) register struct cstate *ts; struct slcompress *comp; + if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255) + return ERR_PTR(-EINVAL); + comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL); if (! comp) goto out_fail; - if ( rslots > 0 && rslots < 256 ) { + if (rslots > 0) { size_t rsize = rslots * sizeof(struct cstate); comp->rstate = kzalloc(rsize, GFP_KERNEL); if (! comp->rstate) @@ -106,7 +110,7 @@ slhc_init(int rslots, int tslots) comp->rslot_limit = rslots - 1; } - if ( tslots > 0 && tslots < 256 ) { + if (tslots > 0) { size_t tsize = tslots * sizeof(struct cstate); comp->tstate = kzalloc(tsize, GFP_KERNEL); if (! comp->tstate) @@ -141,7 +145,7 @@ out_free2: out_free: kfree(comp); out_fail: - return NULL; + return ERR_PTR(-ENOMEM); } diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 05387b1..a17d86a 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -164,7 +164,7 @@ static int sl_alloc_bufs(struct slip *sl, int mtu) if (cbuff == NULL) goto err_exit; slcomp = slhc_init(16, 16); - if (slcomp == NULL) + if (IS_ERR(slcomp)) goto err_exit; #endif spin_lock_bh(&sl->lock);