Commit f326061d authored by Kirill Tkhai's avatar Kirill Tkhai Committed by Andrei Vagin

sfds: Protect service fds reuse

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
v5: Add comment and print sfd type before BUG().
Signed-off-by: 's avatarKirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 2f301786
...@@ -27,6 +27,7 @@ enum sfd_type { ...@@ -27,6 +27,7 @@ enum sfd_type {
}; };
struct pstree_item; struct pstree_item;
extern bool sfds_protected;
extern void set_proc_self_fd(int fd); extern void set_proc_self_fd(int fd);
extern int clone_service_fd(int id); extern int clone_service_fd(int id);
......
...@@ -473,12 +473,27 @@ int service_fd_min_fd(struct pstree_item *item) ...@@ -473,12 +473,27 @@ int service_fd_min_fd(struct pstree_item *item)
} }
static DECLARE_BITMAP(sfd_map, SERVICE_FD_MAX); static DECLARE_BITMAP(sfd_map, SERVICE_FD_MAX);
/*
* Variable for marking areas of code, where service fds modifications
* are prohibited. It's used to safe them from reusing their numbers
* by ordinary files. See install_service_fd() and close_service_fd().
*/
bool sfds_protected = false;
static void sfds_protection_bug(enum sfd_type type)
{
pr_err("Service fd %u is being modified in protected context\n", type);
print_stack_trace(current ? vpid(current) : 0);
BUG();
}
int install_service_fd(enum sfd_type type, int fd) int install_service_fd(enum sfd_type type, int fd)
{ {
int sfd = __get_service_fd(type, service_fd_id); int sfd = __get_service_fd(type, service_fd_id);
BUG_ON((int)type <= SERVICE_FD_MIN || (int)type >= SERVICE_FD_MAX); BUG_ON((int)type <= SERVICE_FD_MIN || (int)type >= SERVICE_FD_MAX);
if (sfds_protected && !test_bit(type, sfd_map))
sfds_protection_bug(type);
if (dup3(fd, sfd, O_CLOEXEC) != sfd) { if (dup3(fd, sfd, O_CLOEXEC) != sfd) {
pr_perror("Dup %d -> %d failed", fd, sfd); pr_perror("Dup %d -> %d failed", fd, sfd);
...@@ -508,6 +523,9 @@ int close_service_fd(enum sfd_type type) ...@@ -508,6 +523,9 @@ int close_service_fd(enum sfd_type type)
{ {
int fd; int fd;
if (sfds_protected)
sfds_protection_bug(type);
fd = get_service_fd(type); fd = get_service_fd(type);
if (fd < 0) if (fd < 0)
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment