[Devel] [PATCH RHEL7 COMMIT] ploop: Add @id argument to ->autodetect()

2020-08-24 Thread Vasily Averin
The commit is pushed to "branch-rh7-3.10.0-1127.18.2.vz7.163.x-ovz" and will 
appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.18.2.vz7.163.9
-->
commit 5c4a961d7209b18bb1001f2315d8650021b1805b
Author: Kirill Tkhai 
Date:   Tue Aug 25 09:04:49 2020 +0300

ploop: Add @id argument to ->autodetect()

https://jira.sw.ru/browse/PSBM-105347
Signed-off-by: Kirill Tkhai 
---
 drivers/block/ploop/io.c| 2 +-
 drivers/block/ploop/io_direct.c | 2 +-
 drivers/block/ploop/io_kaio.c   | 2 +-
 include/linux/ploop/ploop.h | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/block/ploop/io.c b/drivers/block/ploop/io.c
index 5499f97..ad1d365 100644
--- a/drivers/block/ploop/io.c
+++ b/drivers/block/ploop/io.c
@@ -43,7 +43,7 @@ static struct ploop_io_ops * ploop_io_get(struct ploop_io 
*io, unsigned int id)
mutex_lock(&ploop_ios_mutex);
list_for_each_entry(ops, &ploop_ios, list) {
if ((id == ops->id || id == PLOOP_IO_AUTO) &&
-   !ops->autodetect(io) && try_module_get(ops->owner)) {
+   !ops->autodetect(io, id) && try_module_get(ops->owner)) {
mutex_unlock(&ploop_ios_mutex);
return ops;
}
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index 54c9954..db3eacd 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -1711,7 +1711,7 @@ static int dio_dump(struct ploop_io * io)
return -1;
 }
 
-static int dio_autodetect(struct ploop_io * io)
+static int dio_autodetect(struct ploop_io *io, unsigned int id)
 {
struct file  * file  = io->files.file;
struct inode * inode = file->f_mapping->host;
diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c
index 365e2e3..38599e2 100644
--- a/drivers/block/ploop/io_kaio.c
+++ b/drivers/block/ploop/io_kaio.c
@@ -1208,7 +1208,7 @@ static void kaio_issue_flush(struct ploop_io * io, struct 
ploop_request *preq)
spin_unlock_irq(&io->plo->lock);
 }
 
-static int kaio_autodetect(struct ploop_io * io)
+static int kaio_autodetect(struct ploop_io *io, unsigned int id)
 {
struct file  * file  = io->files.file;
struct inode * inode = file->f_mapping->host;
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index fe6f94e..2dc0c26 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -208,7 +208,7 @@ struct ploop_io_ops
loff_t  (*i_size_read)(struct ploop_io*);
fmode_t (*f_mode)(struct ploop_io*);
 
-   int (*autodetect)(struct ploop_io * io);
+   int (*autodetect)(struct ploop_io *io, unsigned int id);
 };
 
 static inline loff_t generic_i_size_read(struct ploop_io *io)
___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH RHEL7 COMMIT] ploop: Formulate "kaio_backed_ext4" module parameter purpose

2020-08-24 Thread Vasily Averin
The commit is pushed to "branch-rh7-3.10.0-1127.18.2.vz7.163.x-ovz" and will 
appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.18.2.vz7.163.9
-->
commit c1253660b825e125fdef5a270a8a6e0e75d3dad5
Author: Kirill Tkhai 
Date:   Tue Aug 25 09:04:55 2020 +0300

ploop: Formulate "kaio_backed_ext4" module parameter purpose

This matters in case of PLOOP_IO_AUTO is requested
in struct ploop_ctl_chunk::pctl_type:
1)not-zero is to choose io_kaio engine for ext4;
2)zero is to choose io_direct.

In case of certail PLOOP_IO_XXX is passed, the parameter
is ignored.

