2013-07-22 01:21:54

by Davidlohr Bueso

[permalink] [raw]
Subject: [PATCH 0/4] ipc: misc fixes & pending cleanups

Applies on top of linux-next (20130719), please consider them
for 3.12. Very straightforward patchset:

Patch 1: always check the return of find_vma in shmdt(2)
Patch 2-4: remove now mostly unused functions from the previous
cleanups and optimizations.

Davidlohr Bueso (4):
ipc, shm: guard against non-existant vma in shmdt(2)
ipc: drop ipc_lock_by_ptr
ipc, shm: drop shm_lock_check
ipc: drop ipc_lock_check

ipc/namespace.c | 3 ++-
ipc/shm.c | 14 +-------------
ipc/util.c | 22 ++++------------------
ipc/util.h | 7 -------
4 files changed, 7 insertions(+), 39 deletions(-)

--
1.7.11.7


2013-07-22 01:21:58

by Davidlohr Bueso

[permalink] [raw]
Subject: [PATCH 4/4] ipc: drop ipc_lock_check

No remaining users, we now use ipc_obtain_object_check().

Signed-off-by: Davidlohr Bueso <[email protected]>
---
ipc/util.c | 16 ----------------
ipc/util.h | 1 -
2 files changed, 17 deletions(-)

diff --git a/ipc/util.c b/ipc/util.c
index 9f6aa30..e829da9 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -686,22 +686,6 @@ out:
return out;
}

-struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id)
-{
- struct kern_ipc_perm *out;
-
- out = ipc_lock(ids, id);
- if (IS_ERR(out))
- return out;
-
- if (ipc_checkid(out, id)) {
- ipc_unlock(out);
- return ERR_PTR(-EIDRM);
- }
-
- return out;
-}
-
/**
* ipcget - Common sys_*get() code
* @ns : namsepace
diff --git a/ipc/util.h b/ipc/util.h
index 14b0a2a..c5f3338b 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -177,7 +177,6 @@ static inline void ipc_unlock(struct kern_ipc_perm *perm)
rcu_read_unlock();
}

-struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id);
struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id);
int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
struct ipc_ops *ops, struct ipc_params *params);
--
1.7.11.7

2013-07-22 01:21:56

by Davidlohr Bueso

[permalink] [raw]
Subject: [PATCH 2/4] ipc: drop ipc_lock_by_ptr

After previous cleanups and optimizations, this function is no longer
heavily used and we don't have a good reason to keep it. Update the
few remaining callers and get rid of it.

Signed-off-by: Davidlohr Bueso <[email protected]>
---
ipc/namespace.c | 3 ++-
ipc/util.c | 6 ++++--
ipc/util.h | 6 ------
3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/ipc/namespace.c b/ipc/namespace.c
index 67dc744..aba9a58 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -89,7 +89,8 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
perm = idr_find(&ids->ipcs_idr, next_id);
if (perm == NULL)
continue;
- ipc_lock_by_ptr(perm);
+ rcu_read_lock();
+ ipc_lock_object(perm);
free(ns, perm);
total++;
}
diff --git a/ipc/util.c b/ipc/util.c
index 1ddadcf..9f6aa30 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -205,7 +205,8 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
continue;
}

- ipc_lock_by_ptr(ipc);
+ rcu_read_lock();
+ ipc_lock_object(ipc);
return ipc;
}

@@ -838,7 +839,8 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
ipc = idr_find(&ids->ipcs_idr, pos);
if (ipc != NULL) {
*new_pos = pos + 1;
- ipc_lock_by_ptr(ipc);
+ rcu_read_lock();
+ ipc_lock_object(ipc);
return ipc;
}
}
diff --git a/ipc/util.h b/ipc/util.h
index 0a362ff..14b0a2a 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -171,12 +171,6 @@ static inline void ipc_assert_locked_object(struct kern_ipc_perm *perm)
assert_spin_locked(&perm->lock);
}

-static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
-{
- rcu_read_lock();
- ipc_lock_object(perm);
-}
-
static inline void ipc_unlock(struct kern_ipc_perm *perm)
{
ipc_unlock_object(perm);
--
1.7.11.7

2013-07-22 01:22:39

by Davidlohr Bueso

[permalink] [raw]
Subject: [PATCH 3/4] ipc, shm: drop shm_lock_check

This function was replaced by a the lockless shm_obtain_object_check(),
and no longer has any users.

Signed-off-by: Davidlohr Bueso <[email protected]>
---
ipc/shm.c | 11 -----------
1 file changed, 11 deletions(-)

diff --git a/ipc/shm.c b/ipc/shm.c
index c7ee2f6..9ffc563 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -167,17 +167,6 @@ static inline void shm_lock_by_ptr(struct shmid_kernel *ipcp)
ipc_lock_object(&ipcp->shm_perm);
}

-static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns,
- int id)
-{
- struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id);
-
- if (IS_ERR(ipcp))
- return (struct shmid_kernel *)ipcp;
-
- return container_of(ipcp, struct shmid_kernel, shm_perm);
-}
-
static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s)
{
ipc_rmid(&shm_ids(ns), &s->shm_perm);
--
1.7.11.7

2013-07-22 01:23:03

by Davidlohr Bueso

[permalink] [raw]
Subject: [PATCH 1/4] ipc, shm: guard against non-existant vma in shmdt(2)

When !CONFIG_MMU there's a chance we can derefence a NULL pointer
when the VM area isn't found - check the return value of find_vma().

Also, remove the redundant -EINVAL return: retval is set to the proper
return code and *only* changed to 0, when we actually unmap the segments.

Signed-off-by: Davidlohr Bueso <[email protected]>
---
ipc/shm.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/ipc/shm.c b/ipc/shm.c
index 59f2194..c7ee2f6 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1288,8 +1288,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
#else /* CONFIG_MMU */
/* under NOMMU conditions, the exact address to be destroyed must be
* given */
- retval = -EINVAL;
- if (vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) {
+ if (vma && vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) {
do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
retval = 0;
}
--
1.7.11.7