/
githubmirror
/
libsmbios
Обзор
Документация
Войти
/
githubmirror
/
libsmbios
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/libsmbios_c/token/token_da.c
247 строк
8 KB
Peter Jones
Fix two pointer arithmetic errors.
03 июн 2017, 00:31
03 июн 2017, 00:31
88b17ce
Код
Авторство
О чём код?
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0: * * Copyright (C) 2005 Dell Inc. * by Michael Brown <Michael_E_Brown@dell.com> * Licensed under the Open Software License version 2.1 * * Alternatively, you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. */ #define LIBSMBIOS_C_SOURCE // Include compat.h first, then system headers, then public, then private #include "smbios_c/compat.h" // system #include <stdlib.h> #include <string.h> // public #include "smbios_c/obj/cmos.h" #include "smbios_c/cmos.h" #include "smbios_c/obj/smbios.h" #include "smbios_c/smbios.h" #include "smbios_c/smi.h" #include "smbios_c/types.h" #include "libsmbios_c_intlize.h" #include "internal_strl.h" // private #include "token_impl.h" // helpers so we dont get line lengths from heck. #define cast_token(t) ((struct calling_interface_token *)(t->token_ptr)) #define cast_struct(t) ((struct calling_interface_structure *)token_obj_get_smbios_struct(t)) static int _da_get_type(const struct token_obj *t) { fnprintf("\n"); return 0xDA; } static int _da_get_id(const struct token_obj *t) { fnprintf("\n"); return cast_token(t)->tokenId; } // pretend DA tokens are bool. // if user wants to get fancy, use the raw smi write_nv_data functions... static int _da_is_bool(const struct token_obj *t) { fnprintf("\n"); return true; } static int _da_is_string(const struct token_obj *t) { fnprintf("\n"); return true; } static int _da_is_active(const struct token_obj *t) { fnprintf("token 0x%04x location: 0x%04x value 0x%04x\n", cast_token(t)->tokenId, cast_token(t)->location, cast_token(t)->value); int retval = 0; u32 curVal=0; int ret = dell_smi_read_nv_storage(cast_token(t)->location, &curVal, 0, 0); if (ret) { retval = ret; strlcpy( t->errstring, _("Low level SMI call failed.\n"), ERROR_BUFSIZE); strlcat( t->errstring, dell_smi_strerror(), ERROR_BUFSIZE ); goto out; } if (cast_token(t)->value == curVal) retval = 1; out: return retval; } // wonky to get around GCC error: "cast from pointer to integer of different size" // as well as "warning: dereferencing type-punned pointer will break strict-aliasing rules" // should be just security_key = (u16)t->private_data; union void_u16 { void *ptr; u16 val; }; static int _da_activate(const struct token_obj *t) { fnprintf("token 0x%04x location: 0x%04x value 0x%04x\n", cast_token(t)->tokenId, cast_token(t)->location, cast_token(t)->value); // security key in private_data union void_u16 *indirect = (union void_u16*) &(t->private_data); int retval = dell_smi_write_nv_storage(indirect->val, cast_token(t)->location, cast_token(t)->value, 0); if (retval) { strlcpy( t->errstring, _("Low level SMI call failed.\n"), ERROR_BUFSIZE); strlcat( t->errstring, dell_smi_strerror(), ERROR_BUFSIZE ); } return retval; } static char * _da_get_string(const struct token_obj *t, size_t *len) { char *retval = 0; u32 toRead = 0; fnprintf("token 0x%04x location: 0x%04x value 0x%04x\n", cast_token(t)->tokenId, cast_token(t)->location, cast_token(t)->value); int ret = dell_smi_read_nv_storage(cast_token(t)->location, &toRead, 0, 0); if (ret) { strlcpy( t->errstring, _("Low level SMI call failed.\n"), ERROR_BUFSIZE); strlcat( t->errstring, dell_smi_strerror(), ERROR_BUFSIZE ); goto out; } if (len) *len = 2; retval = calloc(1, sizeof(u16)); memcpy(retval, &toRead, sizeof(u16)); out: return retval; } static int _da_set_string(const struct token_obj *t, const char *str, size_t size) { fnprintf("\n"); // security key in private_data union void_u16 *indirect = (union void_u16*) &(t->private_data); fnprintf("token 0x%04x location: 0x%04x value 0x%04x\n", cast_token(t)->tokenId, cast_token(t)->location, cast_token(t)->value); u16 toWrite = 0; if (str && size >= 2) toWrite = *(u16 *)str; else if (str && size >= 1) toWrite = *(u8 *)str; fnprintf("setting string: 0x%04x\n", toWrite); int retval = dell_smi_write_nv_storage(indirect->val, cast_token(t)->location, toWrite, 0); if (retval) { strlcpy( t->errstring, _("Low level SMI call failed.\n"), ERROR_BUFSIZE); strlcat( t->errstring, dell_smi_strerror(), ERROR_BUFSIZE ); } fnprintf("retval %d\n", retval); return retval; } static int _da_try_password(const struct token_obj *t, const char *pass_ascii, const char *pass_scan) { fnprintf("\n"); union void_u16 *indirect = (union void_u16*) &(t->private_data); const char *whichpw = pass_scan; if (dell_smi_password_format(DELL_SMI_PASSWORD_ADMIN) == DELL_SMI_PASSWORD_FMT_ASCII) whichpw=pass_ascii; fnprintf("current security key: %d\n", indirect->val); int ret = dell_smi_get_security_key(whichpw, &(indirect->val)); fnprintf("new security key: 0x%04x\n", indirect->val); return ret; } void __hidden init_da_token(struct token_table *table, struct token_obj *t) { fnprintf("\n"); t->get_type = _da_get_type; t->get_id = _da_get_id; t->is_bool = _da_is_bool; t->is_string = _da_is_string; t->is_active = _da_is_active; t->activate = _da_activate; t->get_string = _da_get_string; t->set_string = _da_set_string; t->try_password = _da_try_password; t->private_data = 0; t->errstring = table->errstring; } int __hidden add_da_tokens(struct token_table *table) { char *error=0; int retval = 0; fnprintf("\n"); smbios_table_for_each_struct_type(table->smbios_table, s, 0xDA) { struct calling_interface_structure *da_struct = (struct calling_interface_structure*)s; struct calling_interface_token *token = da_struct->tokens; while (token->tokenId != TokenTypeEOT) { if (token->tokenId == TokenTypeUnused) { token++; continue; } if ( (void *)(token + 1) > (void *)(da_struct + da_struct->length)) { fnprintf("\n"); fnprintf("\n"); fnprintf("\n"); fnprintf("BIOS BUG ============================= BIOS BUG\n"); fnprintf("BIOS BUG ============================= BIOS BUG\n"); fnprintf("\n"); fnprintf("Ran off the end of the token table! %p > %p \n\n", token, da_struct + da_struct->length); fnprintf("\n"); fnprintf("BIOS BUG ============================= BIOS BUG\n"); fnprintf("BIOS BUG ============================= BIOS BUG\n\n\n\n"); fnprintf("\n"); fnprintf("\n"); fnprintf("\n"); break; } error = _("Allocation failure while trying to create token object."); struct token_obj *n = calloc(1, sizeof(struct token_obj)); if (!n) goto out_err; n->token_ptr = token; n->smbios_structure = s; init_da_token(table, n); add_token(table, n); token++; } } goto out; out_err: strlcat(table->errstring, error, ERROR_BUFSIZE); retval = -1; out: return retval; }