lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <CACT4Y+aZpC8HCq7ztZpV1ahyg2QxGonz6P7bwk+irRT=M2n-YA@mail.gmail.com> Date: Sun, 30 Oct 2022 07:33:15 -0700 From: Dmitry Vyukov <dvyukov@...gle.com> To: bongsu.jeon@...sung.com, krzysztof.kozlowski@...aro.org, netdev@...r.kernel.org Cc: syzkaller@...glegroups.com Subject: Re: [PATCH] nfc: Allow to create multiple virtual nci devices On Sun, 30 Oct 2022 at 07:29, Dmitry Vyukov <dvyukov@...gle.com> wrote: > > The current virtual nci driver is great for testing and fuzzing. > But it allows to create at most one "global" device which does not allow > to run parallel tests and harms fuzzing isolation and reproducibility. > Restructure the driver to allow creation of multiple independent devices. > This should be backwards compatible for existing tests. > > Signed-off-by: Dmitry Vyukov <dvyukov@...gle.com> > Cc: Bongsu Jeon <bongsu.jeon@...sung.com> > Cc: Krzysztof Kozlowski <krzysztof.kozlowski@...aro.org> > Cc: netdev@...r.kernel.org FYI here is this commit on github if it makes it easier to review for you: https://github.com/dvyukov/linux/commit/d0659d94a8d80f6e33f926b87a37bf1d7bdbb99d Thanks > --- > drivers/nfc/virtual_ncidev.c | 143 ++++++++++++++++------------------- > 1 file changed, 66 insertions(+), 77 deletions(-) > > diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c > index 85c06dbb2c449..8c2836a174ba2 100644 > --- a/drivers/nfc/virtual_ncidev.c > +++ b/drivers/nfc/virtual_ncidev.c > @@ -13,12 +13,6 @@ > #include <linux/wait.h> > #include <net/nfc/nci_core.h> > > -enum virtual_ncidev_mode { > - virtual_ncidev_enabled, > - virtual_ncidev_disabled, > - virtual_ncidev_disabling, > -}; > - > #define IOCTL_GET_NCIDEV_IDX 0 > #define VIRTUAL_NFC_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \ > NFC_PROTO_MIFARE_MASK | \ > @@ -27,12 +21,12 @@ enum virtual_ncidev_mode { > NFC_PROTO_ISO14443_B_MASK | \ > NFC_PROTO_ISO15693_MASK) > > -static enum virtual_ncidev_mode state; > -static DECLARE_WAIT_QUEUE_HEAD(wq); > -static struct miscdevice miscdev; > -static struct sk_buff *send_buff; > -static struct nci_dev *ndev; > -static DEFINE_MUTEX(nci_mutex); > +struct virtual_nci_dev { > + struct nci_dev *ndev; > + struct mutex mtx; > + struct sk_buff *send_buff; > + struct wait_queue_head wq; > +}; > > static int virtual_nci_open(struct nci_dev *ndev) > { > @@ -41,31 +35,29 @@ static int virtual_nci_open(struct nci_dev *ndev) > > static int virtual_nci_close(struct nci_dev *ndev) > { > - mutex_lock(&nci_mutex); > - kfree_skb(send_buff); > - send_buff = NULL; > - mutex_unlock(&nci_mutex); > + struct virtual_nci_dev *vdev = nci_get_drvdata(ndev); > + > + mutex_lock(&vdev->mtx); > + kfree_skb(vdev->send_buff); > + vdev->send_buff = NULL; > + mutex_unlock(&vdev->mtx); > > return 0; > } > > static int virtual_nci_send(struct nci_dev *ndev, struct sk_buff *skb) > { > - mutex_lock(&nci_mutex); > - if (state != virtual_ncidev_enabled) { > - mutex_unlock(&nci_mutex); > - kfree_skb(skb); > - return 0; > - } > + struct virtual_nci_dev *vdev = nci_get_drvdata(ndev); > > - if (send_buff) { > - mutex_unlock(&nci_mutex); > + mutex_lock(&vdev->mtx); > + if (vdev->send_buff) { > + mutex_unlock(&vdev->mtx); > kfree_skb(skb); > return -1; > } > - send_buff = skb_copy(skb, GFP_KERNEL); > - mutex_unlock(&nci_mutex); > - wake_up_interruptible(&wq); > + vdev->send_buff = skb_copy(skb, GFP_KERNEL); > + mutex_unlock(&vdev->mtx); > + wake_up_interruptible(&vdev->wq); > consume_skb(skb); > > return 0; > @@ -80,29 +72,30 @@ static const struct nci_ops virtual_nci_ops = { > static ssize_t virtual_ncidev_read(struct file *file, char __user *buf, > size_t count, loff_t *ppos) > { > + struct virtual_nci_dev *vdev = file->private_data; > size_t actual_len; > > - mutex_lock(&nci_mutex); > - while (!send_buff) { > - mutex_unlock(&nci_mutex); > - if (wait_event_interruptible(wq, send_buff)) > + mutex_lock(&vdev->mtx); > + while (!vdev->send_buff) { > + mutex_unlock(&vdev->mtx); > + if (wait_event_interruptible(vdev->wq, vdev->send_buff)) > return -EFAULT; > - mutex_lock(&nci_mutex); > + mutex_lock(&vdev->mtx); > } > > - actual_len = min_t(size_t, count, send_buff->len); > + actual_len = min_t(size_t, count, vdev->send_buff->len); > > - if (copy_to_user(buf, send_buff->data, actual_len)) { > - mutex_unlock(&nci_mutex); > + if (copy_to_user(buf, vdev->send_buff->data, actual_len)) { > + mutex_unlock(&vdev->mtx); > return -EFAULT; > } > > - skb_pull(send_buff, actual_len); > - if (send_buff->len == 0) { > - consume_skb(send_buff); > - send_buff = NULL; > + skb_pull(vdev->send_buff, actual_len); > + if (vdev->send_buff->len == 0) { > + consume_skb(vdev->send_buff); > + vdev->send_buff = NULL; > } > - mutex_unlock(&nci_mutex); > + mutex_unlock(&vdev->mtx); > > return actual_len; > } > @@ -111,6 +104,7 @@ static ssize_t virtual_ncidev_write(struct file *file, > const char __user *buf, > size_t count, loff_t *ppos) > { > + struct virtual_nci_dev *vdev = file->private_data; > struct sk_buff *skb; > > skb = alloc_skb(count, GFP_KERNEL); > @@ -122,63 +116,57 @@ static ssize_t virtual_ncidev_write(struct file *file, > return -EFAULT; > } > > - nci_recv_frame(ndev, skb); > + nci_recv_frame(vdev->ndev, skb); > return count; > } > > static int virtual_ncidev_open(struct inode *inode, struct file *file) > { > int ret = 0; > + struct virtual_nci_dev *vdev; > > - mutex_lock(&nci_mutex); > - if (state != virtual_ncidev_disabled) { > - mutex_unlock(&nci_mutex); > - return -EBUSY; > - } > - > - ndev = nci_allocate_device(&virtual_nci_ops, VIRTUAL_NFC_PROTOCOLS, > - 0, 0); > - if (!ndev) { > - mutex_unlock(&nci_mutex); > + vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); > + if (!vdev) > + return -ENOMEM; > + vdev->ndev = nci_allocate_device(&virtual_nci_ops, > + VIRTUAL_NFC_PROTOCOLS, 0, 0); > + if (!vdev->ndev) { > + kfree(vdev); > return -ENOMEM; > } > > - ret = nci_register_device(ndev); > + mutex_init(&vdev->mtx); > + init_waitqueue_head(&vdev->wq); > + file->private_data = vdev; > + nci_set_drvdata(vdev->ndev, vdev); > + > + ret = nci_register_device(vdev->ndev); > if (ret < 0) { > - nci_free_device(ndev); > - mutex_unlock(&nci_mutex); > + mutex_destroy(&vdev->mtx); > + nci_free_device(vdev->ndev); > + kfree(vdev); > return ret; > } > - state = virtual_ncidev_enabled; > - mutex_unlock(&nci_mutex); > > return 0; > } > > static int virtual_ncidev_close(struct inode *inode, struct file *file) > { > - mutex_lock(&nci_mutex); > - > - if (state == virtual_ncidev_enabled) { > - state = virtual_ncidev_disabling; > - mutex_unlock(&nci_mutex); > - > - nci_unregister_device(ndev); > - nci_free_device(ndev); > - > - mutex_lock(&nci_mutex); > - } > + struct virtual_nci_dev *vdev = file->private_data; > > - state = virtual_ncidev_disabled; > - mutex_unlock(&nci_mutex); > + nci_unregister_device(vdev->ndev); > + nci_free_device(vdev->ndev); > + mutex_destroy(&vdev->mtx); > > return 0; > } > > -static long virtual_ncidev_ioctl(struct file *flip, unsigned int cmd, > +static long virtual_ncidev_ioctl(struct file *file, unsigned int cmd, > unsigned long arg) > { > - const struct nfc_dev *nfc_dev = ndev->nfc_dev; > + struct virtual_nci_dev *vdev = file->private_data; > + const struct nfc_dev *nfc_dev = vdev->ndev->nfc_dev; > void __user *p = (void __user *)arg; > > if (cmd != IOCTL_GET_NCIDEV_IDX) > @@ -199,14 +187,15 @@ static const struct file_operations virtual_ncidev_fops = { > .unlocked_ioctl = virtual_ncidev_ioctl > }; > > +static struct miscdevice miscdev = { > + .minor = MISC_DYNAMIC_MINOR, > + .name = "virtual_nci", > + .fops = &virtual_ncidev_fops, > + .mode = 0600, > +}; > + > static int __init virtual_ncidev_init(void) > { > - state = virtual_ncidev_disabled; > - miscdev.minor = MISC_DYNAMIC_MINOR; > - miscdev.name = "virtual_nci"; > - miscdev.fops = &virtual_ncidev_fops; > - miscdev.mode = 0600; > - > return misc_register(&miscdev); > } > > > base-commit: 02a97e02c64fb3245b84835cbbed1c3a3222e2f1 > -- > 2.38.1.273.g43a17bfeac-goog >
Powered by blists - more mailing lists