kern/189821: nice(3) on FreeBSD returns EACCES instead of EPERM when provided negative prio's; is not compatible with Linux/NetBSD/POSIX

Garrett Cooper yaneurabeya at gmail.com
Wed May 14 22:10:01 UTC 2014


>Number:         189821
>Category:       kern
>Synopsis:       nice(3) on FreeBSD returns EACCES instead of EPERM when provided negative prio's; is not compatible with Linux/NetBSD/POSIX
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 14 22:10:00 UTC 2014
>Closed-Date:
>Last-Modified:
>Originator:     Garrett Cooper
>Release:        11.0-CURRENT
>Organization:
n/a
>Environment:
>Description:
The t_nice testcase from NetBSD fails when testing out negative priorities set with nice(3) because it's more or less a pass-through to setpriority(2). If one provides a negative priority to nice(3)/setpriority, it will return EACCES, not EPERM.

Linux/NetBSD/POSIX requires EPERM (before fix):

# kyua test t_nice
t_nice:nice_err  ->  failed: /usr/src/lib/libc/tests/gen/t_nice.c:85: Expected errno 1, got 13, in nice(i) == -1  [0.006s]
t_nice:nice_priority  ->  passed  [0.022s]
t_nice:nice_root  ->  passed  [0.005s]
t_nice:nice_thread  ->  passed  [0.007s]

3/4 passed (1 failed)
Committed action 42

After fix:

# env LD_PRELOAD=/usr/obj/usr/src/lib/libc/libc.so.7 kyua test t_nice
t_nice:nice_err  ->  passed  [0.005s]
t_nice:nice_priority  ->  passed  [0.039s]
t_nice:nice_root  ->  passed  [0.006s]
t_nice:nice_thread  ->  passed  [0.007s]

4/4 passed (0 failed)
Committed action 43

More discussion can be found here: https://github.com/yaneurabeya/freebsd/commit/0e07e7cd2d690af70a725cb869b4679d5d05cbc0#diff-414e52a1b185ec7b1c19140f302d99f8L82
>How-To-Repeat:
% sudo /bin/sh sh
% pw useradd notprivileged
% cat > test_unprivileged_negative_priority_with_nice.c <<EOF
#include <sys/resource.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>

int
main(void)
{

        if (geteuid() == 0) {
                printf("is root\n");
                return (1);
        }

        assert(nice(-1) == -1);
        assert(errno == EPERM);

        return (0);
}
EOF
% cc -o test_unprivileged_negative_priority_with_nice test_unprivileged_negative_priority_with_nice.c
% sudo -u notprivileged ./test_unprivileged_negative_priority_with_nice
% pw userdel notprivileged
>Fix:
See: https://github.com/yaneurabeya/freebsd/pull/6

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list