From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751775AbdK3GTQ (ORCPT ); Thu, 30 Nov 2017 01:19:16 -0500 Received: from relay-out3.mail.masterhost.ru ([83.222.12.13]:23372 "EHLO relay-out3.mail.masterhost.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750995AbdK3GTP (ORCPT ); Thu, 30 Nov 2017 01:19:15 -0500 X-Greylist: delayed 390 seconds by postgrey-1.27 at vger.kernel.org; Thu, 30 Nov 2017 01:19:14 EST From: Philippe Mikoyan To: akpm@linux-foundation.org Cc: viro@zeniv.linux.org.uk, manfred@colorfullife.com, linux-kernel@vger.kernel.org, edgar.kaziakhmedov@virtuozzo.com, philippe.mikoyan@skat.systems Subject: [PATCH 1/2] ipc/shm: Fix shm_nattch incorrect value Date: Thu, 30 Nov 2017 09:12:23 +0300 Message-Id: <20171130061224.25466-2-philippe.mikoyan@skat.systems> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171130061224.25466-1-philippe.mikoyan@skat.systems> References: <20171130061224.25466-1-philippe.mikoyan@skat.systems> X-KLMS-Rule-ID: 1 X-KLMS-Message-Action: clean X-KLMS-AntiSpam-Lua-Profiles: 119311 [Nov 30 2017] X-KLMS-AntiSpam-Version: 5.7.67.0 X-KLMS-AntiSpam-Envelope-From: philippe.mikoyan@skat.systems X-KLMS-AntiSpam-Rate: 0 X-KLMS-AntiSpam-Status: not_detected X-KLMS-AntiSpam-Method: none X-KLMS-AntiSpam-Info: LuaCore: 90 90 5dc5ed154507efaef166c077cc2b8afd8a7be26b, Auth:dkim=none, {DNS response errors} X-KLMS-AntiSpam-Interceptor-Info: scan successful X-KLMS-AntiPhishing: not scanned, disabled by settings X-KLMS-AntiVirus: Kaspersky Security 8.0 for Linux Mail Server, version 8.0.1.721, not scanned, license restriction Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch fixes that do_shmat increases shm_nattch value twice. E.g. if memory segment was created just now and process attaches it, shmctl(..IPC_STAT..) of concurrently running process can at some point of time return data structure with 'shm_nattch' equal to 2. Signed-off-by: Philippe Mikoyan Signed-off-by: Edgar Kaziakhmedov --- ipc/shm.c | 58 +++++++++++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/ipc/shm.c b/ipc/shm.c index badac463e2c8..565f17925128 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -190,33 +190,31 @@ static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s) ipc_rmid(&shm_ids(ns), &s->shm_perm); } - -static int __shm_open(struct vm_area_struct *vma) -{ - struct file *file = vma->vm_file; - struct shm_file_data *sfd = shm_file_data(file); - struct shmid_kernel *shp; - - shp = shm_lock(sfd->ns, sfd->id); - - if (IS_ERR(shp)) - return PTR_ERR(shp); - - shp->shm_atim = ktime_get_real_seconds(); - shp->shm_lprid = task_tgid_vnr(current); - shp->shm_nattch++; - shm_unlock(shp); - return 0; -} - /* This is called by fork, once for every shm attach. */ static void shm_open(struct vm_area_struct *vma) { - int err = __shm_open(vma); + struct file *file = vma->vm_file; + struct shm_file_data *sfd = shm_file_data(file); + struct shmid_kernel *shp; + int err = 0; + + shp = shm_lock(sfd->ns, sfd->id); + + if (IS_ERR(shp)) { + err = PTR_ERR(shp); + goto warn; + } + + shp->shm_atim = ktime_get_real_seconds(); + shp->shm_lprid = task_tgid_vnr(current); + shp->shm_nattch++; + shm_unlock(shp); + /* * We raced in the idr lookup or with shm_destroy(). * Either way, the ID is busted. */ +warn: WARN_ON_ONCE(err); } @@ -418,19 +416,10 @@ static int shm_mmap(struct file *file, struct vm_area_struct *vma) struct shm_file_data *sfd = shm_file_data(file); int ret; - /* - * In case of remap_file_pages() emulation, the file can represent - * removed IPC ID: propogate shm_lock() error to caller. - */ - ret = __shm_open(vma); - if (ret) - return ret; - ret = call_mmap(sfd->file, vma); - if (ret) { - shm_close(vma); + if (ret) return ret; - } + sfd->vm_ops = vma->vm_ops; #ifdef CONFIG_MMU WARN_ON(!sfd->vm_ops->fault); @@ -944,6 +933,7 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid, tbuf->shm_cpid = shp->shm_cprid; tbuf->shm_lpid = shp->shm_lprid; tbuf->shm_nattch = shp->shm_nattch; + rcu_read_unlock(); return result; @@ -1351,7 +1341,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, path = shp->shm_file->f_path; path_get(&path); + + shp->shm_atim = ktime_get_real_seconds(); + shp->shm_lprid = task_tgid_vnr(current); shp->shm_nattch++; + size = i_size_read(d_inode(path.dentry)); ipc_unlock_object(&shp->shm_perm); rcu_read_unlock(); @@ -1411,6 +1405,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, out_fput: fput(file); + if (!err) + goto out; out_nattch: down_write(&shm_ids(ns).rwsem); -- 2.11.0