How to use QCoreApplication to set root permission to my app
-
Hello,
I want to run my GUI app as root in order to be able to do commands such as iwconfig. I manually set my GUI app to run as root, but whenever Qt runs my app, it aborts since it detected my app to be running setuid. Now I found this http://doc-snapshot.qt-project.org/qt5-5.4/qcoreapplication.html#setSetuidAllowed and from my understanding, this member of class QClassApplication sets whether the app will be allowed to run setuid or not. I want to use this, but have no idea how to integrate it. I added this to my mainwindow.h:
@#include<QCoreApplication>
...
private:
Ui::MainWindow *ui;
QCoreApplication setSUID;
};
@I also added this to my mainwindow.cpp
@
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
...
ui->setupUi(this);
setSUID.setSetuidAllowed(true);};
@But building this causes a particular error to appear: /mainwindow.cpp:6: error: no matching function for call to 'QCoreApplication::QCoreApplication()'. What am I doing wrong?
Thanks
-
QCoreApplication is a singleton class in Qt. You cannot instantiate it again. And, by the way, setSetuidAllowed() is a static function, so you do not need an object.
Here are the solutions:
@
qApp->setSetuidAllowed(true);// or
QCoreApplication::instance()->setSetuidAllowed(true);// or, in your main function:
main () {
QApplication app();
app.setSetuidAllowed(true);MainWindow mw;
mw.show();return app.exec();
}
@I would recommend to run this function as soon as possible (main function is the right place, the MainWindow constructor might be a bit too late).
Please keep in mind that running your application as root is a security risk.
-
Hello sierdzio and thanks for your help! I tried your three solutions separately, by placing each one of them inside my main function, and with each time after building, I changed the permissions to the binary built by Qt as follows;
sudo su
chown root:root <mybin>
chmod +s <mybin>After changing permissions, I ran the binary from Qt, but the error "FATAL: The application binary appears to be running setuid, this is a security hole.
The program has unexpectedly finished." still appears. Am I doing something wrong here? I also know that it is a security risk, but I need the permissions since I am running Linux terminal commands through a Qt GUI. -
OK, the docs claim this flag has to be set before QCoreApplication instance is created.
So, please try this:
@
main () {
QApplication::setSetuidAllowed(true);QApplication app();
MainWindow mw;
mw.show();return app.exec();
}
@ -
From the documentation:
[quote]Qt is not an appropriate solution for setuid programs due to its large attack surface. However some applications may be required to run in this manner for historical reasons. This flag will prevent Qt from aborting the application when this is detected, and must be set before a QCoreApplication instance is created.[/quote]So, do it like this:
@
//FIRST allow running elevated
QApplication::setSetuidAllowed(true);
//THEN create the application
QApplication app();
@Otherwise, QCoreApplication will on construction already figure out that you are running elevated, and terminate before you can even set the permission for it. There is a reason the method is static...
-
Hello sierdzio and Andre,
I tried your solutions, but there seems to be no way around for the moment. This error appeared when I tried to run my app in Qt creator:
Gtk-WARNING **: This process is currently running setuid or setgid.
This is not a supported use of GTK+. You must create a helper
program instead. For further details, see:http://www.gtk.org/setuid.html
Refusing to initialize GTK+.
For now, I am looking into other ways to solve this. Thank you for your help!
-
Old topic, but similar experience... setSetuidAllowed(true) isn't working for me in either of the above shown implementations: calling on the QCoreApplication immediately after, or before creation of the app object.
I thought I had this working in Ubuntu 18.04 on Qt 5.9.5, but today I'm testing it in 20.04 on the default Qt 5.12.8 and the GTK+ errors refusing to start are back. I don't have an easy way to go back and test on 18.04 at the moment, maybe I'm mis-remembering how I got it to work back when.
I would really like to get this to work so I can bridge our existing message server modules with the libpam functionality that the app is required to exercise. In our architecture, a "helper app" will just expose sensitive information more than necessary.
-
Hi @admd91 ,
Have you found any alternative solution on this ?
-
@xenovas
It is unlikely that @admd91 is still around to answer from 2015....Assuming for the moment that @MangoCat is correct and cannot get
setSetuidAllowed(true)
to work (I don't know), the obvious question is why try to make the Qt GUI app run as setuid root, which is a really bad idea anyway? Not to mention, there are often problems running the UI as root (e.g. Xorg complaining). Isolate whatever bit really needs setuid root and put that into a separate process? I know he wroteIn our architecture, a "helper app" will just expose sensitive information more than necessary.
but I'm not sure why this is seen as worse than running the whole UI setuid root. In any case, if
setSetuidAllowed(true)
really doesn't work I'm not sure what better solution is available. -
@JonB thank you for your reply. Well, i don't want my GUI app to run as root of-course, but i want to perform some elevated tasks through my app. For example, a low privileged user cannot write to shadow file. Therefore, i want to explicitly change permissions for a specific task when my app runs from an unprivileged user. Nevertheless, using the Qt GUI model the app cannot run using the SUID as it should. In general, in order to perform the elevated tasks the app should have set the SUID bit on. So , the logic here is to set the owner to root, then set the SUID bit and then change the privileges to non root as the application runs, and only restore the root permissions when need it. But all of these are useless if Qt cannot run with SUID bit on... If there is something else that i am missing here please correct me, thank you again for your response.
-
@xenovas
You are missing that this post claims it doesn't work!-
Have you tried out to see whether you can do this run setuid and
setSetuidAllowed()
? If yes it works, great; else.... -
...Move your tasks to some external app run setuid, so only they run setuid and you can actually do it instead of being stuck?
-
-
@JonB Well, I'm not sure if i understood but anyway, i will do my research on this, thanks
-
@JonB Maybe i should use the capability model to see how to perform this kind of tasks, i will check it. Thank you again
-
@xenovas
https://doc.qt.io/qt-5/qcoreapplication.html#setSetuidAllowed says:If allow is false (the default) and Qt detects the application is running with an effective user id different than the real user id, the application will be aborted when a QCoreApplication instance is created.
Let's assume
setSetuidAllowed(true)
does not work. Maybe if your first statement inmain()
before creatingQCoreApplication
is to switch over to effective uid == real uid then all works fine, and you only switch back to root effective uid at the instant you need to do a root uid operation. So instead of trying to start the UI setuid. I don't know, only a thought, you would have to try.