Revision e94c6101e151b019b8babc518ac2a6ada644a5a1 authored by Maximilian Heyne on 15 July 2022, 22:51:07 UTC, committed by Juergen Gross on 12 August 2022, 10:13:51 UTC
In some use cases[1], the backend is created while the frontend doesn't
support the persistent grants feature, but later the frontend can be
changed to support the feature and reconnect.  In the past, 'blkback'
enabled the persistent grants feature since it unconditionally checked
if frontend supports the persistent grants feature for every connect
('connect_ring()') and decided whether it should use persistent grans or
not.

However, commit aac8a70db24b ("xen-blkback: add a parameter for
disabling of persistent grants") has mistakenly changed the behavior.
It made the frontend feature support check to not be repeated once it
shown the 'feature_persistent' as 'false', or the frontend doesn't
support persistent grants.

This commit changes the behavior of the parameter to make effect for
every connect, so that the previous workflow can work again as expected.

[1] https://lore.kernel.org/xen-devel/CAJwUmVB6H3iTs-C+U=v-pwJB7-_ZRHPxHzKRJZ22xEPW7z8a=g@mail.gmail.com/

Reported-by: Andrii Chepurnyi <andrii.chepurnyi82@gmail.com>
Fixes: aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent grants")
Cc: <stable@vger.kernel.org> # 5.10.x
Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
Signed-off-by: SeongJae Park <sj@kernel.org>
Reviewed-by: Maximilian Heyne <mheyne@amazon.de>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20220715225108.193398-3-sj@kernel.org
Signed-off-by: Juergen Gross <jgross@suse.com>
1 parent fc9be61
Raw File
bpf-fancy.c
// SPDX-License-Identifier: GPL-2.0
/*
 * Seccomp BPF example using a macro-based generator.
 *
 * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
 * Author: Will Drewry <wad@chromium.org>
 *
 * The code may be used by anyone for any purpose,
 * and can serve as a starting point for developing
 * applications using prctl(PR_ATTACH_SECCOMP_FILTER).
 */

#include <linux/filter.h>
#include <linux/seccomp.h>
#include <linux/unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/prctl.h>
#include <unistd.h>

#include "bpf-helper.h"

#ifndef PR_SET_NO_NEW_PRIVS
#define PR_SET_NO_NEW_PRIVS 38
#endif

int main(int argc, char **argv)
{
	struct bpf_labels l = {
		.count = 0,
	};
	static const char msg1[] = "Please type something: ";
	static const char msg2[] = "You typed: ";
	char buf[256];
	struct sock_filter filter[] = {
		/* TODO: LOAD_SYSCALL_NR(arch) and enforce an arch */
		LOAD_SYSCALL_NR,
		SYSCALL(__NR_exit, ALLOW),
		SYSCALL(__NR_exit_group, ALLOW),
		SYSCALL(__NR_write, JUMP(&l, write_fd)),
		SYSCALL(__NR_read, JUMP(&l, read)),
		DENY,  /* Don't passthrough into a label */

		LABEL(&l, read),
		ARG(0),
		JNE(STDIN_FILENO, DENY),
		ARG(1),
		JNE((unsigned long)buf, DENY),
		ARG(2),
		JGE(sizeof(buf), DENY),
		ALLOW,

		LABEL(&l, write_fd),
		ARG(0),
		JEQ(STDOUT_FILENO, JUMP(&l, write_buf)),
		JEQ(STDERR_FILENO, JUMP(&l, write_buf)),
		DENY,

		LABEL(&l, write_buf),
		ARG(1),
		JEQ((unsigned long)msg1, JUMP(&l, msg1_len)),
		JEQ((unsigned long)msg2, JUMP(&l, msg2_len)),
		JEQ((unsigned long)buf, JUMP(&l, buf_len)),
		DENY,

		LABEL(&l, msg1_len),
		ARG(2),
		JLT(sizeof(msg1), ALLOW),
		DENY,

		LABEL(&l, msg2_len),
		ARG(2),
		JLT(sizeof(msg2), ALLOW),
		DENY,

		LABEL(&l, buf_len),
		ARG(2),
		JLT(sizeof(buf), ALLOW),
		DENY,
	};
	struct sock_fprog prog = {
		.filter = filter,
		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
	};
	ssize_t bytes;
	bpf_resolve_jumps(&l, filter, sizeof(filter)/sizeof(*filter));

	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
		perror("prctl(NO_NEW_PRIVS)");
		return 1;
	}

	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
		perror("prctl(SECCOMP)");
		return 1;
	}
	syscall(__NR_write, STDOUT_FILENO, msg1, strlen(msg1));
	bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf)-1);
	bytes = (bytes > 0 ? bytes : 0);
	syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2));
	syscall(__NR_write, STDERR_FILENO, buf, bytes);
	/* Now get killed */
	syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)+2);
	return 0;
}
back to top