This patch adds a kauth helper to be used by file ioslave.
Depends on D6709
elvisangelaccio | |
dfaure |
Frameworks |
This patch adds a kauth helper to be used by file ioslave.
Depends on D6709
Lint Skipped |
Unit Tests Skipped |
src/core/jobuidelegateextension.h | ||
---|---|---|
230 ↗ | (On Diff #15515) | This class is public, adding virtual methods is BIC. Remember to add @since 5.37 to the class. |
src/ioslaves/file/file_unix.cpp | ||
684 ↗ | (On Diff #15515) | s/the the/the/ |
src/ioslaves/file/kauth/helper.h | ||
30 ↗ | (On Diff #15515) | Best class ever. Add a comment to explain what it does? |
In my previous revision the logic for showing warning from ioslave was flawed. In case of deleteRecursive everything would have worked out fine but in case of copy the logic for warning would have failed. Since CopyJob creates number of sub jobs, there are as many number of slaves. If there happen to be more than one file with read access restricted then ioslave's warning would have been shown multiple times.
In this revision, I added a variable m_enablePrivilegeExecution, a public method isPrivilegeExecutionEnabled and an additional job flag PrivilegeExecution to the KIO Job class.
Now if an application want's to execute a privilege file operation, it will
The step 2 is very important. Even if the flag is set its upto us to decide which job should support it. And the jobs which support it will also show warnings prior to notifying the slave. This prevents misuse of the job during the brief period of elevated privilege.
@dfaure what do you say about the feasibility of this approach?
@davidedmundson will this revision solve the problem you mentioned D6198. I will include the code for warning in the job itself.
Removed everything except the helper's code
Replaced all the helper method with on method, exec().
src/ioslaves/file/kauth/filehelper.cpp | ||
---|---|---|
71 ↗ | (On Diff #17013) | this calls for a switch() |
86 ↗ | (On Diff #17013) | opendir can return 0, in which case the next line will probably crash. Overall, this whole method seriously lacks error handling in my opinion. Just checking for errno at the end isn't enough, e.g. in cases like this where multiple calls are being made. And even otherwise, I'm unsure if ignoring the return value of chmod/chown/unlink/mkdir and *just* checking errno is enough or not. Does anyone else know? |
src/ioslaves/file/kauth/filehelper.h | ||
22 ↗ | (On Diff #17013) | should be FILEHELPER_H to match the filename |
33 ↗ | (On Diff #17013) | This isn't public API -> no @since. |
src/ioslaves/file/kauth/filehelper.cpp | ||
---|---|---|
86 ↗ | (On Diff #17013) | In case of OPEN and OPENDIR, I can see why we need error checking, opendir() can return null and there are some issues (I read on internet, can't recall the source) if close() fails. But in case of single function calls like chmod() I can't see how return value matters. Say if unlink fails for whatever reasons, we can return the error code and the checking for exact error code can be done by ioslave. Is there something I am overlooking? |
src/ioslaves/file/kauth/filehelper.cpp | ||
---|---|---|
41 ↗ | (On Diff #17507) | I assume this enum is duplicated elsewhere (in whoever is serializing the arguments for FileHelper), right? |
102 ↗ | (On Diff #17507) | missing else or break here, no? |
86 ↗ | (On Diff #17013) | The documentation for chown and others says: Upon successful completion, these functions shall return 0. Otherwise, these functions shall return −1 and set errno to indicate the error. It does NOT say, that errno isn't set when the function is successful. It seems to me that it would be perfectly valid for a libc implementation to do something like "try this, it fails (and sets errno), then try that, it worked, return 0". For this reason I would feel much safer (especially in code run by root!) if the error handling was more classic, i.e. by checking return values. |
src/ioslaves/file/kauth/filehelper.cpp | ||
---|---|---|
86 ↗ | (On Diff #17013) |
It is valid and isn't that uncommon.
Currently helper sets the error and slave terminates due to Kauth::ErrorReply. Do you want this to not happen, like in case where chown succeeds but errno is set? And what error code should I check for and whether it should be for each case or at the end of method? |
Not sure I understand your question. If we agree on using return values then there is only one way to do that. E.g. chmod() returns 0 on success, so the code could be like
if (chmod(...) == 0) return reply; break;
which jumps to the if (errno) code when chmod returns non-zero.
Same for all other methods, check the man page for each to avoid making any assumptions, but presumably they all return 0 on success.
src/ioslaves/file/kauth/filehelper.cpp | ||
---|---|---|
39 ↗ | (On Diff #18012) | this basically abuses a global variable for something that could just be a return value from this function. |
44 ↗ | (On Diff #18012) | should be unnecessary now, with the above suggested change |
134 ↗ | (On Diff #18012) | I hope we never have the opposite problem, where a libc function returns non-zero but "forgets" to set errno. reply.setError(errno ? errno : -1); to make sure we never return success when an error happened. |
src/ioslaves/file/kauth/filehelper.cpp | ||
---|---|---|
44 ↗ | (On Diff #18012) | In my system errno is set to 11. It seems like the case where function call succeeds but errno is set. But then it happens right after control reaches this method so I can't figure out which call might have set the error. I can't say if its unique to my system or not but there it is. So I think its best to set errno to 0 just to be on safe side. |
src/ioslaves/file/kauth/filehelper.cpp | ||
---|---|---|
46 ↗ | (On Diff #18201) | Well, this proves exactly my earlier point: we should only test errno *when* a libc function fails. If this code is still checking errno after success somewhere, then *that* it what should be fixed. And once it's fixed, there's no need to reset errno here. (BTW strerror(11) is EAGAIN, "Resource temporarily unavailable", rather frequent for non-blocking sockets, which is probably what triggered the slave to wake up in the first place.) So, where is this code checking for errno even after success? In the caller of this method? It's hard to review all these separate review requests because I never have a global overview or the ability to search across the whole codebase -- but at the same time, everything in a single merge request would kill this slow webbrowser... [QtWebEngine compiled in debug mode] :-) |
src/ioslaves/file/kauth/filehelper.cpp | ||
---|---|---|
46 ↗ | (On Diff #18201) | Actually action OPEN and OPENDIR were relying on this errno assignment (in the previous revision). I forgot that in this revision both of them return on success. |
src/ioslaves/file/kauth/filehelper.cpp | ||
---|---|---|
34 ↗ | (On Diff #18235) | BTW what happens if two instances of this helper (and two instances of kio_file) try to do this at the same time? Don't they need different socket paths, to avoid interferring with each other? I suppose the PID of the kio_file process should be added to this path, which means passing it in the QVariantMap to exec(), right? |
104 ↗ | (On Diff #18235) | You send fd=-1 if opendir fails, but not if dirfd fails. |
Is it even needed to send -1, if we're going to return an error reply anyway?
The current logic is "after a successful sendFileDescriptor close the socket". So sending -1 was to ensure socket is closed.
-Removed the hard-coded socket path. Now it will take socket path from ioslave.
-Removed sendFileDescriptor(-1) calls.
src/ioslaves/file/kauth/file.actions | ||
---|---|---|
3 ↗ | (On Diff #15515) | We could use more descriptive sentences here. Note also that we are not necessarily asking for the root password. How about something like:
|
Probably because "Frameworks" as group reviewer was still in the "requested changes" status.