mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 15:40:56 +07:00
seccomp: Add find_notification helper
This adds a helper which can iterate through a seccomp_filter to find a notification matching an ID. It removes several replicated chunks of code. Signed-off-by: Sargun Dhillon <sargun@sargun.me> Acked-by: Christian Brauner <christian.brauner@ubuntu.com> Reviewed-by: Tycho Andersen <tycho@tycho.ws> Cc: Matt Denton <mpdenton@google.com> Cc: Kees Cook <keescook@google.com>, Cc: Jann Horn <jannh@google.com>, Cc: Robert Sesek <rsesek@google.com>, Cc: Chris Palmer <palmer@google.com> Cc: Christian Brauner <christian.brauner@ubuntu.com> Cc: Tycho Andersen <tycho@tycho.ws> Link: https://lore.kernel.org/r/20200601112532.150158-1-sargun@sargun.me Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
c818c03b66
commit
9f87dcf14b
@ -41,6 +41,7 @@
|
|||||||
#include <linux/tracehook.h>
|
#include <linux/tracehook.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/anon_inodes.h>
|
#include <linux/anon_inodes.h>
|
||||||
|
#include <linux/lockdep.h>
|
||||||
|
|
||||||
enum notify_state {
|
enum notify_state {
|
||||||
SECCOMP_NOTIFY_INIT,
|
SECCOMP_NOTIFY_INIT,
|
||||||
@ -1024,6 +1025,23 @@ static int seccomp_notify_release(struct inode *inode, struct file *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* must be called with notif_lock held */
|
||||||
|
static inline struct seccomp_knotif *
|
||||||
|
find_notification(struct seccomp_filter *filter, u64 id)
|
||||||
|
{
|
||||||
|
struct seccomp_knotif *cur;
|
||||||
|
|
||||||
|
lockdep_assert_held(&filter->notify_lock);
|
||||||
|
|
||||||
|
list_for_each_entry(cur, &filter->notif->notifications, list) {
|
||||||
|
if (cur->id == id)
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static long seccomp_notify_recv(struct seccomp_filter *filter,
|
static long seccomp_notify_recv(struct seccomp_filter *filter,
|
||||||
void __user *buf)
|
void __user *buf)
|
||||||
{
|
{
|
||||||
@ -1081,15 +1099,8 @@ static long seccomp_notify_recv(struct seccomp_filter *filter,
|
|||||||
* may have died when we released the lock, so we need to make
|
* may have died when we released the lock, so we need to make
|
||||||
* sure it's still around.
|
* sure it's still around.
|
||||||
*/
|
*/
|
||||||
knotif = NULL;
|
|
||||||
mutex_lock(&filter->notify_lock);
|
mutex_lock(&filter->notify_lock);
|
||||||
list_for_each_entry(cur, &filter->notif->notifications, list) {
|
knotif = find_notification(filter, unotif.id);
|
||||||
if (cur->id == unotif.id) {
|
|
||||||
knotif = cur;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (knotif) {
|
if (knotif) {
|
||||||
knotif->state = SECCOMP_NOTIFY_INIT;
|
knotif->state = SECCOMP_NOTIFY_INIT;
|
||||||
up(&filter->notif->request);
|
up(&filter->notif->request);
|
||||||
@ -1104,7 +1115,7 @@ static long seccomp_notify_send(struct seccomp_filter *filter,
|
|||||||
void __user *buf)
|
void __user *buf)
|
||||||
{
|
{
|
||||||
struct seccomp_notif_resp resp = {};
|
struct seccomp_notif_resp resp = {};
|
||||||
struct seccomp_knotif *knotif = NULL, *cur;
|
struct seccomp_knotif *knotif;
|
||||||
long ret;
|
long ret;
|
||||||
|
|
||||||
if (copy_from_user(&resp, buf, sizeof(resp)))
|
if (copy_from_user(&resp, buf, sizeof(resp)))
|
||||||
@ -1121,13 +1132,7 @@ static long seccomp_notify_send(struct seccomp_filter *filter,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
list_for_each_entry(cur, &filter->notif->notifications, list) {
|
knotif = find_notification(filter, resp.id);
|
||||||
if (cur->id == resp.id) {
|
|
||||||
knotif = cur;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!knotif) {
|
if (!knotif) {
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
goto out;
|
goto out;
|
||||||
@ -1153,7 +1158,7 @@ static long seccomp_notify_send(struct seccomp_filter *filter,
|
|||||||
static long seccomp_notify_id_valid(struct seccomp_filter *filter,
|
static long seccomp_notify_id_valid(struct seccomp_filter *filter,
|
||||||
void __user *buf)
|
void __user *buf)
|
||||||
{
|
{
|
||||||
struct seccomp_knotif *knotif = NULL;
|
struct seccomp_knotif *knotif;
|
||||||
u64 id;
|
u64 id;
|
||||||
long ret;
|
long ret;
|
||||||
|
|
||||||
@ -1164,16 +1169,12 @@ static long seccomp_notify_id_valid(struct seccomp_filter *filter,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = -ENOENT;
|
knotif = find_notification(filter, id);
|
||||||
list_for_each_entry(knotif, &filter->notif->notifications, list) {
|
if (knotif && knotif->state == SECCOMP_NOTIFY_SENT)
|
||||||
if (knotif->id == id) {
|
ret = 0;
|
||||||
if (knotif->state == SECCOMP_NOTIFY_SENT)
|
else
|
||||||
ret = 0;
|
ret = -ENOENT;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
mutex_unlock(&filter->notify_lock);
|
mutex_unlock(&filter->notify_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user