Add smartmontools patches

Those patches were tested and work. Currently in the process of
minimizing the code required in main.c .
Those 4 patches mostly add support for more ATA Security commands to
smartmontools.
master
itycodes 4 months ago
parent c3cea8f4a9
commit 72a047dedc

@ -0,0 +1,119 @@
From d46897645c8545638983e414b695a6a901074b86 Mon Sep 17 00:00:00 2001
From: itycodes <tranquillitycodes@proton.me>
Date: Wed, 29 May 2024 06:19:13 +0200
Subject: [PATCH 1/4] Add ATA command Security Unlock
---
smartmontools/atacmds.h | 1 +
smartmontools/ataprint.cpp | 16 +++++++++++++---
smartmontools/ataprint.h | 1 +
smartmontools/smartctl.cpp | 3 +++
smartmontools/smartd.cpp | 6 ++++++
5 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/smartmontools/atacmds.h b/smartmontools/atacmds.h
index 9e813776..b914cc64 100644
--- a/smartmontools/atacmds.h
+++ b/smartmontools/atacmds.h
@@ -55,6 +55,7 @@ typedef enum {
#define ATA_IDLE 0xe3
#define ATA_SMART_CMD 0xb0
#define ATA_SECURITY_FREEZE_LOCK 0xf5
+#define ATA_SECURITY_UNLOCK 0xf2
#ifndef ATA_SET_FEATURES
#define ATA_SET_FEATURES 0xef
#endif
diff --git a/smartmontools/ataprint.cpp b/smartmontools/ataprint.cpp
index 4efb03a7..40edd33f 100644
--- a/smartmontools/ataprint.cpp
+++ b/smartmontools/ataprint.cpp
@@ -3754,7 +3754,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
if ( options.smart_disable || options.smart_enable
|| options.smart_auto_save_disable || options.smart_auto_save_enable
|| options.smart_auto_offl_disable || options.smart_auto_offl_enable
- || options.set_aam || options.set_apm || options.set_lookahead
+ || options.set_aam || options.set_apm || options.set_lookahead || options.set_security_unlock
|| options.set_wcache || options.set_security_freeze || options.set_standby
|| options.sct_wcache_reorder_set || options.sct_wcache_sct_set || options.set_dsn)
pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
@@ -3878,6 +3878,16 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("ATA Security set to frozen mode\n");
}
+ // Unlock ATA security
+ if (options.set_security_unlock) {
+ if (!ata_nodata_command(device, ATA_SECURITY_UNLOCK)) {
+ pout("ATA SECURITY UNLOCK failed: %s\n", device->get_errmsg());
+ returnval |= FAILSMART;
+ }
+ else
+ pout("ATA Security set to unlocked\n");
+ }
+
// Set standby timer unless immediate standby is also requested
if (options.set_standby && !options.set_standby_now) {
if (!ata_nodata_command(device, ATA_IDLE, options.set_standby-1)) {
@@ -4000,8 +4010,8 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.smart_auto_save_disable || options.smart_auto_save_enable
|| options.smart_auto_offl_disable || options.smart_auto_offl_enable
|| options.set_aam || options.set_apm || options.set_lookahead
- || options.set_wcache || options.set_security_freeze || options.set_standby
- || options.sct_wcache_reorder_set || options.set_dsn)
+ || options.set_wcache || options.set_security_freeze || options.set_security_unlock
+ || options.set_standby || options.sct_wcache_reorder_set || options.set_dsn)
pout("\n");
// START OF READ-ONLY OPTIONS APART FROM -V and -i
diff --git a/smartmontools/ataprint.h b/smartmontools/ataprint.h
index 64b74570..ff35dead 100644
--- a/smartmontools/ataprint.h
+++ b/smartmontools/ataprint.h
@@ -93,6 +93,7 @@ struct ata_print_options
bool set_standby_now = false; // set drive to standby
bool get_security = false; // print ATA security status
bool set_security_freeze = false; // Freeze ATA security
+ bool set_security_unlock = false; // Unlock ATA security
bool get_wcache = false; // print write cache status
int set_wcache = 0; // disable(-1), enable(1) write cache
bool sct_wcache_reorder_get = false; // print write cache reordering status
diff --git a/smartmontools/smartctl.cpp b/smartmontools/smartctl.cpp
index 67d1beef..4fd5915e 100644
--- a/smartmontools/smartctl.cpp
+++ b/smartmontools/smartctl.cpp
@@ -1077,6 +1077,9 @@ static int parse_options(int argc, char** argv, const char * & type,
else if (!get && !strcmp(optarg, "security-freeze")) {
ataopts.set_security_freeze = true;
}
+ else if(!get && !strcmp(optarg, "security-unlock")) {
+ ataopts.set_security_unlock = true;
+ }
else if (!get && !strcmp(optarg, "standby,now")) {
ataopts.set_standby_now = true;
scsiopts.set_standby_now = true;
diff --git a/smartmontools/smartd.cpp b/smartmontools/smartd.cpp
index 34f2cde2..9e4ae2eb 100644
--- a/smartmontools/smartd.cpp
+++ b/smartmontools/smartd.cpp
@@ -435,6 +435,7 @@ struct dev_config
int set_lookahead{}; // disable(-1), enable(1) read look-ahead
int set_standby{}; // set(1..255->0..254) standby timer
bool set_security_freeze{}; // Freeze ATA security
+ bool set_security_unlock{}; // Unlock ATA security
int set_wcache{}; // disable(-1), enable(1) write cache
int set_dsn{}; // disable(0x2), enable(0x1) DSN
@@ -2341,6 +2342,11 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
format_set_result_msg(msg, "Security freeze",
ata_nodata_command(atadev, ATA_SECURITY_FREEZE_LOCK));
+
+ if (cfg.set_security_unlock)
+ format_set_result_msg(msg, "Security unlock",
+ ata_nodata_command(atadev, ATA_SECURITY_UNLOCK));
+
if (cfg.set_standby)
format_set_result_msg(msg, "Standby",
ata_nodata_command(atadev, ATA_IDLE, cfg.set_standby-1), cfg.set_standby, true);
--
2.45.1

@ -0,0 +1,170 @@
From a88a02e36b93e6c1d1b9d123761a3c26d652086d Mon Sep 17 00:00:00 2001
From: itycodes <tranquillitycodes@proton.me>
Date: Wed, 29 May 2024 23:01:48 +0200
Subject: [PATCH 2/4] Add a password flag for ATA Security
---
smartmontools/atacmds.cpp | 19 +++++++++++++++++++
smartmontools/atacmds.h | 15 +++++++++++++++
smartmontools/ataprint.cpp | 2 +-
smartmontools/ataprint.h | 1 +
smartmontools/smartctl.cpp | 14 ++++++++++++++
smartmontools/smartd.cpp | 1 +
6 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/smartmontools/atacmds.cpp b/smartmontools/atacmds.cpp
index 3f88c299..0c465c8b 100644
--- a/smartmontools/atacmds.cpp
+++ b/smartmontools/atacmds.cpp
@@ -12,6 +12,8 @@
*/
#include "config.h"
+#include <cstdlib>
+#include <new>
#define __STDC_FORMAT_MACROS 1 // enable PRI* for C++
#include <inttypes.h>
@@ -795,6 +797,23 @@ bool ata_nodata_command(ata_device * device, unsigned char command,
return device->ata_pass_through(in);
}
+// Issue a no-data ATA command with optional sector count register value
+bool ata_password_command(ata_device * device, unsigned char command, unsigned char flags,
+ unsigned short password[16])
+{
+ ata_cmd_in in;
+ in.in_regs.command = command;
+ in.in_regs.sector_count = 1;
+ ata_security_unlock_data_content* unlock = new ata_security_unlock_data_content();
+ memset(unlock, 0, sizeof(ata_security_unlock_data_content));
+ memcpy(&unlock->flags, &flags, sizeof(unlock->flags));
+ memcpy(&unlock->password, password, sizeof(unlock->password));
+ printf("The password is: %s\n", (char*)&unlock->password);
+ in.set_data_out(unlock, 1);
+
+ return device->ata_pass_through(in);
+}
+
// Issue SET FEATURES command with optional sector count register value
bool ata_set_features(ata_device * device, unsigned char features,
int sector_count /* = -1 */)
diff --git a/smartmontools/atacmds.h b/smartmontools/atacmds.h
index b914cc64..77a1522d 100644
--- a/smartmontools/atacmds.h
+++ b/smartmontools/atacmds.h
@@ -193,6 +193,17 @@ STATIC_ASSERT(sizeof(ata_smart_attribute) == 12);
#define ATTRIBUTE_FLAGS_OTHER(x) ((x) & 0xffc0)
+// ATA Security Unlock data structure
+#pragma pack(1)
+struct ata_security_unlock_data_content
+{
+ unsigned short flags; // 3 = Error Recovery Control
+ unsigned short password[16]; // 1 = Set Current, 2 = Return Current, 3 = Set Power-on, 4 = Return Power-on, 5 = Restore Default
+ unsigned short words017_255[239]; // reserved
+} ATTR_PACKED;
+#pragma pack()
+STATIC_ASSERT(sizeof(ata_security_unlock_data_content) == 512);
+
// Format of data returned by SMART READ DATA
// Table 62 of T13/1699-D (ATA8-ACS) Revision 6a, September 2008
#pragma pack(1)
@@ -754,6 +765,10 @@ int ataCheckPowerMode(ata_device * device);
// Issue a no-data ATA command with optional sector count register value
bool ata_nodata_command(ata_device * device, unsigned char command, int sector_count = -1);
+// Issue an ATA command that needs a password
+bool ata_password_command(ata_device * device, unsigned char command, unsigned char flags,
+ unsigned short password[16]);
+
// Issue SET FEATURES command with optional sector count register value
bool ata_set_features(ata_device * device, unsigned char features, int sector_count = -1);
diff --git a/smartmontools/ataprint.cpp b/smartmontools/ataprint.cpp
index 40edd33f..00ff8878 100644
--- a/smartmontools/ataprint.cpp
+++ b/smartmontools/ataprint.cpp
@@ -3880,7 +3880,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
// Unlock ATA security
if (options.set_security_unlock) {
- if (!ata_nodata_command(device, ATA_SECURITY_UNLOCK)) {
+ if (!ata_password_command(device, ATA_SECURITY_UNLOCK, 0, options.security_password)) {
pout("ATA SECURITY UNLOCK failed: %s\n", device->get_errmsg());
returnval |= FAILSMART;
}
diff --git a/smartmontools/ataprint.h b/smartmontools/ataprint.h
index ff35dead..dcf96dfb 100644
--- a/smartmontools/ataprint.h
+++ b/smartmontools/ataprint.h
@@ -94,6 +94,7 @@ struct ata_print_options
bool get_security = false; // print ATA security status
bool set_security_freeze = false; // Freeze ATA security
bool set_security_unlock = false; // Unlock ATA security
+ unsigned short* security_password; // ATA security password
bool get_wcache = false; // print write cache status
int set_wcache = 0; // disable(-1), enable(1) write cache
bool sct_wcache_reorder_get = false; // print write cache reordering status
diff --git a/smartmontools/smartctl.cpp b/smartmontools/smartctl.cpp
index 4fd5915e..25b3d09e 100644
--- a/smartmontools/smartctl.cpp
+++ b/smartmontools/smartctl.cpp
@@ -191,6 +191,8 @@ static void Usage()
" %s, swapid\n\n"
" -P TYPE, --presets=TYPE (ATA)\n"
" Drive-specific presets: use, ignore, show, showall\n\n"
+" -p PASSWORD, --password=PASSWORD (ATA)\n"
+" ATA Security User Password\n\n"
" -B [+]FILE, --drivedb=[+]FILE (ATA)\n"
" Read and replace [add] drive database from FILE\n"
" [default is +%s",
@@ -254,6 +256,8 @@ static std::string getvalidarglist(int opt)
"nvmelog,N,SIZE, tapedevstat, zdevstat, envrep, farm";
case 'P':
return "use, ignore, show, showall";
+ case 'p':
+ return "<PASSWORD>";
case 't':
return "offline, short, long, conveyance, force, vendor,N, select,M-N, "
"pending,N, afterselect,[on|off]";
@@ -331,6 +335,7 @@ static int parse_options(int argc, char** argv, const char * & type,
{ "badsum", required_argument, 0, 'b' },
{ "report", required_argument, 0, 'r' },
{ "smart", required_argument, 0, opt_smart },
+ { "password", required_argument, 0, 'p' },
{ "offlineauto", required_argument, 0, 'o' },
{ "saveauto", required_argument, 0, 'S' },
{ "health", no_argument, 0, 'H' },
@@ -801,6 +806,15 @@ static int parse_options(int argc, char** argv, const char * & type,
badarg = true;
}
break;
+ // Password, has to be 32 characters
+ case 'p':
+ if(strlen(optarg) != 32) {
+ badarg = true;
+ } else {
+ ataopts.security_password = (unsigned short*)malloc(32);
+ memcpy(ataopts.security_password, optarg, 32);
+ }
+ break;
case 't':
if (!strcmp(optarg,"offline")) {
testcnt++;
diff --git a/smartmontools/smartd.cpp b/smartmontools/smartd.cpp
index 9e4ae2eb..c218434d 100644
--- a/smartmontools/smartd.cpp
+++ b/smartmontools/smartd.cpp
@@ -436,6 +436,7 @@ struct dev_config
int set_standby{}; // set(1..255->0..254) standby timer
bool set_security_freeze{}; // Freeze ATA security
bool set_security_unlock{}; // Unlock ATA security
+ unsigned short security_password[16]{}; // ATA security password
int set_wcache{}; // disable(-1), enable(1) write cache
int set_dsn{}; // disable(0x2), enable(0x1) DSN
--
2.45.1

@ -0,0 +1,43 @@
From 7b081ec58a7fc893fc8aa7a89ac525bab07357ac Mon Sep 17 00:00:00 2001
From: itycodes <tranquillitycodes@proton.me>
Date: Fri, 31 May 2024 14:06:20 +0200
Subject: [PATCH 3/4] Add a temporary patch that replaces '*' with '\0' in
--password
---
smartmontools/atacmds.cpp | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/smartmontools/atacmds.cpp b/smartmontools/atacmds.cpp
index 0c465c8b..b1164a13 100644
--- a/smartmontools/atacmds.cpp
+++ b/smartmontools/atacmds.cpp
@@ -797,7 +797,7 @@ bool ata_nodata_command(ata_device * device, unsigned char command,
return device->ata_pass_through(in);
}
-// Issue a no-data ATA command with optional sector count register value
+// Issue a password ATA command with optional sector count register value
bool ata_password_command(ata_device * device, unsigned char command, unsigned char flags,
unsigned short password[16])
{
@@ -808,7 +808,15 @@ bool ata_password_command(ata_device * device, unsigned char command, unsigned c
memset(unlock, 0, sizeof(ata_security_unlock_data_content));
memcpy(&unlock->flags, &flags, sizeof(unlock->flags));
memcpy(&unlock->password, password, sizeof(unlock->password));
- printf("The password is: %s\n", (char*)&unlock->password);
+ printf("The password is: %s (", (char*)&unlock->password);
+ char* passwd = (char*)&unlock->password;
+ for(int i = 0; i < 32; i++){
+ if(passwd[i] == '*'){
+ passwd[i] = 0;
+ }
+ printf(" %d ", passwd[i]);
+ }
+ printf("\n)");
in.set_data_out(unlock, 1);
return device->ata_pass_through(in);
--
2.45.1

@ -0,0 +1,93 @@
From f3eb303f6b1c6192b50a05f1877665da0e009d53 Mon Sep 17 00:00:00 2001
From: itycodes <tranquillitycodes@proton.me>
Date: Fri, 14 Jun 2024 01:02:12 +0200
Subject: [PATCH 4/4] Add ATA command Security Disable
---
smartmontools/atacmds.h | 1 +
smartmontools/ataprint.cpp | 15 +++++++++++++--
smartmontools/ataprint.h | 1 +
smartmontools/smartctl.cpp | 3 +++
4 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/smartmontools/atacmds.h b/smartmontools/atacmds.h
index 77a1522d..32b57f77 100644
--- a/smartmontools/atacmds.h
+++ b/smartmontools/atacmds.h
@@ -56,6 +56,7 @@ typedef enum {
#define ATA_SMART_CMD 0xb0
#define ATA_SECURITY_FREEZE_LOCK 0xf5
#define ATA_SECURITY_UNLOCK 0xf2
+#define ATA_SECURITY_DISABLE 0xf6
#ifndef ATA_SET_FEATURES
#define ATA_SET_FEATURES 0xef
#endif
diff --git a/smartmontools/ataprint.cpp b/smartmontools/ataprint.cpp
index 00ff8878..2fe97903 100644
--- a/smartmontools/ataprint.cpp
+++ b/smartmontools/ataprint.cpp
@@ -3755,7 +3755,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.smart_auto_save_disable || options.smart_auto_save_enable
|| options.smart_auto_offl_disable || options.smart_auto_offl_enable
|| options.set_aam || options.set_apm || options.set_lookahead || options.set_security_unlock
- || options.set_wcache || options.set_security_freeze || options.set_standby
+ || options.set_security_disable || options.set_wcache || options.set_security_freeze || options.set_standby
|| options.sct_wcache_reorder_set || options.sct_wcache_sct_set || options.set_dsn)
pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
@@ -3888,6 +3888,17 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("ATA Security set to unlocked\n");
}
+
+ // Disable ATA security
+ if (options.set_security_disable) {
+ if (!ata_password_command(device, ATA_SECURITY_DISABLE, 0, options.security_password)) {
+ pout("ATA SECURITY DISABLE failed: %s\n", device->get_errmsg());
+ returnval |= FAILSMART;
+ }
+ else
+ pout("ATA Security set to disabled\n");
+ }
+
// Set standby timer unless immediate standby is also requested
if (options.set_standby && !options.set_standby_now) {
if (!ata_nodata_command(device, ATA_IDLE, options.set_standby-1)) {
@@ -4011,7 +4022,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.smart_auto_offl_disable || options.smart_auto_offl_enable
|| options.set_aam || options.set_apm || options.set_lookahead
|| options.set_wcache || options.set_security_freeze || options.set_security_unlock
- || options.set_standby || options.sct_wcache_reorder_set || options.set_dsn)
+ || options.set_security_disable || options.set_standby || options.sct_wcache_reorder_set || options.set_dsn)
pout("\n");
// START OF READ-ONLY OPTIONS APART FROM -V and -i
diff --git a/smartmontools/ataprint.h b/smartmontools/ataprint.h
index dcf96dfb..4725fe41 100644
--- a/smartmontools/ataprint.h
+++ b/smartmontools/ataprint.h
@@ -94,6 +94,7 @@ struct ata_print_options
bool get_security = false; // print ATA security status
bool set_security_freeze = false; // Freeze ATA security
bool set_security_unlock = false; // Unlock ATA security
+ bool set_security_disable = false; // Disable ATA security
unsigned short* security_password; // ATA security password
bool get_wcache = false; // print write cache status
int set_wcache = 0; // disable(-1), enable(1) write cache
diff --git a/smartmontools/smartctl.cpp b/smartmontools/smartctl.cpp
index 25b3d09e..034b7c2a 100644
--- a/smartmontools/smartctl.cpp
+++ b/smartmontools/smartctl.cpp
@@ -1094,6 +1094,9 @@ static int parse_options(int argc, char** argv, const char * & type,
else if(!get && !strcmp(optarg, "security-unlock")) {
ataopts.set_security_unlock = true;
}
+ else if(!get && !strcmp(optarg, "security-disable")) {
+ ataopts.set_security_disable = true;
+ }
else if (!get && !strcmp(optarg, "standby,now")) {
ataopts.set_standby_now = true;
scsiopts.set_standby_now = true;
--
2.45.1
Loading…
Cancel
Save