From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alex Williamson Subject: [PATCH v2] device-assignment: chmod the rom file before opening read/write Date: Tue, 04 Jan 2011 11:45:49 -0700 Message-ID: <20110104184516.28545.73442.stgit@s20.home> References: <20110104180649.23471.81148.stgit@s20.home> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Cc: alex.williamson@redhat.com, chrisw@redhat.com To: kvm@vger.kernel.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:51702 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751037Ab1ADSpu (ORCPT ); Tue, 4 Jan 2011 13:45:50 -0500 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p04Ijo12000871 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 4 Jan 2011 13:45:50 -0500 In-Reply-To: <20110104180649.23471.81148.stgit@s20.home> Sender: kvm-owner@vger.kernel.org List-ID: The PCI sysfs rom file is exposed read-only by default, but we need to write to it to enable and disable the ROM around the read. When running as root, the code works fine as is, but when running de-privileged via libvirt, the fopen("r+") will fail if the file doesn't have owner write permissions. libvirt already gives us ownership of the file, so we can toggle this around the short usage window ourselves. Signed-off-by: Alex Williamson Acked-by: Chris Wright --- hw/device-assignment.c | 19 ++++++++++++------- 1 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 8446cd4..81c77ae 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1866,16 +1866,18 @@ static void assigned_dev_load_option_rom(AssignedDevice *dev) return; } - if (access(rom_file, F_OK)) { - fprintf(stderr, "pci-assign: Insufficient privileges for %s\n", - rom_file); + /* The ROM file is typically mode 0400, ensure that it's at least 0600 + * for the following fopen to succeed when qemu is de-privileged. */ + if (chmod(rom_file, (st.st_mode & ALLPERMS) | S_IRUSR | S_IWUSR)) { + fprintf(stderr, "pci-assign: Insufficient privileges for %s (%s)\n", + rom_file, strerror(errno)); return; } /* Write "1" to the ROM file to enable it */ fp = fopen(rom_file, "r+"); if (fp == NULL) { - return; + goto restore_rom; } val = 1; if (fwrite(&val, 1, 1, fp) != 1) { @@ -1895,17 +1897,20 @@ static void assigned_dev_load_option_rom(AssignedDevice *dev) "or load from file with romfile=\n", rom_file); qemu_ram_free(dev->dev.rom_offset); dev->dev.rom_offset = 0; - goto close_rom; + goto disable_rom; } pci_register_bar(&dev->dev, PCI_ROM_SLOT, st.st_size, 0, pci_map_option_rom); -close_rom: +disable_rom: /* Write "0" to disable ROM */ fseek(fp, 0, SEEK_SET); val = 0; - if (!fwrite(&val, 1, 1, fp)) { + if (fwrite(&val, 1, 1, fp) != 1) { DEBUG("%s\n", "Failed to disable pci-sysfs rom file"); } +close_rom: fclose(fp); +restore_rom: + chmod(rom_file, st.st_mode & ALLPERMS); }