Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3]: src/sbin/atactl Pull up revision 1.38 (requested by drochner ...



details:   https://anonhg.NetBSD.org/src/rev/a27ca266c469
branches:  netbsd-3
changeset: 575377:a27ca266c469
user:      tron <tron%NetBSD.org@localhost>
date:      Fri Apr 15 22:07:53 2005 +0000

description:
Pull up revision 1.38 (requested by drochner in ticket #156):
Implement a "security" command with subcommands to query the status of
the "security" extension and to "freeze" it. With the security extension
frozen, disk passwords cannot be set anymore, until the next hard reset.
Normally, this is the business of the BIOS, but older/buggy/embedded
BIOSes don't care. This leaves the (theoretical) possibility that a
malicious program in posession of superuser rights sets a disk password,
rendering the disk useless (or at least uneconomical to recover from).
Inspired by an article in the german "ct" magazine.
Being here, consolidate the implementations of IDENTIFY into one, and
fix an obvious alignment problem.

diffstat:

 sbin/atactl/atactl.c |  96 +++++++++++++++++++++++++++++++++++----------------
 1 files changed, 66 insertions(+), 30 deletions(-)

diffs (176 lines):

diff -r 992e8fcc7532 -r a27ca266c469 sbin/atactl/atactl.c
--- a/sbin/atactl/atactl.c      Fri Apr 15 09:49:14 2005 +0000
+++ b/sbin/atactl/atactl.c      Fri Apr 15 22:07:53 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atactl.c,v 1.37 2005/01/20 15:36:02 xtraeme Exp $      */
+/*     $NetBSD: atactl.c,v 1.37.2.1 2005/04/15 22:07:53 tron Exp $     */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: atactl.c,v 1.37 2005/01/20 15:36:02 xtraeme Exp $");
+__RCSID("$NetBSD: atactl.c,v 1.37.2.1 2005/04/15 22:07:53 tron Exp $");
 #endif
 
 
@@ -118,6 +118,8 @@
 void   print_error(void *);
 void   print_selftest(void *);
 
+struct ataparams *getataparams(void);
+
 int    is_smart(void);
 
 int    fd;                             /* file descriptor for device */
@@ -131,6 +133,7 @@
 void   device_idle(int, char *[]);
 void   device_checkpower(int, char *[]);
 void   device_smart(int, char *[]);
+void   device_security(int, char *[]);
 
 void   device_smart_temp(struct ata_smart_attr *, uint64_t);
 
@@ -144,6 +147,7 @@
        { "checkpower", "",                     device_checkpower },
        { "smart",      "enable|disable|status|offline #|error-log|selftest-log",
                                                device_smart },
+       { "security",   "freeze|status",        device_security },
        { NULL,         NULL,                   NULL },
 };
 
@@ -283,6 +287,17 @@
        {   0,          "Unknown" },
 };
 
+struct bitinfo ata_sec_st[] = {
+       { WDC_SEC_SUPP,         "supported" },
+       { WDC_SEC_EN,           "enabled" },
+       { WDC_SEC_LOCKED,       "locked" },
+       { WDC_SEC_FROZEN,       "frozen" },
+       { WDC_SEC_EXP,          "expired" },
+       { WDC_SEC_ESE_SUPP,     "enhanced erase support" },
+       { WDC_SEC_LEV_MAX,      "maximum level" },
+       { 0,                    NULL },
+};
+
 int
 main(int argc, char *argv[])
 {
@@ -715,6 +730,29 @@
                print_selftest_entry(i, &stlog->log_entries[i]);
 }
 
+struct ataparams *
+getataparams()
+{
+       struct atareq req;
+       static union {
+               unsigned char inbuf[DEV_BSIZE];
+               struct ataparams inqbuf;
+       } inbuf;
+
+       memset(&inbuf, 0, sizeof(inbuf));
+       memset(&req, 0, sizeof(req));
+
+       req.flags = ATACMD_READ;
+       req.command = WDCC_IDENTIFY;
+       req.databuf = (caddr_t)&inbuf;
+       req.datalen = sizeof(inbuf);
+       req.timeout = 1000;
+
+       ata_command(&req);
+
+       return (&inbuf.inqbuf);
+}
+
 /*
  * is_smart:
  *
@@ -725,23 +763,10 @@
 is_smart(void)
 {
        int retval = 0;
-       struct atareq req;
-       unsigned char inbuf[DEV_BSIZE];
        struct ataparams *inqbuf;
        char *status;
 
-       memset(&inbuf, 0, sizeof(inbuf));
-       memset(&req, 0, sizeof(req));
-
-       inqbuf = (struct ataparams *) inbuf;
-
-       req.flags = ATACMD_READ;
-       req.command = WDCC_IDENTIFY;
-       req.databuf = (caddr_t) inbuf;
-       req.datalen = sizeof(inbuf);
-       req.timeout = 1000;
-
-       ata_command(&req);
+       inqbuf = getataparams();
 
        if (inqbuf->atap_cmd_def != 0 && inqbuf->atap_cmd_def != 0xffff) {
                if (!(inqbuf->atap_cmd_set1 & WDC_CMD1_SMART)) {
@@ -779,8 +804,6 @@
 device_identify(int argc, char *argv[])
 {
        struct ataparams *inqbuf;
-       struct atareq req;
-       unsigned char inbuf[DEV_BSIZE];
 #if BYTE_ORDER == LITTLE_ENDIAN
        int i;
        u_int16_t *p;
@@ -790,18 +813,7 @@
        if (argc != 0)
                usage();
 
-       memset(&inbuf, 0, sizeof(inbuf));
-       memset(&req, 0, sizeof(req));
-
-       inqbuf = (struct ataparams *) inbuf;
-
-       req.flags = ATACMD_READ;
-       req.command = WDCC_IDENTIFY;
-       req.databuf = (caddr_t) inbuf;
-       req.datalen = sizeof(inbuf);
-       req.timeout = 1000;
-
-       ata_command(&req);
+       inqbuf = getataparams();
 
 #if BYTE_ORDER == LITTLE_ENDIAN
        /*
@@ -1183,6 +1195,30 @@
        return;
 }
 
+void
+device_security(int argc, char *argv[])
+{
+       struct atareq req;
+       struct ataparams *inqbuf;
+
+       /* need subcommand */
+       if (argc < 1)
+               usage();
+
+       if (strcmp(argv[0], "freeze") == 0) {
+               memset(&req, 0, sizeof(req));
+               req.command = WCDD_SECURITY_FREEZE;
+               req.timeout = 1000;
+               ata_command(&req);
+       } else if (strcmp(argv[0], "status") == 0) {
+               inqbuf = getataparams();
+               print_bitinfo("\t", "\n", inqbuf->atap_sec_st, ata_sec_st);
+       } else
+               usage();
+
+       return;
+}
+
 /*
  * bus_reset:
  *     Reset an ATA bus (will reset all devices on the bus)



Home | Main Index | Thread Index | Old Index