<div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Den tors 5 sep. 2019 01:22Alexander Ivash <<a href="mailto:elderorb@gmail.com">elderorb@gmail.com</a>> skrev:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thank you for fast response, but my question is purely about QML. On<br>
C++ side I have a lot of ways for nullifying / erasing sensitive<br>
information *after* it is not needed (let say after particular QML<br>
screen gets' closed). But on QML / JS side I have no any control at<br>
all. Would be great if one of QML guys could step in and comment too.<br>
<br>
Here is the small example illustrating my issue (all I need is to make<br>
'Piter Pen' to disappear from memory dumps):<br>
<br>
<main.qml><br>
<br>
import QtQuick 2.12<br>
import QtQuick.Window 2.12<br>
<br>
Window {<br>
visible: true<br>
width: 640<br>
height: 480<br>
title: qsTr("Hello World")<br>
<br>
Component.onCompleted: {<br>
var test = "Piter Pen";<br>
<br>
// uncommenting results in a crash<br>
// backend.cleanup(test);<br>
<br>
// doesnt' nullify "Piter Pen"<br>
// gc();<br>
<br>
// doesn't work either<br>
/*<br>
Qt.callLater(() => {<br>
gc();<br>
})<br>
*/<br>
}<br>
}<br>
<br>
<main.cpp><br>
<br>
#include <QGuiApplication><br>
#include <QQmlContext><br>
#include <QQmlApplicationEngine><br>
#include <random><br>
#include <chrono><br>
#include <QString><br>
#include <QByteArray><br>
#include <QDebug><br>
<br>
class Backend : public QObject<br>
{<br>
Q_OBJECT<br>
public:<br>
explicit Backend(QObject *parent = nullptr) {<br>
QString str1 = "Piter Pen";<br>
QString str2 = str1;<br>
QString str3 = str2;<br>
<br>
qDebug() << "str1:" << str1;<br>
qDebug() << "str2:" << str2;<br>
qDebug() << "str3:" << str3;<br>
<br>
cleanup(str1);<br>
<br>
qDebug() << "str1:" << str1;<br>
qDebug() << "str2:" << str2;<br>
qDebug() << "str3:" << str3;<br>
}<br>
<br>
Q_INVOKABLE void cleanup(const QString& str) {<br>
std::mt19937<br>
eng(std::chrono::system_clock::now().time_since_epoch().count());<br>
std::uniform_int_distribution<ushort> distribution;<br>
<br>
QChar* data = const_cast<QChar*> (str.constData());<br>
<br>
for(int i = 0; i < str.length(); ++i) {<br>
data[i] = distribution(eng);<br>
}<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Just a word of caution: Even if you had not gotten a crash, like Thiago said you need to be very careful here: A smart compiler could possibly decide that since the memory pointed to by data is not used after this, it can optimize this entire loop of yours away.</div><div dir="auto"><br></div><div dir="auto">Not saying that's going to happen, but you need to be very careful. I think there are platform specific memory-zeroing functions that could be used that are written with that in mind. At least I know OpenBSD has something like that.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
}<br>
};<br>
<br>
int main(int argc, char *argv[])<br>
{<br>
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);<br>
<br>
QGuiApplication app(argc, argv);<br>
<br>
Backend backend;<br>
QQmlApplicationEngine engine;<br>
const QUrl url(QStringLiteral("qrc:/main.qml"));<br>
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,<br>
&app, [url](QObject *obj, const QUrl &objUrl) {<br>
if (!obj && url == objUrl)<br>
QCoreApplication::exit(-1);<br>
}, Qt::QueuedConnection);<br>
engine.rootContext()->setContextProperty("backend", &backend);<br>
engine.load(url);<br>
<br>
return app.exec();<br>
}<br>
<br>
#include "main.moc"<br>
<br>
чт, 5 сент. 2019 г. в 01:32, Thiago Macieira <<a href="mailto:thiago.macieira@intel.com" target="_blank" rel="noreferrer">thiago.macieira@intel.com</a>>:<br>
><br>
> On Wednesday, 4 September 2019 14:46:09 PDT Alexander Ivash wrote:<br>
> > Is there any mechanism for cleanup sensitive data like passwords etc<br>
> > from QML? This issue is that gc() doesn't seem to even nullify memory<br>
> > (at least in release on Windows) so all the sensitive information<br>
> > stays in memory.<br>
><br>
> Write in C++ and manage your memory VERY carefully. Remember that memset()<br>
> before free / delete or going out of scope is removed by the compiler.<br>
><br>
> Don't use new or malloc. Instead, mmap() your chunk of memory yourself and<br>
> mlock() it properly.<br>
><br>
> Of course, to display such information you need to accept that it is no longer<br>
> secure. It'll go to QML, then to the text engines, then the pixels will be<br>
> transferred to the display server or the GPU, etc.<br>
> --<br>
> Thiago Macieira - thiago.macieira (AT) <a href="http://intel.com" rel="noreferrer noreferrer" target="_blank">intel.com</a><br>
> Software Architect - Intel System Software Products<br>
><br>
><br>
><br>
> _______________________________________________<br>
> Interest mailing list<br>
> <a href="mailto:Interest@qt-project.org" target="_blank" rel="noreferrer">Interest@qt-project.org</a><br>
> <a href="https://lists.qt-project.org/listinfo/interest" rel="noreferrer noreferrer" target="_blank">https://lists.qt-project.org/listinfo/interest</a><br>
_______________________________________________<br>
Interest mailing list<br>
<a href="mailto:Interest@qt-project.org" target="_blank" rel="noreferrer">Interest@qt-project.org</a><br>
<a href="https://lists.qt-project.org/listinfo/interest" rel="noreferrer noreferrer" target="_blank">https://lists.qt-project.org/listinfo/interest</a><br>
</blockquote></div></div></div>