Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp4624040yba; Tue, 30 Apr 2019 01:20:51 -0700 (PDT) X-Google-Smtp-Source: APXvYqzsCO+PCSmbNoztzjYSbbXjYEc2GJwZJJVoVm+iu0/LdAtIM7qxcbagrg0ATYTqPcawmFHE X-Received: by 2002:a65:4247:: with SMTP id d7mr19834123pgq.114.1556612450995; Tue, 30 Apr 2019 01:20:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556612450; cv=none; d=google.com; s=arc-20160816; b=wnKU8TThK12reCpodUm3fvXk0PTXAjBe8oE9UHLPF6k6qbImHjmFtAlFd44+F2A58w MNV4dDTZFekQXLPMR7jZMn+zMHkviKWup5HJ1/45XUZsWGfnT/ZxsT/vNZhMUUnLhJH9 o7hLjSVFVePVY8G+dOFCvcXU09MU8Bcrvb+fG+Yw1JsQFk3x5VhkG4W92HYnF2drHKwB SVZ4KLx1/IRMYw4WRB3/iQ0BeRKLJvYv8a7/j5siT1HYbHfLuYQ/RLb110I6VuWzqHj1 HMgTSKFd6BJeQyk4UdSPTlzYkhAtiP+xCdmUKnNump7s3JfAzH6vNKPOL6tmpBwDm+Z1 LUzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=INByUq3lVa3EFEeFkF0GCwcbXF+CEthavbsWjHwZITo=; b=OudLFIGd6Dpbr4THnTgg21q/j5cIOrJYVjp2XkFaMEI04HEbx6df0TP5UU6AjjTl0B a9b7oBjrB9pUp4gqOy1rhc8ZQxItRz+yieaao1oGawq8pv0wtuyCOz13ehSXJK7pB/lL qNwLOrH2hJNwCuKUjDcLEJuZ3QfXQQvG9TQm7ZmChUmuJ7ZPMLAd7N+OhwJFmEzXQFSn hpw4lzXAyrbt3KvSngPjq+5/U2Xevclt0nuLGqQwkzKOKeiOmwL45BQ7cQ3mdsdU8xSX m1FeqPqWfQlvjiTz6312qcUkDSpuIxGJV8hfu8QOtDexVgr4IO79LeL1imvyZz3xybN3 JkIA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o68si4413700pfo.98.2019.04.30.01.20.35; Tue, 30 Apr 2019 01:20:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726668AbfD3ITd (ORCPT + 99 others); Tue, 30 Apr 2019 04:19:33 -0400 Received: from mx2.suse.de ([195.135.220.15]:55614 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726646AbfD3ITc (ORCPT ); Tue, 30 Apr 2019 04:19:32 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 19136AE3F; Tue, 30 Apr 2019 08:19:30 +0000 (UTC) From: =?UTF-8?q?Michal=20Koutn=C3=BD?= To: gorcunov@gmail.com Cc: akpm@linux-foundation.org, arunks@codeaurora.org, brgl@bgdev.pl, geert+renesas@glider.be, ldufour@linux.ibm.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, mguzik@redhat.com, mhocko@kernel.org, mkoutny@suse.com, rppt@linux.ibm.com, vbabka@suse.cz, ktkhai@virtuozzo.com Subject: [PATCH 2/3] prctl_set_mm: Refactor checks from validate_prctl_map Date: Tue, 30 Apr 2019 10:18:43 +0200 Message-Id: <20190430081844.22597-3-mkoutny@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190430081844.22597-1-mkoutny@suse.com> References: <20190418182321.GJ3040@uranus.lan> <20190430081844.22597-1-mkoutny@suse.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Despite comment of validate_prctl_map claims there are no capability checks, it is not completely true since commit 4d28df6152aa ("prctl: Allow local CAP_SYS_ADMIN changing exe_file"). Extract the check out of the function and make the function perform purely arithmetic checks. This patch should not change any behavior, it is mere refactoring for following patch. CC: Kirill Tkhai CC: Cyrill Gorcunov Signed-off-by: Michal Koutný --- kernel/sys.c | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/kernel/sys.c b/kernel/sys.c index 12df0e5434b8..e1acb444d7b0 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1882,10 +1882,12 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) } /* + * Check arithmetic relations of passed addresses. + * * WARNING: we don't require any capability here so be very careful * in what is allowed for modification from userspace. */ -static int validate_prctl_map(struct prctl_mm_map *prctl_map) +static int validate_prctl_map_addr(struct prctl_mm_map *prctl_map) { unsigned long mmap_max_addr = TASK_SIZE; struct mm_struct *mm = current->mm; @@ -1949,24 +1951,6 @@ static int validate_prctl_map(struct prctl_mm_map *prctl_map) prctl_map->start_data)) goto out; - /* - * Someone is trying to cheat the auxv vector. - */ - if (prctl_map->auxv_size) { - if (!prctl_map->auxv || prctl_map->auxv_size > sizeof(mm->saved_auxv)) - goto out; - } - - /* - * Finally, make sure the caller has the rights to - * change /proc/pid/exe link: only local sys admin should - * be allowed to. - */ - if (prctl_map->exe_fd != (u32)-1) { - if (!ns_capable(current_user_ns(), CAP_SYS_ADMIN)) - goto out; - } - error = 0; out: return error; @@ -1993,11 +1977,17 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data if (copy_from_user(&prctl_map, addr, sizeof(prctl_map))) return -EFAULT; - error = validate_prctl_map(&prctl_map); + error = validate_prctl_map_addr(&prctl_map); if (error) return error; if (prctl_map.auxv_size) { + /* + * Someone is trying to cheat the auxv vector. + */ + if (!prctl_map.auxv || prctl_map.auxv_size > sizeof(mm->saved_auxv)) + return -EINVAL; + memset(user_auxv, 0, sizeof(user_auxv)); if (copy_from_user(user_auxv, (const void __user *)prctl_map.auxv, @@ -2010,6 +2000,14 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data } if (prctl_map.exe_fd != (u32)-1) { + /* + * Make sure the caller has the rights to + * change /proc/pid/exe link: only local sys admin should + * be allowed to. + */ + if (!ns_capable(current_user_ns(), CAP_SYS_ADMIN)) + return -EINVAL; + error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd); if (error) return error; @@ -2097,7 +2095,7 @@ static int prctl_set_mm(int opt, unsigned long addr, unsigned long arg4, unsigned long arg5) { struct mm_struct *mm = current->mm; - struct prctl_mm_map prctl_map; + struct prctl_mm_map prctl_map = { .auxv = NULL, .auxv_size = 0, .exe_fd = -1 }; struct vm_area_struct *vma; int error; @@ -2139,9 +2137,6 @@ static int prctl_set_mm(int opt, unsigned long addr, prctl_map.arg_end = mm->arg_end; prctl_map.env_start = mm->env_start; prctl_map.env_end = mm->env_end; - prctl_map.auxv = NULL; - prctl_map.auxv_size = 0; - prctl_map.exe_fd = -1; switch (opt) { case PR_SET_MM_START_CODE: @@ -2181,7 +2176,7 @@ static int prctl_set_mm(int opt, unsigned long addr, goto out; } - error = validate_prctl_map(&prctl_map); + error = validate_prctl_map_addr(&prctl_map); if (error) goto out; -- 2.16.4