Skip to content

Commit b872402

Browse files
dwrobelgrandixximo
authored andcommitted
rootless: incr_io_usage()
Allow the incr_io_usage() to be used without root privileges. Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
1 parent a3413f0 commit b872402

1 file changed

Lines changed: 41 additions & 30 deletions

File tree

src/hal/utils/upci.c

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -352,37 +352,48 @@ int upci_find_device(struct upci_dev_info *p)
352352

353353
static int incr_io_usage ( void )
354354
{
355-
int retval, eno;
356-
357-
/* make sure we can do I/O */
358-
if ( ioaccess == 0 ) {
359-
/* enable access */
360-
/* this needs privileges */
361-
if (seteuid(0) != 0) {
362-
errmsg(__func__, "need root privileges (or setuid root)");
363-
return -1;
364-
}
365-
/* do it */
366-
retval = iopl(3);
367-
eno = errno;
368-
/* drop privileges */
369-
if(seteuid(getuid()) != 0)
370-
{
371-
errmsg(__func__, "unable to drop root privileges");
372-
/* Don't continue past this point, because following code may
373-
* execute with unexpected privileges
374-
*/
375-
_exit(99);
376-
}
377-
/* check result */
378-
if(retval < 0 || iopl(3) < 0) {
379-
errmsg(__func__,"opening I/O ports: %s", strerror(eno));
380-
return -1;
381-
}
355+
int retval = 0, eno = 0;
356+
357+
/* Try iopl(3) with our existing privileges first: succeeds when
358+
* the process holds CAP_SYS_RAWIO via file caps or is already
359+
* setuid root. Only fall back to seteuid(0) if that path is closed.
360+
*/
361+
do {
362+
if (ioaccess) {
363+
break;
364+
}
365+
366+
retval = iopl(3);
367+
if (retval == 0) {
368+
break;
369+
}
370+
371+
retval = seteuid(0);
372+
if (retval != 0) {
373+
eno = errno;
374+
break;
375+
}
376+
377+
retval = iopl(3);
378+
eno = errno;
379+
380+
if (seteuid(getuid()) != 0) {
381+
errmsg(__func__, "unable to drop root privileges");
382+
/* Don't continue past this point, because following code may
383+
* execute with unexpected privileges
384+
*/
385+
_exit(99);
386+
}
387+
} while (0);
388+
389+
if (retval == 0) {
390+
/* increment reference count */
391+
ioaccess++;
392+
} else {
393+
errmsg(__func__,"error: %s", strerror(eno));
382394
}
383-
/* increment reference count */
384-
ioaccess++;
385-
return 0;
395+
396+
return retval;
386397
}
387398

388399
static void decr_io_usage ( void )

0 commit comments

Comments
 (0)