[v4,07/19] sfds: Protect service fds reuse

Submitted by Kirill Tkhai on Jan. 10, 2018, 2:01 p.m.

Details

Message ID 151559288412.31108.10374368638510708530.stgit@localhost.localdomain
State New
Series "Introduce custom per-task service fds placement"
Headers show

Commit Message

Kirill Tkhai Jan. 10, 2018, 2:01 p.m.
This patch introduces sfds_protected, which allows
to mask areas, where modifications of sfds are prohibited.
That guarantees, that populated sfds won't be reused.

v4: New

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/include/servicefd.h |    1 +
 criu/util.c              |   13 +++++++++++++
 2 files changed, 14 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/include/servicefd.h b/criu/include/servicefd.h
index 6266b5324..812396310 100644
--- a/criu/include/servicefd.h
+++ b/criu/include/servicefd.h
@@ -27,6 +27,7 @@  enum sfd_type {
 };
 
 struct pstree_item;
+extern bool sfds_protected;
 
 extern void set_proc_self_fd(int fd);
 extern int clone_service_fd(int id);
diff --git a/criu/util.c b/criu/util.c
index d90bab09c..c3665f10b 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -473,12 +473,22 @@  int service_fd_min_fd(struct pstree_item *item)
 }
 
 static DECLARE_BITMAP(sfd_map, SERVICE_FD_MAX);
+bool sfds_protected = false;
+
+static void sfds_protection_bug(void)
+{
+	pr_err("Service fd is being modified in protected context\n");
+	print_stack_trace(current ? vpid(current) : 0);
+	BUG();
+}
 
 int install_service_fd(enum sfd_type type, int fd)
 {
 	int sfd = __get_service_fd(type, service_fd_id);
 
 	BUG_ON((int)type <= SERVICE_FD_MIN || (int)type >= SERVICE_FD_MAX);
+	if (sfds_protected && !test_bit(type, sfd_map))
+		sfds_protection_bug();
 
 	if (dup3(fd, sfd, O_CLOEXEC) != sfd) {
 		pr_perror("Dup %d -> %d failed", fd, sfd);
@@ -508,6 +518,9 @@  int close_service_fd(enum sfd_type type)
 {
 	int fd;
 
+	if (sfds_protected)
+		sfds_protection_bug();
+
 	fd = get_service_fd(type);
 	if (fd < 0)
 		return 0;

Comments

Andrey Vagin Jan. 11, 2018, 5:24 p.m.
On Wed, Jan 10, 2018 at 05:01:24PM +0300, Kirill Tkhai wrote:
> This patch introduces sfds_protected, which allows
> to mask areas, where modifications of sfds are prohibited.
> That guarantees, that populated sfds won't be reused.
> 
> v4: New
> 
> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
> ---
>  criu/include/servicefd.h |    1 +
>  criu/util.c              |   13 +++++++++++++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/criu/include/servicefd.h b/criu/include/servicefd.h
> index 6266b5324..812396310 100644
> --- a/criu/include/servicefd.h
> +++ b/criu/include/servicefd.h
> @@ -27,6 +27,7 @@ enum sfd_type {
>  };
>  
>  struct pstree_item;
> +extern bool sfds_protected;

pls add a comment. What does sfds_protected mean and why do we need it?
>  
>  extern void set_proc_self_fd(int fd);
>  extern int clone_service_fd(int id);
> diff --git a/criu/util.c b/criu/util.c
> index d90bab09c..c3665f10b 100644
> --- a/criu/util.c
> +++ b/criu/util.c
> @@ -473,12 +473,22 @@ int service_fd_min_fd(struct pstree_item *item)
>  }
>  
>  static DECLARE_BITMAP(sfd_map, SERVICE_FD_MAX);
> +bool sfds_protected = false;
> +
> +static void sfds_protection_bug(void)
> +{
> +	pr_err("Service fd is being modified in protected context\n");
> +	print_stack_trace(current ? vpid(current) : 0);
> +	BUG();
> +}
>  
>  int install_service_fd(enum sfd_type type, int fd)
>  {
>  	int sfd = __get_service_fd(type, service_fd_id);
>  
>  	BUG_ON((int)type <= SERVICE_FD_MIN || (int)type >= SERVICE_FD_MAX);
> +	if (sfds_protected && !test_bit(type, sfd_map))
> +		sfds_protection_bug();
>  
>  	if (dup3(fd, sfd, O_CLOEXEC) != sfd) {
>  		pr_perror("Dup %d -> %d failed", fd, sfd);
> @@ -508,6 +518,9 @@ int close_service_fd(enum sfd_type type)
>  {
>  	int fd;
>  
> +	if (sfds_protected)
> +		sfds_protection_bug();
> +
>  	fd = get_service_fd(type);
>  	if (fd < 0)
>  		return 0;
>