https://jira.sw.ru/browse/PSBM-105347
Signed-off-by: Kirill Tkhai 
---
 drivers/block/ploop/dev.c| 6 ++
 drivers/block/ploop/fmt_ploop1.c | 4 +++-
 drivers/block/ploop/io_direct.c  | 5 +++--
 drivers/block/ploop/io_kaio.c| 4 ++--
 4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 686d1b9..197faa5 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -61,6 +61,12 @@ static long user_threshold __read_mostly = 4L * 1024 * 1024; 
/* 4GB in KB */
 
 static int large_disk_support __read_mostly = 1; /* true */
 static int native_discard_support __read_mostly = 1;
+/*
+ * This matters in case of PLOOP_IO_AUTO is requested
+ * in struct ploop_ctl_chunk::pctl_type:
+ * 1)not-zero is to choose io_kaio engine for ext4;
+ * 2)zero is to choose io_direct.
+ */
 int kaio_backed_ext4 __read_mostly = 0;
 EXPORT_SYMBOL(kaio_backed_ext4);
 
diff --git a/drivers/block/ploop/fmt_ploop1.c b/drivers/block/ploop/fmt_ploop1.c
index b5f9594..0036e09 100644
--- a/drivers/block/ploop/fmt_ploop1.c
+++ b/drivers/block/ploop/fmt_ploop1.c
@@ -333,7 +333,9 @@ ploop1_open(struct ploop_delta * delta)
((u64)ph->bd_size + ph->l1_off) << 9)
delta->flags |= PLOOP_FMT_PREALLOCATED;
 
-   if (delta->io.ops->id != PLOOP_IO_DIRECT && !kaio_backed_ext4)
+   /* FIXME: is there a better place for this? */
+   if (delta->io.ops->id != PLOOP_IO_DIRECT &&
+   delta->io.files.inode->i_sb->s_magic != EXT4_SUPER_MAGIC)
set_bit(PLOOP_S_NO_FALLOC_DISCARD, &delta->plo->state);
 
return 0;
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index db3eacd..4f82b8b 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -1721,11 +1721,12 @@ static int dio_autodetect(struct ploop_io *io, unsigned 
int id)
mm_segment_t fs;
unsigned int flags;
 
-   if (kaio_backed_ext4)
-   return -1;
if (inode->i_sb->s_magic != EXT4_SUPER_MAGIC)
return -1; /* not mine */
 
+   if (id == PLOOP_IO_AUTO && kaio_backed_ext4)
+   return -1;
+
if (inode->i_sb->s_bdev == NULL) {
printk("File on FS EXT(%s) without backing device\n", s_id);
return -1;
diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c
index 38599e2..2f6164c 100644
--- a/drivers/block/ploop/io_kaio.c
+++ b/drivers/block/ploop/io_kaio.c
@@ -1138,7 +1138,6 @@ static void kaio_queue_settings(struct ploop_io * io, 
struct request_queue * q)
struct inode *inode = file->f_mapping->host;
 
if (inode->i_sb->s_magic == EXT4_SUPER_MAGIC) {
-   WARN_ON(!kaio_backed_ext4);
blk_queue_stack_limits(q, bdev_get_queue(io->files.bdev));
/*
 * There is no a way to force block engine to split a request
@@ -1214,7 +1213,8 @@ static int kaio_autodetect(struct ploop_io *io, unsigned 
int id)
struct inode * inode = file->f_mapping->host;
 
if (inode->i_sb->s_magic != FUSE_SUPER_MAGIC &&
-   (inode->i_sb->s_magic != EXT4_SUPER_MAGIC || !kaio_backed_ext4))
+   (inode->i_sb->s_magic != EXT4_SUPER_MAGIC ||
+(id == PLOOP_IO_AUTO && !kaio_backed_ext4)))
return -1; /* not mine */
 
if (!(file->f_flags & O_DIRECT)) {
___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH RH7 1/2] ploop: Add @id argument to ->autodetect()

2020-08-24 Thread Kirill Tkhai
Signed-off-by: Kirill Tkhai 
---
 drivers/block/ploop/io.c|2 +-
 drivers/block/ploop/io_direct.c |2 +-
 drivers/block/ploop/io_kaio.c   |2 +-
 include/linux/ploop/ploop.h |2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/block/ploop/io.c b/drivers/block/ploop/io.c
index 5499f9781151..ad1d365d7c6c 100644
--- a/drivers/block/ploop/io.c
+++ b/drivers/block/ploop/io.c
@@ -43,7 +43,7 @@ static struct ploop_io_ops * ploop_io_get(struct ploop_io 
*io, unsigned int id)
mutex_lock(&ploop_ios_mutex);
list_for_each_entry(ops, &ploop_ios, list) {
if ((id == ops->id || id == PLOOP_IO_AUTO) &&
-   !ops->autodetect(io) && try_module_get(ops->owner)) {
+   !ops->autodetect(io, id) && try_module_get(ops->owner)) {
mutex_unlock(&ploop_ios_mutex);
return ops;
}
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index 54c995411c45..db3eacd2d845 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -1711,7 +1711,7 @@ static int dio_dump(struct ploop_io * io)
return -1;
 }
 
-static int dio_autodetect(struct ploop_io * io)
+static int dio_autodetect(struct ploop_io *io, unsigned int id)
 {
struct file  * file  = io->files.file;
struct inode * inode = file->f_mapping->host;
diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c
index 365e2e3850d4..38599e201163 100644
--- a/drivers/block/ploop/io_kaio.c
+++ b/drivers/block/ploop/io_kaio.c
@@ -1208,7 +1208,7 @@ static void kaio_issue_flush(struct ploop_io * io, struct 
ploop_request *preq)
spin_unlock_irq(&io->plo->lock);
 }
 
-static int kaio_autodetect(struct ploop_io * io)
+static int kaio_autodetect(struct ploop_io *io, unsigned int id)
 {
struct file  * file  = io->files.file;
struct inode * inode = file->f_mapping->host;
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index fe6f94ef550c..2dc0c2690490 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -208,7 +208,7 @@ struct ploop_io_ops
loff_t  (*i_size_read)(struct ploop_io*);
fmode_t (*f_mode)(struct ploop_io*);
 
-   int (*autodetect)(struct ploop_io * io);
+   int (*autodetect)(struct ploop_io *io, unsigned int id);
 };
 
 static inline loff_t generic_i_size_read(struct ploop_io *io)


___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH RH7 2/2] ploop: Formulate "kaio_backed_ext4" module parameter purpose

2020-08-24 Thread Kirill Tkhai
This matters in case of PLOOP_IO_AUTO is requested
in struct ploop_ctl_chunk::pctl_type:
1)not-zero is to choose io_kaio engine for ext4;
2)zero is to choose io_direct.

In case of certail PLOOP_IO_XXX is passed, the parameter
is ignored.

Signed-off-by: Kirill Tkhai 
---
 drivers/block/ploop/dev.c|6 ++
 drivers/block/ploop/fmt_ploop1.c |4 +++-
 drivers/block/ploop/io_direct.c  |5 +++--
 drivers/block/ploop/io_kaio.c|4 ++--
 4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 686d1b96bdae..197faa5db05d 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -61,6 +61,12 @@ static long user_threshold __read_mostly = 4L * 1024 * 1024; 
/* 4GB in KB */
 
 static int large_disk_support __read_mostly = 1; /* true */
 static int native_discard_support __read_mostly = 1;
+/*
+ * This matters in case of PLOOP_IO_AUTO is requested
+ * in struct ploop_ctl_chunk::pctl_type:
+ * 1)not-zero is to choose io_kaio engine for ext4;
+ * 2)zero is to choose io_direct.
+ */
 int kaio_backed_ext4 __read_mostly = 0;
 EXPORT_SYMBOL(kaio_backed_ext4);
 
diff --git a/drivers/block/ploop/fmt_ploop1.c b/drivers/block/ploop/fmt_ploop1.c
index b5f95946c801..0036e09b4bf4 100644
--- a/drivers/block/ploop/fmt_ploop1.c
+++ b/drivers/block/ploop/fmt_ploop1.c
@@ -333,7 +333,9 @@ ploop1_open(struct ploop_delta * delta)
((u64)ph->bd_size + ph->l1_off) << 9)
delta->flags |= PLOOP_FMT_PREALLOCATED;
 
-   if (delta->io.ops->id != PLOOP_IO_DIRECT && !kaio_backed_ext4)
+   /* FIXME: is there a better place for this? */
+   if (delta->io.ops->id != PLOOP_IO_DIRECT &&
+   delta->io.files.inode->i_sb->s_magic != EXT4_SUPER_MAGIC)
set_bit(PLOOP_S_NO_FALLOC_DISCARD, &delta->plo->state);
 
return 0;
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index db3eacd2d845..4f82b8b5ce36 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -1721,11 +1721,12 @@ static int dio_autodetect(struct ploop_io *io, unsigned 
int id)
mm_segment_t fs;
unsigned int flags;
 
-   if (kaio_backed_ext4)
-   return -1;
if (inode->i_sb->s_magic != EXT4_SUPER_MAGIC)
return -1; /* not mine */
 
+   if (id == PLOOP_IO_AUTO && kaio_backed_ext4)
+   return -1;
+
if (inode->i_sb->s_bdev == NULL) {
printk("File on FS EXT(%s) without backing device\n", s_id);
return -1;
diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c
index 38599e201163..2f6164cc16fd 100644
--- a/drivers/block/ploop/io_kaio.c
+++ b/drivers/block/ploop/io_kaio.c
@@ -1138,7 +1138,6 @@ static void kaio_queue_settings(struct ploop_io * io, 
struct request_queue * q)
struct inode *inode = file->f_mapping->host;
 
if (inode->i_sb->s_magic == EXT4_SUPER_MAGIC) {
-   WARN_ON(!kaio_backed_ext4);
blk_queue_stack_limits(q, bdev_get_queue(io->files.bdev));
/*
 * There is no a way to force block engine to split a request
@@ -1214,7 +1213,8 @@ static int kaio_autodetect(struct ploop_io *io, unsigned 
int id)
struct inode * inode = file->f_mapping->host;
 
if (inode->i_sb->s_magic != FUSE_SUPER_MAGIC &&
-   (inode->i_sb->s_magic != EXT4_SUPER_MAGIC || !kaio_backed_ext4))
+   (inode->i_sb->s_magic != EXT4_SUPER_MAGIC ||
+(id == PLOOP_IO_AUTO && !kaio_backed_ext4)))
return -1; /* not mine */
 
if (!(file->f_flags & O_DIRECT)) {


___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH RHEL7 COMMIT] ms/kernel/kmod: fix use-after-free of the sub_info structure

2020-08-24 Thread Vasily Averin
The commit is pushed to "branch-rh7-3.10.0-1127.18.2.vz7.163.x-ovz" and will 
appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.18.2.vz7.163.8
-->
commit b970da536cb20510058d6013b29b0ef34e3228c6
Author: Martin Schwidefsky 
Date:   Mon Aug 24 16:47:51 2020 +0300

ms/kernel/kmod: fix use-after-free of the sub_info structure

Found this in the message log on a s390 system:

BUG kmalloc-192 (Not tainted): Poison overwritten
Disabling lock debugging due to kernel taint
INFO: 0x684761f4-0x684761f7. First byte 0xff instead of 
0x6b
INFO: Allocated in call_usermodehelper_setup+0x70/0x128 age=71 cpu=2 
pid=648
 __slab_alloc.isra.47.constprop.56+0x5f6/0x658
 kmem_cache_alloc_trace+0x106/0x408
 call_usermodehelper_setup+0x70/0x128
 call_usermodehelper+0x62/0x90
 cgroup_release_agent+0x178/0x1c0
 process_one_work+0x36e/0x680
 worker_thread+0x2f0/0x4f8
 kthread+0x10a/0x120
 kernel_thread_starter+0x6/0xc
 kernel_thread_starter+0x0/0xc
INFO: Freed in call_usermodehelper_exec+0x110/0x1b8 age=71 cpu=2 pid=648
 __slab_free+0x94/0x560
 kfree+0x364/0x3e0
 call_usermodehelper_exec+0x110/0x1b8
 cgroup_release_agent+0x178/0x1c0
 process_one_work+0x36e/0x680
 worker_thread+0x2f0/0x4f8
 kthread+0x10a/0x120
 kernel_thread_starter+0x6/0xc
 kernel_thread_starter+0x0/0xc

There is a use-after-free bug on the subprocess_info structure allocated
by the user mode helper.  In case do_execve() returns with an error
call_usermodehelper() stores the error code to sub_info->retval, but
sub_info can already have been freed.

Regarding UMH_NO_WAIT, the sub_info structure can be freed by
__call_usermodehelper() before the worker thread returns from
do_execve(), allowing memory corruption when do_execve() failed after
exec_mmap() is called.

Regarding UMH_WAIT_EXEC, the call to umh_complete() allows
call_usermodehelper_exec() to continue which then frees sub_info.

To fix this race the code needs to make sure that the call to
call_usermodehelper_freeinfo() is always done after the last store to
sub_info->retval.

Signed-off-by: Martin Schwidefsky 
Reviewed-by: Oleg Nesterov 
Cc: Tetsuo Handa 
Signed-off-by: Andrew Morton 
Signed-off-by: Linus Torvalds 

https://jira.sw.ru/browse/PSBM-107061
(cherry-picked from commit 0baf2a4dbf75abb7c186fd6c8d55d27aaa354a29)
Signed-off-by: Andrey Ryabinin 
---
 kernel/kmod.c | 76 +--
 1 file changed, 37 insertions(+), 39 deletions(-)

diff --git a/kernel/kmod.c b/kernel/kmod.c
index 7fc0ba9..de2bcfd 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -585,12 +585,34 @@ int __request_module(bool wait, const char *fmt, ...)
 EXPORT_SYMBOL(__request_module);
 #endif /* CONFIG_MODULES */
 
+static void call_usermodehelper_freeinfo(struct subprocess_info *info)
+{
+   if (info->cleanup)
+   (*info->cleanup)(info);
+   kfree(info);
+}
+
+static void umh_complete(struct subprocess_info *sub_info)
+{
+   struct completion *comp = xchg(&sub_info->complete, NULL);
+   /*
+* See call_usermodehelper_exec(). If xchg() returns NULL
+* we own sub_info, the UMH_KILLABLE caller has gone away
+* or the caller used UMH_NO_WAIT.
+*/
+   if (comp)
+   complete(comp);
+   else
+   call_usermodehelper_freeinfo(sub_info);
+}
+
 /*
  * This is the task which runs the usermode application
  */
 static int call_usermodehelper(void *data)
 {
struct subprocess_info *sub_info = data;
+   int wait = sub_info->wait & ~UMH_KILLABLE;
struct cred *new;
int retval;
 
@@ -607,7 +629,7 @@ static int call_usermodehelper(void *data)
retval = -ENOMEM;
new = prepare_kernel_cred(current);
if (!new)
-   goto fail;
+   goto out;
 
spin_lock(&umh_sysctl_lock);
new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset);
@@ -619,7 +641,7 @@ static int call_usermodehelper(void *data)
retval = sub_info->init(sub_info, new);
if (retval) {
abort_creds(new);
-   goto fail;
+   goto out;
}
}
 
@@ -628,12 +650,13 @@ static int call_usermodehelper(void *data)
retval = do_execve(getname_kernel(sub_info->path),
   (const char __user *const __user *)sub_info->argv,
   (const char __user *const __user *)sub_info->envp);
+out:
+   sub_info->retval = retval;
+   /* wait_for_helper() will call umh_complete if UHM_WAIT_PROC. */
+   if (wait != UMH_WAIT_PROC)
+   um

[Devel] [PATCH rh7] ms/kernel/kmod: fix use-after-free of the sub_info structure

2020-08-24 Thread Andrey Ryabinin
From: Martin Schwidefsky 

Found this in the message log on a s390 system:

BUG kmalloc-192 (Not tainted): Poison overwritten
Disabling lock debugging due to kernel taint
INFO: 0x684761f4-0x684761f7. First byte 0xff instead of 0x6b
INFO: Allocated in call_usermodehelper_setup+0x70/0x128 age=71 cpu=2 pid=648
 __slab_alloc.isra.47.constprop.56+0x5f6/0x658
 kmem_cache_alloc_trace+0x106/0x408
 call_usermodehelper_setup+0x70/0x128
 call_usermodehelper+0x62/0x90
 cgroup_release_agent+0x178/0x1c0
 process_one_work+0x36e/0x680
 worker_thread+0x2f0/0x4f8
 kthread+0x10a/0x120
 kernel_thread_starter+0x6/0xc
 kernel_thread_starter+0x0/0xc
INFO: Freed in call_usermodehelper_exec+0x110/0x1b8 age=71 cpu=2 pid=648
 __slab_free+0x94/0x560
 kfree+0x364/0x3e0
 call_usermodehelper_exec+0x110/0x1b8
 cgroup_release_agent+0x178/0x1c0
 process_one_work+0x36e/0x680
 worker_thread+0x2f0/0x4f8
 kthread+0x10a/0x120
 kernel_thread_starter+0x6/0xc
 kernel_thread_starter+0x0/0xc

There is a use-after-free bug on the subprocess_info structure allocated
by the user mode helper.  In case do_execve() returns with an error
call_usermodehelper() stores the error code to sub_info->retval, but
sub_info can already have been freed.

Regarding UMH_NO_WAIT, the sub_info structure can be freed by
__call_usermodehelper() before the worker thread returns from
do_execve(), allowing memory corruption when do_execve() failed after
exec_mmap() is called.

Regarding UMH_WAIT_EXEC, the call to umh_complete() allows
call_usermodehelper_exec() to continue which then frees sub_info.

To fix this race the code needs to make sure that the call to
call_usermodehelper_freeinfo() is always done after the last store to
sub_info->retval.

Signed-off-by: Martin Schwidefsky 
Reviewed-by: Oleg Nesterov 
Cc: Tetsuo Handa 
Signed-off-by: Andrew Morton 
Signed-off-by: Linus Torvalds 

https://jira.sw.ru/browse/PSBM-107061
(cherry-picked from commit 0baf2a4dbf75abb7c186fd6c8d55d27aaa354a29)
Signed-off-by: Andrey Ryabinin 
---
 kernel/kmod.c | 76 +--
 1 file changed, 37 insertions(+), 39 deletions(-)

diff --git a/kernel/kmod.c b/kernel/kmod.c
index 7fc0ba9e3216..de2bcfdc94d0 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -585,12 +585,34 @@ int __request_module(bool wait, const char *fmt, ...)
 EXPORT_SYMBOL(__request_module);
 #endif /* CONFIG_MODULES */
 
+static void call_usermodehelper_freeinfo(struct subprocess_info *info)
+{
+   if (info->cleanup)
+   (*info->cleanup)(info);
+   kfree(info);
+}
+
+static void umh_complete(struct subprocess_info *sub_info)
+{
+   struct completion *comp = xchg(&sub_info->complete, NULL);
+   /*
+* See call_usermodehelper_exec(). If xchg() returns NULL
+* we own sub_info, the UMH_KILLABLE caller has gone away
+* or the caller used UMH_NO_WAIT.
+*/
+   if (comp)
+   complete(comp);
+   else
+   call_usermodehelper_freeinfo(sub_info);
+}
+
 /*
  * This is the task which runs the usermode application
  */
 static int call_usermodehelper(void *data)
 {
struct subprocess_info *sub_info = data;
+   int wait = sub_info->wait & ~UMH_KILLABLE;
struct cred *new;
int retval;
 
@@ -607,7 +629,7 @@ static int call_usermodehelper(void *data)
retval = -ENOMEM;
new = prepare_kernel_cred(current);
if (!new)
-   goto fail;
+   goto out;
 
spin_lock(&umh_sysctl_lock);
new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset);
@@ -619,7 +641,7 @@ static int call_usermodehelper(void *data)
retval = sub_info->init(sub_info, new);
if (retval) {
abort_creds(new);
-   goto fail;
+   goto out;
}
}
 
@@ -628,12 +650,13 @@ static int call_usermodehelper(void *data)
retval = do_execve(getname_kernel(sub_info->path),
   (const char __user *const __user *)sub_info->argv,
   (const char __user *const __user *)sub_info->envp);
+out:
+   sub_info->retval = retval;
+   /* wait_for_helper() will call umh_complete if UHM_WAIT_PROC. */
+   if (wait != UMH_WAIT_PROC)
+   umh_complete(sub_info);
if (!retval)
return 0;
-
-   /* Exec failed? */
-fail:
-   sub_info->retval = retval;
do_exit(0);
 }
 
@@ -644,26 +667,6 @@ static int call_helper(void *data)
return call_usermodehelper(data);
 }
 
-static void call_usermodehelper_freeinfo(struct subprocess_info *info)
-{
-   if (info->cleanup)
-   (*info->cleanup)(info);
-   kfree(info);
-}
-
-static void umh_complete(struct subprocess_info *sub_info)
-{
-   struct completion *comp = xchg(&sub_i

[Devel] [PATCH RHEL7 COMMIT] ms/netfilter: nfnetlink: correctly validate length of batch messages (take 2)

2020-08-24 Thread Vasily Averin
The commit is pushed to "branch-rh7-3.10.0-1127.18.2.vz7.163.x-ovz" and will 
appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.18.2.vz7.163.6
-->
commit 57932314acbae8fac4f907029f29a15b1497ea10
Author: Andrey Ryabinin 
Date:   Mon Aug 24 12:02:45 2020 +0300

ms/netfilter: nfnetlink: correctly validate length of batch messages (take 
2)

We did backport of the upstream commit c58d6c93680f
  ("netfilter: nfnetlink: correctly validate length of batch messages")
a while ago in scope of https://jira.sw.ru/browse/PSBM-57511.
Our backport is commit defecd27dbb0
  ("ms/netfilter: nfnetlink: correctly validate length of batch messages")

However the backport was incomplete, hence we can observe:
   skbuff: skb_over_panic: text:b0b5ea8a len:-48 put:-48 
head:880055082c80 data:880055082c80 tail:0xffd0 end:0xc0 dev:
   [ cut here ]
   kernel BUG at net/core/skbuff.c:131!

Backport the missing part to finally fix this.

https://jira.sw.ru/browse/PSBM-106395
Signed-off-by: Andrey Ryabinin 
---
 net/netfilter/nfnetlink.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index a48f185..e22f84b 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -331,8 +331,9 @@ replay:
if (nlh->nlmsg_len < NLMSG_HDRLEN ||
skb->len < nlh->nlmsg_len ||
nlmsg_len(nlh) < sizeof(struct nfgenmsg)) {
-   err = -EINVAL;
-   goto ack;
+   nfnl_err_reset(&err_list);
+   status |= NFNL_BATCH_FAILURE;
+   goto done;
}
 
/* Only requests are handled by the kernel */
___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel