예제 #1
0
static XConfigScreenPtr clone_screen(XConfigScreenPtr screen0, int idx)
{
    XConfigScreenPtr screen = nvalloc(sizeof(XConfigScreenRec));
    
    screen->identifier = nvasprintf("%s (%d)", screen0->identifier, idx);
    
    screen->device = clone_device(screen0->device, idx);
    screen->device_name = nvstrdup(screen->device->identifier);
    
    screen->monitor = screen0->monitor;
    screen->monitor_name = nvstrdup(screen0->monitor_name);
    
    screen->defaultdepth = screen0->defaultdepth;
    
    screen->displays = clone_display_list(screen0->displays);
    
    screen->options = xconfigOptionListDup(screen0->options);
    if (screen0->comment) screen->comment = nvstrdup(screen0->comment);

    /* insert the new screen after the original screen */

    screen->next = screen0->next;
    screen0->next = screen;

    return screen;
    
} /* clone_screen() */
/*
 * Iterate over the list of kernel modules from the manifest file; generate
 * and store module information records for each module in the Package.
 */
static int parse_kernel_modules_list(Package *p, char *list) {
    char *name;

    p->num_kernel_modules = 0; /* in case this gets called more than once */

    for (name = strtok(list, " "); name; name = strtok(NULL, " ")) {
        KernelModuleInfo *module;
        p->kernel_modules = nvrealloc(p->kernel_modules,
                                      (p->num_kernel_modules + 1) *
                                      sizeof(p->kernel_modules[0]));
        module = p->kernel_modules + p->num_kernel_modules;
        memset(module, 0, sizeof(*module));

        module->module_name = nvstrdup(name);
        module->module_filename = nvstrcat(name, ".ko", NULL);
        module->has_separate_interface_file = has_separate_interface_file(name);
        if (module->has_separate_interface_file) {
            char *core_binary = nvidia_to_nv(name, "-kernel.o_binary");
            module->interface_filename = nvidia_to_nv(name, "-linux.o");
            module->core_object_name = nvstrcat(name, "/", core_binary, NULL);
            nvfree(core_binary);
        }
        populate_optional_module_info(module);

        p->num_kernel_modules++;
    }

    return p->num_kernel_modules;
}
예제 #3
0
static void create_adjacencies(Options *op, XConfigPtr config,
                               XConfigLayoutPtr layout)
{
    XConfigAdjacencyPtr adj, prev_adj;
    XConfigScreenPtr screen;
    int i;

    i = 0;
    prev_adj = NULL;
    
    for (screen = config->screens; screen; screen = screen->next) {
        
        adj = nvalloc(sizeof(XConfigAdjacencyRec));
        
        adj->scrnum = i;
        adj->screen_name = nvstrdup(screen->identifier);
        adj->screen = screen;
        
        if (prev_adj) {
            prev_adj->next = adj;
        } else {
            layout->adjacencies = adj;
        }
        
        prev_adj = adj;
        i++;
    }
    
    xconfigGenerateAssignScreenAdjacencies(layout);
    
} /* create_adjacencies() */
예제 #4
0
static char *create_display_device_target_string(CtrlTarget *t,
                                                 const ConfigProperties *conf)
{
    char *target_name = NULL;
    char *target_prefix_name = NULL;
    char *display_name = NULL;
    char *s;

    if (t->protoNames[NV_DPY_PROTO_NAME_RANDR]) {
        target_name = t->protoNames[NV_DPY_PROTO_NAME_RANDR];
    }

    /* If we don't have a target name here, use the full name and return. */
    if (!target_name) {
        return nvstrdup(t->name);
    }

    /* Get the display name if the user requested it to be used. */
    if (conf->booleans &
        CONFIG_PROPERTIES_INCLUDE_DISPLAY_NAME_IN_CONFIG_FILE) {
        display_name = NvCtrlGetDisplayName(t);
    }

    /* Get the target type prefix. */
    target_prefix_name = nvstrdup(t->targetTypeInfo->parsed_name);
    nvstrtoupper(target_prefix_name);

    /* Build the string */
    if (display_name && target_prefix_name) {
        s = nvasprintf("%s[%s:%s]", display_name,
                       target_prefix_name, target_name);
    } else if (target_prefix_name) {
        s = nvasprintf("[%s:%s]", target_prefix_name, target_name);
    } else if (display_name) {
        s = nvasprintf("%s[%s]", display_name, target_name);
    } else {
        s = nvasprintf("[%s]", target_name);
    }

    free(target_prefix_name);
    free(display_name);

    return s;
}
예제 #5
0
void ctk_help_data_list_prepend(GList **list,
                                const gchar *label,
                                const gchar *help_text,
                                const gchar *extended_help_text)
{
    CtkHelpDataItem *item;

    if (!label || !help_text) {
        return;
    }

    item = nvalloc(sizeof(CtkHelpDataItem));

    item->label = nvstrdup(label);
    item->help_text = nvstrdup(help_text);
    item->extended_help_text = extended_help_text ?
                               nvstrdup(extended_help_text) : NULL;

    *list = g_list_prepend(*list, item);
}
예제 #6
0
static XConfigDisplayPtr clone_display_list(XConfigDisplayPtr display0)
{
    XConfigDisplayPtr d = NULL, prev = NULL, head = NULL;
    
    while (display0) {
        d = nvalloc(sizeof(XConfigDisplayRec));
        memcpy(d, display0, sizeof(XConfigDisplayRec));
        if (display0->visual) d->visual = nvstrdup(display0->visual);
        if (display0->comment) d->comment = nvstrdup(display0->comment);
        d->options = xconfigOptionListDup(display0->options);
        d->next = NULL;
        if (prev) prev->next = d;
        if (!head) head = d;
        prev = d;
        display0 = display0->next;
    }
    
    return head;
    
} /* clone_display_list() */
예제 #7
0
static XConfigDevicePtr clone_device(XConfigDevicePtr device0, int idx)
{
    XConfigDevicePtr device;

    device = nvalloc(sizeof(XConfigDeviceRec));
    
    device->identifier = nvasprintf("%s (%d)", device0->identifier, idx);
    
    if (device0->vendor)  device->vendor  = nvstrdup(device0->vendor);
    if (device0->board)   device->board   = nvstrdup(device0->board);
    if (device0->chipset) device->chipset = nvstrdup(device0->chipset);
    if (device0->busid)   device->busid   = nvstrdup(device0->busid);
    if (device0->card)    device->card    = nvstrdup(device0->card);
    if (device0->driver)  device->driver  = nvstrdup(device0->driver);
    if (device0->ramdac)  device->ramdac  = nvstrdup(device0->ramdac);
    if (device0->comment) device->comment = nvstrdup(device0->comment);

    /* these are needed for multiple X screens on one GPU */

    device->screen = idx;
    device0->screen = 0;

    device->chipid = -1;
    device->chiprev = -1;
    device->irq = -1;

    device->options = xconfigOptionListDup(device0->options);
    
    /* insert the new device after the original device */
    
    device->next = device0->next;
    device0->next = device;

    return device;
    
} /* clone_device() */
예제 #8
0
static void send_control(int sock, char *string, ...)
{
    va_list args;
    char *line = NULL;
    char *newline;
    char *s = NULL;

    line = nvstrdup(string);
        
    va_start(args, string);
    s = va_arg(args, char *);
    while (s) {
        newline = nvstrcat(line, s, NULL);
        nvfree(line);
        line = newline;
        s = va_arg(args, char *);
    }
    va_end(args);

    write(sock, line, strlen(line));
    nvfree(line);

} /* send_control() */
static Package *parse_manifest (Options *op)
{
    char *buf, *c, *tmpstr;
    int line;
    int fd, ret, len = 0;
    struct stat stat_buf;
    Package *p;
    char *manifest = MAP_FAILED, *ptr;
    int opengl_files_packaged = FALSE;

    p = (Package *) nvalloc(sizeof (Package));

    /* open the manifest file */

    if ((fd = open(".manifest", O_RDONLY)) == -1) {
        ui_error(op, "No package found for installation.  Please run "
                 "this utility with the '--help' option for usage "
                 "information.");
        goto fail;
    }
    
    if (fstat(fd, &stat_buf) == -1) goto cannot_open;
    
    len = stat_buf.st_size;

    manifest = mmap(0, len, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
    if (manifest == MAP_FAILED) goto cannot_open;
    
    /* the first line is the description */

    line = 1;
    p->description = get_next_line(manifest, &ptr, manifest, len);
    if (!p->description) goto invalid_manifest_file;
    
    /* the second line is the version */
    
    line++;
    p->version = get_next_line(ptr, &ptr, manifest, len);
    if (!p->version) goto invalid_manifest_file;
    
    /* Ignore the third line */

    line++;
    nvfree(get_next_line(ptr, &ptr, manifest, len));

    /* the fourth line is the list of kernel modules. */

    line++;
    tmpstr = get_next_line(ptr, &ptr, manifest, len);
    if (parse_kernel_modules_list(p, tmpstr) == 0) {
        goto invalid_manifest_file;
    }
    nvfree(tmpstr);

    /*
     * set the default value of excluded_kernel_modules to an empty, heap
     * allocated string so that it can be freed and won't prematurely end
     * an nvstrcat()ed string when unset.
     */

    p->excluded_kernel_modules = nvstrdup("");

    /*
     * ignore the fifth and sixth lines
     */

    line++;
    nvfree(get_next_line(ptr, &ptr, manifest, len));
    line++;
    nvfree(get_next_line(ptr, &ptr, manifest, len));

    /* the seventh line is the kernel module build directory */

    line++;
    p->kernel_module_build_directory = get_next_line(ptr, &ptr, manifest, len);
    if (!p->kernel_module_build_directory) goto invalid_manifest_file;
    remove_trailing_slashes(p->kernel_module_build_directory);

    /*
     * the eigth line is the directory containing precompiled kernel
     * interfaces
     */

    line++;
    p->precompiled_kernel_interface_directory =
        get_next_line(ptr, &ptr, manifest, len);
    if (!p->precompiled_kernel_interface_directory)
        goto invalid_manifest_file;
    remove_trailing_slashes(p->precompiled_kernel_interface_directory);

    /* the rest of the file is file entries */

    line++;
    
    for (; (buf = get_next_line(ptr, &ptr, manifest, len)); line++) {
        char *flag = NULL;
        PackageEntry entry;
        int entry_success = FALSE;

        if (buf[0] == '\0') {
            free(buf);
            break;
        }

        /* initialize the new entry */

        memset(&entry, 0, sizeof(PackageEntry));

        /* read the file name and permissions */

        c = buf;

        entry.file = read_next_word(buf, &c);

        if (!entry.file) goto entry_done;

        tmpstr = read_next_word(c, &c);

        if (!tmpstr) goto entry_done;

        /* translate the mode string into an octal mode */

        ret = mode_string_to_mode(op, tmpstr, &entry.mode);

        free(tmpstr);

        if (!ret) goto entry_done;

        /* every file has a type field */

        entry.type = FILE_TYPE_NONE;

        flag = read_next_word(c, &c);
        if (!flag) goto entry_done;

        entry.type = parse_manifest_file_type(flag, &entry.caps);

        if (entry.type == FILE_TYPE_NONE) {
            goto entry_done;
        }

        /* Track whether certain file types were packaged */

        switch (entry.type) {
            case FILE_TYPE_XMODULE_SHARED_LIB:
                op->x_files_packaged = TRUE;
                break;
            default: break;
        }

        /* set opengl_files_packaged if any OpenGL files were packaged */

        if (entry.caps.is_opengl) {
            opengl_files_packaged = TRUE;
        }

        /* some libs/symlinks have an arch field */

        entry.compat_arch = FILE_COMPAT_ARCH_NONE;

        if (entry.caps.has_arch) {
            nvfree(flag);
            flag = read_next_word(c, &c);
            if (!flag) goto entry_done;

            if (strcmp(flag, "COMPAT32") == 0)
                entry.compat_arch = FILE_COMPAT_ARCH_COMPAT32;
            else if (strcmp(flag, "NATIVE") == 0)
                entry.compat_arch = FILE_COMPAT_ARCH_NATIVE;
            else {
                goto entry_done;
            }
        }

        /* if compat32 files are packaged, set compat32_files_packaged */

        if (entry.compat_arch == FILE_COMPAT_ARCH_COMPAT32) {
            op->compat32_files_packaged = TRUE;
        }

        /* some libs/symlinks have a class field */

        entry.tls_class = FILE_TLS_CLASS_NONE;

        if (entry.caps.has_tls_class) {
            nvfree(flag);
            flag = read_next_word(c, &c);
            if (!flag) goto entry_done;

            if (strcmp(flag, "CLASSIC") == 0)
                entry.tls_class = FILE_TLS_CLASS_CLASSIC;
            else if (strcmp(flag, "NEW") == 0)
                entry.tls_class = FILE_TLS_CLASS_NEW;
            else {
                goto entry_done;
            }
        }

        /* some file types have a path field, or inherit their paths */

        if (entry.caps.has_path) {
            entry.path = read_next_word(c, &c);
            if (!entry.path) goto invalid_manifest_file;
        } else if (entry.caps.inherit_path) {
            int i;
            char *path, *depth, *slash;
            const char * const depth_marker = "INHERIT_PATH_DEPTH:";

            depth = read_next_word(c, &c);
            if (!depth ||
                strncmp(depth, depth_marker, strlen(depth_marker)) != 0) {
                goto invalid_manifest_file;
            }
            entry.inherit_path_depth = atoi(depth + strlen(depth_marker));
            nvfree(depth);

            /* Remove the file component from the packaged filename */
            path = entry.path = nvstrdup(entry.file);
            slash = strrchr(path, '/');
            if (slash == NULL) {
                goto invalid_manifest_file;
            }
            slash[1] = '\0';

            /* Strip leading directory components from the path */
            for (i = 0; i < entry.inherit_path_depth; i++) {
                slash = strchr(entry.path, '/');

                if (slash == NULL) {
                    goto invalid_manifest_file;
                }

                entry.path = slash + 1;
            }

            entry.path = nvstrdup(entry.path);
            nvfree(path);
        } else {
            entry.path = NULL;
        }

        /* symlinks have a target */

        if (entry.caps.is_symlink) {
            entry.target = read_next_word(c, &c);
            if (!entry.target) goto invalid_manifest_file;
        } else {
            entry.target = NULL;
        }

        /*
         * as a convenience for later, set the 'name' pointer to
         * the basename contained in 'file' (ie the portion of
         * 'file' without any leading directory components
         */

        entry.name = strrchr(entry.file, '/');
        if (entry.name) entry.name++;

        if (!entry.name) entry.name = entry.file;

        add_package_entry(p,
                          entry.file,
                          entry.path,
                          entry.name,
                          entry.target,
                          entry.dst,
                          entry.type,
                          entry.tls_class,
                          entry.compat_arch,
                          entry.mode);

        entry_success = TRUE;

 entry_done:
        /* clean up */

        nvfree(buf);
        nvfree(flag);
        if (!entry_success) {
            goto invalid_manifest_file;
        }
    }

    /* If no OpenGL files were packaged, we can't install them. Set the
     * no_opengl_files flag so that everything we skip when explicitly
     * excluding OpenGL is also skipped when OpenGL is not packaged. */

    if (!opengl_files_packaged) {
        op->no_opengl_files = TRUE;
    }

    munmap(manifest, len);
    if (fd != -1) close(fd);

    return p;
    
 cannot_open:
    ui_error(op, "Failure opening package's .manifest file (%s).",
             strerror(errno));
    goto fail;

 invalid_manifest_file:

    ui_error(op, "Invalid .manifest file; error on line %d.", line);
    goto fail;

 fail:
    free_package(p);
    if (manifest != MAP_FAILED) munmap(manifest, len);
    if (fd != -1) close(fd);
    return NULL;
       
} /* parse_manifest() */
예제 #10
0
static int assisted_module_signing(Options *op, Package *p)
{
    int generate_keys = FALSE, do_sign = FALSE, secureboot, i;

    secureboot = secure_boot_enabled();

    if (secureboot < 0) {
        ui_log(op, "Unable to determine if Secure Boot is enabled: %s",
               strerror(-secureboot));
    }

    if (op->kernel_module_signed) {
        /* The kernel module is already signed, e.g. from linking a precompiled
         * interface + appending a detached signature */
        return TRUE;
    }

    if (test_kernel_config_option(op, p, "CONFIG_DUMMY_OPTION") ==
        KERNEL_CONFIG_OPTION_UNKNOWN) {
        /* Unable to test kernel configuration options, possibly due to
         * missing kernel headers. Since we might be installing on a
         * system that doesn't have the headers, bail out. */
        return TRUE;
    }

    if (op->module_signing_secret_key && op->module_signing_public_key) {
        /* If the user supplied signing keys, sign the module, regardless of
         * whether or not we actually need to. */
        do_sign = TRUE;
    } else if (test_kernel_config_option(op, p, "CONFIG_MODULE_SIG_FORCE") ==
               KERNEL_CONFIG_OPTION_DEFINED) {
        /* If CONFIG_MODULE_SIG_FORCE is set, we must sign. */
        ui_message(op, "The target kernel has CONFIG_MODULE_SIG_FORCE set, "
                   "which means that it requires that kernel modules be "
                   "cryptographically signed by a trusted key.");
        do_sign = TRUE;
    } else if (secureboot != 1 && !op->expert) {
        /* If this is a non-UEFI system, or a UEFI system with secure boot
         * disabled, or we are unable to determine whether the system has
         * secure boot enabled, bail out unless in expert mode. */
        return TRUE;
    } else if (test_kernel_config_option(op, p, "CONFIG_MODULE_SIG") ==
               KERNEL_CONFIG_OPTION_DEFINED){
        /* The kernel may or may not enforce module signatures; ask the user
         * whether to sign the module. */

        const char *choices[2] = {
            "Sign the kernel module",
            "Install without signing"
        };

        const char* sb_message = (secureboot == 1) ?
                                     "This system also has UEFI Secure Boot "
                                     "enabled; many distributions enforce "
                                     "module signature verification on UEFI "
                                     "systems when Secure Boot is enabled. " :
                                     "";

        do_sign = (ui_multiple_choice(op, choices, 2, 1, "The target kernel "
                                      "has CONFIG_MODULE_SIG set, which means "
                                      "that it supports cryptographic "
                                      "signatures on kernel modules. On some "
                                      "systems, the kernel may refuse to load "
                                      "modules without a valid signature from "
                                      "a trusted key. %sWould you like to sign "
                                      "the NVIDIA kernel module?",
                                      sb_message) == 0);
    }

    if (!do_sign) {
        /* The user explicitly opted out of module signing, or the kernel does
         * not support module signatures, and no signing keys were provided;
         * there is nothing for us to do here. */
        return TRUE;
    }

    /* If we're missing either key, we need to get both from the user. */
    if (!op->module_signing_secret_key || !op->module_signing_public_key) {

        const char *choices[2] = {
            "Use an existing key pair",
            "Generate a new key pair"
        };

        generate_keys = (ui_multiple_choice(op, choices, 2, 1, "Would you like "
                                            "to sign the NVIDIA kernel module "
                                            "with an existing key pair, or "
                                            "would you like to generate a new "
                                            "one?") == 1);

        if (generate_keys) {
            char *cmdline, *x509_hash, *private_key_path, *public_key_path;
            int ret, generate_failed = FALSE;

            if (!op->utils[OPENSSL]) {
                ui_error(op, "Unable to generate key pair: openssl not "
                         "found!");
                return FALSE;
            }

            /* Determine what hashing algorithm to use for the generated X.509
             * certificate. XXX The default is to use the same hash that is
             * used for signing modules; the two hashes are actually orthognal
             * to each other, but by choosing the module signing hash we are
             * guaranteed that the chosen hash will be built into the kernel.
             */
            if (op->module_signing_x509_hash) {
                x509_hash = nvstrdup(op->module_signing_x509_hash);
            } else {
                char *guess, *guess_trimmed, *warn = NULL;

                char *no_guess = "Unable to guess the module signing hash.";
                char *common_warn = "The module signing certificate generated "
                                    "by nvidia-installer will be signed with "
                                    "sha256 as a fallback. If the resulting "
                                    "certificate fails to import into your "
                                    "kernel's trusted keyring, please run the "
                                    "installer again, and either use a pre-"
                                    "generated key pair, or set the "
                                    "--module-signing-x509-hash option if you "
                                    "plan to generate a new key pair with "
                                    "nvidia-installer.";

                guess = guess_module_signing_hash(op,
                                                  p->kernel_module_build_directory);

                if (guess == NULL) {
                    warn = no_guess;
                    goto guess_fail;
                }

                guess_trimmed = nv_trim_space(guess);
                guess_trimmed = nv_trim_char_strict(guess_trimmed, '"');

                if (guess_trimmed) {
                    if (strlen(guess_trimmed) == 0) {
                        warn = no_guess;
                        goto guess_fail;
                    }

                    x509_hash = nvstrdup(guess_trimmed);
                } else {
                    warn = "Error while parsing the detected module signing "
                           "hash.";
                    goto guess_fail;
                }

guess_fail:
                nvfree(guess);

                if (warn) {
                    ui_warn(op, "%s %s", warn, common_warn);
                    x509_hash = nvstrdup("sha256");
                }
            }

            log_printf(op, NULL, "Generating key pair for module signing...");

            /* Generate temporary files for the signing key and certificate */

            private_key_path = write_temp_file(op, 0, NULL, 0600);
            public_key_path = write_temp_file(op, 0, NULL, 0644);

            if (!private_key_path || !public_key_path) {
                ui_error(op, "Failed to create one or more temporary files for "
                         "the module signing keys.");
                generate_failed = TRUE;
                goto generate_done;
            }

            /* Generate a key pair using openssl.
             * XXX We assume that sign-file requires the X.509 certificate
             * in DER format; if this changes in the future we will need
             * to be able to accommodate the actual required format. */

            cmdline = nvstrcat("cd ", p->kernel_module_build_directory, "; ",
                               op->utils[OPENSSL], " req -new -x509 -newkey "
                               "rsa:2048 -days 7300 -nodes -subj "
                               "\"/CN=nvidia-installer generated signing key/\""
                               " -keyout ", private_key_path,
                               " -outform DER -out ", public_key_path,
                               " -", x509_hash, NULL);
            nvfree(x509_hash);

            ret = run_command(op, cmdline, NULL, TRUE, 8, TRUE);

            nvfree(cmdline);

            if (ret != 0) {
                ui_error(op, "Failed to generate key pair!");
                generate_failed = TRUE;
                goto generate_done;
            }

            log_printf(op, NULL, "Signing keys generated successfully.");

            /* Set the signing keys to the newly generated pair. */

            op->module_signing_secret_key = nvstrdup(private_key_path);
            op->module_signing_public_key = nvstrdup(public_key_path);

generate_done:
            nvfree(private_key_path);
            nvfree(public_key_path);

            if (generate_failed) {
                return FALSE;
            }
        } else {
            /* The user already has keys; prompt for their locations. */
            op->module_signing_secret_key =
                get_filename(op, op->module_signing_secret_key,
                             "Please provide the path to the private key");
            op->module_signing_public_key =
                get_filename(op, op->module_signing_public_key,
                             "Please provide the path to the public key");
        }
    }

    /* Now that we have keys (user-supplied or installer-generated),
     * sign the kernel module/s which we built earlier. */

    for (i = 0; i < p->num_kernel_modules; i++) {
        if (!sign_kernel_module(op, p->kernel_module_build_directory,
                                p->kernel_modules[i].module_filename, TRUE)) {
            return FALSE;
        }
    }

    if (generate_keys) {

        /* If keys were generated, we should install the verification cert
         * so that the user can make the kernel trust it, and either delete
         * or install the private signing key. */
        char *name, *result = NULL, *fingerprint, *cmdline;
        char short_fingerprint[9];
        int ret, delete_secret_key;

        delete_secret_key = ui_yes_no(op, TRUE, "The NVIDIA kernel module was "
                                      "successfully signed with a newly "
                                      "generated key pair. Would you like to "
                                      "delete the private signing key?");

        /* Get the fingerprint of the X.509 certificate. We already used 
           openssl to create a keypair at this point, so we know we have it;
           otherwise, we would have already returned by now. */
        cmdline = nvstrcat(op->utils[OPENSSL], " x509 -noout -fingerprint ",
                           "-inform DER -in ", op->module_signing_public_key,
                           NULL);
        ret = run_command(op, cmdline, &result, FALSE, 0, FALSE);
        nvfree(cmdline);

        /* Format: "SHA1 Fingerprint=00:00:00:00:..." */
        fingerprint = strchr(result, '=') + 1;

        if (ret != 0 || !fingerprint || strlen(fingerprint) < 40) {
            char *sha1sum = find_system_util("sha1sum");

            if (sha1sum) {
                /* the openssl command failed, or we parsed its output
                 * incorrectly; try to get a sha1sum of the DER certificate */
                cmdline = nvstrcat(sha1sum, " ", op->module_signing_public_key,
                                   NULL);
                ret = run_command(op, cmdline, &result, FALSE, 0, FALSE);
                nvfree(sha1sum);
                nvfree(cmdline);

                fingerprint = result;
            }

            if (!sha1sum || ret != 0 || !fingerprint ||
                strlen(fingerprint) < 40) {
                /* Unable to determine fingerprint */
                fingerprint = "UNKNOWN";
            } else {
                char *end = strchr(fingerprint, ' ');
                *end = '\0';
            }
        } else {
            /* Remove any ':' characters from fingerprint and truncate */
            char *tmp = nv_strreplace(fingerprint, ":", "");
            strncpy(short_fingerprint, tmp, sizeof(short_fingerprint));
            nvfree(tmp);
        }
        short_fingerprint[sizeof(short_fingerprint) - 1] = '\0';

        /* Add the public key to the package */

        /* XXX name will be leaked when freeing package */
        name = nvstrcat("nvidia-modsign-crt-", short_fingerprint, ".der", NULL);

        add_package_entry(p,
                          nvstrdup(op->module_signing_public_key),
                          NULL, /* path */
                          name,
                          NULL, /* target */
                          NULL, /* dst */
                          FILE_TYPE_MODULE_SIGNING_KEY,
                          FILE_TLS_CLASS_NONE,
                          FILE_COMPAT_ARCH_NONE,
                          0444);

        ui_message(op, "An X.509 certificate containing the public signing "
                    "key will be installed to %s/%s. The SHA1 fingerprint of "
                    "this certificate is: %s.\n\nThis certificate must be "
                    "added to a key database which is trusted by your kernel "
                    "in order for the kernel to be able to verify the module "
                    "signature.", op->module_signing_key_path, name,
                    fingerprint);

        nvfree(result);

        /* Delete or install the private key */

        if (delete_secret_key) {
            secure_delete(op, op->module_signing_secret_key);
        } else {

            /* Add the private key to the package */

            name = nvstrcat("nvidia-modsign-key-", short_fingerprint, ".key",
                            NULL);

            add_package_entry(p,
                              nvstrdup(op->module_signing_secret_key),
                              NULL, /* path */
                              name,
                              NULL, /* target */
                              NULL, /* dst */
                              FILE_TYPE_MODULE_SIGNING_KEY,
                              FILE_TLS_CLASS_NONE,
                              FILE_COMPAT_ARCH_NONE,
                              0400);

            ui_message(op, "The private signing key will be installed to %s/%s. "
                       "After the public key is added to a key database which "
                       "is trusted by your kernel, you may reuse the saved "
                       "public/private key pair to sign additional kernel "
                       "modules, without needing to re-enroll the public key. "
                       "Please take some reasonable precautions to secure the "
                       "private key: see the README for suggestions.",
                       op->module_signing_key_path, name);
        }
    } /* if (generate_keys) */

    return TRUE;
} /* assisted_module_signing() */
예제 #11
0
static int enable_separate_x_screens(Options *op, XConfigPtr config,
                                     XConfigLayoutPtr layout)
{
    XConfigScreenPtr screen, *screenlist = NULL;
    XConfigAdjacencyPtr adj;
    int* screens_to_clone = NULL;

    int i, nscreens = 0;
    int have_busids;
    
    /* step 1: build the list of screens that are candidate to be cloned */
    
    if (op->screen) {
        screen = xconfigFindScreen(op->screen, config->screens);
        if (!screen) {
            nv_error_msg("Unable to find screen '%s'.", op->screen);
            return FALSE;
        }
        
        screenlist = nvalloc(sizeof(XConfigScreenPtr));
        screenlist[0] = screen;
        nscreens = 1;
        
    } else {
        for (adj = layout->adjacencies; adj; adj = adj->next) {
            nscreens++;
            screenlist = realloc(screenlist,
                                 sizeof(XConfigScreenPtr) * nscreens);
            
            screenlist[nscreens-1] = adj->screen;
        }
    }
    
    if (!nscreens) return FALSE;
    
    /* step 2: do all screens in the list have a bus ID? */
    
    have_busids = TRUE;
    
    for (i = 0; i < nscreens; i++) {
        if (screenlist[i] &&
            screenlist[i]->device &&
            screenlist[i]->device->busid) {
            // this screen has a busid
        } else {
            have_busids = FALSE;
            break;
        }
    }
    
    /*
     * if not everyone has a bus id, then let's assign bus ids to all
     * the screens; XXX what if _some_ already have busids?  Too bad,
     * we're going to reassign all of them.
     */
    
    if (!have_busids) {
        DevicesPtr pDevices;
        
        pDevices = find_devices(op);
        if (!pDevices) {
            nv_error_msg("Unable to determine number or location of "
                         "GPUs in system; cannot "
                         "honor '--separate-x-screens' option.");
            return FALSE;
        }
        
        for (i = 0; i < nscreens; i++) {
            if (i >= pDevices->nDevices) {
                /*
                 * we have more screens than GPUs, this screen is no
                 * longer a candidate
                 */
                screenlist[i] = NULL;
                continue;
            }
            
            screenlist[i]->device->busid = nvalloc(32);
            xconfigFormatPciBusString(screenlist[i]->device->busid, 32,
                                      pDevices->devices[i].dev.domain,
                                      pDevices->devices[i].dev.bus,
                                      pDevices->devices[i].dev.slot, 0);

            screenlist[i]->device->board = nvstrdup(pDevices->devices[i].name);
        }

        free_devices(pDevices);
    }

    /* step 3 */
    clean_screen_list(screenlist, config, nscreens);
    
    /* step 4 */
    screens_to_clone = get_screens_to_clone(op, screenlist, nscreens);
    
    /* step 5: clone each eligible screen */
    
    for (i = 0; i < nscreens; i++) {
        if (!screenlist[i]) continue;

        while (--screens_to_clone[i] > 0) {
            clone_screen(screenlist[i], screens_to_clone[i]);
        }
    }

    nvfree(screens_to_clone);
    
    /* step 6: wipe the existing adjacencies and recreate them */
    
    xconfigFreeAdjacencyList(&layout->adjacencies);
    
    create_adjacencies(op, config, layout);

    /* free unused device and monitor sections */
    
    free_unused_devices(op, config);
    free_unused_monitors(op, config);

    /* free stuff */

    free(screenlist);

    return TRUE;

} /* enable_separate_x_screens() */