Received: by 10.223.164.202 with SMTP id h10csp286497wrb; Wed, 29 Nov 2017 22:20:48 -0800 (PST) X-Google-Smtp-Source: AGs4zMZUvno8evLtsdLficRqP6/F6GC2Sjy8mJ8NrJPo9HxIkQYb7InvDiQiS746g+pxWih53Y5L X-Received: by 10.98.49.130 with SMTP id x124mr5512065pfx.149.1512022848087; Wed, 29 Nov 2017 22:20:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512022848; cv=none; d=google.com; s=arc-20160816; b=mOVb+zysxsjabOFj8rjKHuZxBBfcAUo/VfDth2FoOn023TXCpXPwSiOi5z0npTWXvS YQ4Fwf3goIa0r9J53RZ4LmLjFaLzU0ylOoIGL2FECAHehy+oeQGmyPY1iRI9tKc7M5dd 52B59NYIBC765NXJ+7Fa6TYe7ewrFijeM7ecWxArymF9IdYRFGYR+Ng3D2LwfkwGqpDb ZZsBdH7HjBbqeaIiAd9OxunjEKhG7ydrfhYFVsVQuaSQmyNJn+byHh6nxetJBB383H11 kqQdWmmgqX7ktA71lXmtFhX8hNuWHpH+4qYe1T70gpJPgHytTzHDxGgedpwdZvm9JILB yN9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=A/EYIQ4pOBn0fgbBQuTt4eYqURo4KPNX2LOuvYIbdS8=; b=s2IaiKQbw2s9JegZ38dZSSt3qAdi3sVTjjAFDm8vdxeIfH8nFmrzXmUwJZGsxs8QtZ j3dMsHq/UXfU4Ur7r9+u0IuegSPOWe4/AInvymxDl4U0MMs1F31fkUrtLp51rJKcrisE phcIPidWVKgQCV9rD8oDZVUDVs32CrHlRWYXUSwzWOwi/5ppSvVPNmTWPh2MyJThesUh K/W//mgcaFMGOpII0Nr31HUYS8NiuvHFOdY5lRc4rvT0EgVqVbilFRoIr1f2hVuntgCh CXxafb0WRguN3Iqoc/S7rzJ8jhW3OLRSMVwP4zvCyWlSqZO3PKOPQSoT6zI2tPXHWqUt rb/Q== 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 b11si2539882plr.503.2017.11.29.22.20.33; Wed, 29 Nov 2017 22:20:48 -0800 (PST) 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 S1752355AbdK3GUQ (ORCPT + 99 others); Thu, 30 Nov 2017 01:20:16 -0500 Received: from relay-out3.mail.masterhost.ru ([83.222.12.13]:16873 "EHLO relay-out3.mail.masterhost.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751694AbdK3GUP (ORCPT ); Thu, 30 Nov 2017 01:20:15 -0500 Received: from [93.175.1.191] (helo=localhost.localdomain) by relay3.mail.masterhost.ru with esmtpa envelope from authenticated with philippe.mikoyan@skat.systems message id 1eKI5Z-0001OR-Kv; Thu, 30 Nov 2017 09:13:00 +0300 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 2/2] ipc: Fix ipc data structures inconsistency Date: Thu, 30 Nov 2017 09:12:24 +0300 Message-Id: <20171130061224.25466-3-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 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org As described in the title, this patch fixes id_ds inconsistency when ctl_stat runs concurrently with some ds-changing function, e.g. shmat, msgsnd or whatever. For instance, if shmctl(IPC_STAT) is running concurrently with shmat, following data structure can be returned: {... shm_lpid = 0, shm_nattch = 1, ...} Signed-off-by: Philippe Mikoyan --- ipc/msg.c | 20 ++++++++++++++------ ipc/sem.c | 10 ++++++++++ ipc/shm.c | 19 ++++++++++++++----- ipc/util.c | 5 ++++- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/ipc/msg.c b/ipc/msg.c index 06be5a9adfa4..047579b42de4 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -475,9 +475,9 @@ static int msgctl_info(struct ipc_namespace *ns, int msqid, static int msgctl_stat(struct ipc_namespace *ns, int msqid, int cmd, struct msqid64_ds *p) { - int err; struct msg_queue *msq; - int success_return; + int id = 0; + int err; memset(p, 0, sizeof(*p)); @@ -488,14 +488,13 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid, err = PTR_ERR(msq); goto out_unlock; } - success_return = msq->q_perm.id; + id = msq->q_perm.id; } else { msq = msq_obtain_object_check(ns, msqid); if (IS_ERR(msq)) { err = PTR_ERR(msq); goto out_unlock; } - success_return = 0; } err = -EACCES; @@ -506,6 +505,14 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid, if (err) goto out_unlock; + ipc_lock_object(&msq->q_perm); + + if (!ipc_valid_object(&msq->q_perm)) { + ipc_unlock_object(&msq->q_perm); + err = -EIDRM; + goto out_unlock; + } + kernel_to_ipc64_perm(&msq->q_perm, &p->msg_perm); p->msg_stime = msq->q_stime; p->msg_rtime = msq->q_rtime; @@ -515,9 +522,10 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid, p->msg_qbytes = msq->q_qbytes; p->msg_lspid = msq->q_lspid; p->msg_lrpid = msq->q_lrpid; - rcu_read_unlock(); - return success_return; + ipc_unlock_object(&msq->q_perm); + rcu_read_unlock(); + return id; out_unlock: rcu_read_unlock(); diff --git a/ipc/sem.c b/ipc/sem.c index f7385bce5fd3..9b6f80d1b3f1 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -1211,10 +1211,20 @@ static int semctl_stat(struct ipc_namespace *ns, int semid, if (err) goto out_unlock; + ipc_lock_object(&sma->sem_perm); + + if (!ipc_valid_object(&sma->sem_perm)) { + ipc_unlock_object(&sma->sem_perm); + err = -EIDRM; + goto out_unlock; + } + kernel_to_ipc64_perm(&sma->sem_perm, &semid64->sem_perm); semid64->sem_otime = get_semotime(sma); semid64->sem_ctime = sma->sem_ctime; semid64->sem_nsems = sma->sem_nsems; + + ipc_unlock_object(&sma->sem_perm); rcu_read_unlock(); return id; diff --git a/ipc/shm.c b/ipc/shm.c index 565f17925128..8f58faba7429 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -896,9 +896,11 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid, int cmd, struct shmid64_ds *tbuf) { struct shmid_kernel *shp; - int result; + int id = 0; int err; + memset(tbuf, 0, sizeof(*tbuf)); + rcu_read_lock(); if (cmd == SHM_STAT) { shp = shm_obtain_object(ns, shmid); @@ -906,14 +908,13 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid, err = PTR_ERR(shp); goto out_unlock; } - result = shp->shm_perm.id; + id = shp->shm_perm.id; } else { shp = shm_obtain_object_check(ns, shmid); if (IS_ERR(shp)) { err = PTR_ERR(shp); goto out_unlock; } - result = 0; } err = -EACCES; @@ -924,7 +925,14 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid, if (err) goto out_unlock; - memset(tbuf, 0, sizeof(*tbuf)); + ipc_lock_object(&shp->shm_perm); + + if (!ipc_valid_object(&shp->shm_perm)) { + ipc_unlock_object(&shp->shm_perm); + err = -EIDRM; + goto out_unlock; + } + kernel_to_ipc64_perm(&shp->shm_perm, &tbuf->shm_perm); tbuf->shm_segsz = shp->shm_segsz; tbuf->shm_atime = shp->shm_atim; @@ -934,8 +942,9 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid, tbuf->shm_lpid = shp->shm_lprid; tbuf->shm_nattch = shp->shm_nattch; + ipc_unlock_object(&shp->shm_perm); rcu_read_unlock(); - return result; + return id; out_unlock: rcu_read_unlock(); diff --git a/ipc/util.c b/ipc/util.c index 78755873cc5b..8d3c3946c825 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -22,9 +22,12 @@ * tree. * - perform initial checks (capabilities, auditing and permission, * etc). - * - perform read-only operations, such as STAT, INFO commands. + * - perform read-only operations, such as INFO command, that + * do not demand atomicity * acquire the ipc lock (kern_ipc_perm.lock) through * ipc_lock_object() + * - perform read-only operatoins that demand atomicity, + * such as STAT command. * - perform data updates, such as SET, RMID commands and * mechanism-specific operations (semop/semtimedop, * msgsnd/msgrcv, shmat/shmdt). -- 2.11.0 From 1585687138664805261@xxx Sat Dec 02 15:38:18 +0000 2017 X-GM-THRID: 1585323514263946873 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread