17 May, 2010

1 commit


12 Apr, 2010

13 commits


09 Mar, 2010

1 commit


03 Mar, 2010

1 commit

  • LSM framework doesn't allow to load a security module on runtime, it must be loaded on boot time.
    but in security/security.c:
    int register_security(struct security_operations *ops)
    {
    ...
    if (security_ops != &default_security_ops)
    return -EAGAIN;
    ...
    }
    if security_ops == &default_security_ops, it can access to register a security module. If selinux is enabled,
    other security modules can't register, but if selinux is disabled on boot time, the security_ops was set to
    default_security_ops, LSM allows other kernel modules to use register_security() to register a not trust
    security module. For example:

    disable selinux on boot time(selinux=0).

    #include
    #include
    #include
    #include
    #include
    #include
    #include

    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("wzt");

    extern int register_security(struct security_operations *ops);
    int (*new_register_security)(struct security_operations *ops);

    int rootkit_bprm_check_security(struct linux_binprm *bprm)
    {
    return 0;
    }

    struct security_operations rootkit_ops = {
    .bprm_check_security = rootkit_bprm_check_security,
    };

    static int rootkit_init(void)
    {
    printk("Load LSM rootkit module.\n");

    /* cat /proc/kallsyms | grep register_security */
    new_register_security = 0xc0756689;
    if (new_register_security(&rootkit_ops)) {
    printk("Can't register rootkit module.\n");
    return 0;
    }
    printk("Register rootkit module ok.\n");

    return 0;
    }

    static void rootkit_exit(void)
    {
    printk("Unload LSM rootkit module.\n");
    }

    module_init(rootkit_init);
    module_exit(rootkit_exit);

    Signed-off-by: Zhitong Wang
    Signed-off-by: James Morris

    wzt.wzt@gmail.com
     

01 Mar, 2010

1 commit


24 Feb, 2010

1 commit

  • Enhance the security framework to support resetting the active security
    module. This eliminates the need for direct use of the security_ops and
    default_security_ops variables outside of security.c, so make security_ops
    and default_security_ops static. Also remove the secondary_ops variable as
    a cleanup since there is no use for that. secondary_ops was originally used by
    SELinux to call the "secondary" security module (capability or dummy),
    but that was replaced by direct calls to capability and the only
    remaining use is to save and restore the original security ops pointer
    value if SELinux is disabled by early userspace based on /etc/selinux/config.
    Further, if we support this directly in the security framework, then we can
    just use &default_security_ops for this purpose since that is now available.

    Signed-off-by: Zhitong Wang
    Acked-by: Stephen Smalley
    Signed-off-by: James Morris

    wzt.wzt@gmail.com
     

07 Feb, 2010

1 commit


04 Feb, 2010

1 commit

  • This allows the LSM to distinguish between syslog functions originating
    from /proc/kmsg access and direct syscalls. By default, the commoncaps
    will now no longer require CAP_SYS_ADMIN to read an opened /proc/kmsg
    file descriptor. For example the kernel syslog reader can now drop
    privileges after opening /proc/kmsg, instead of staying privileged with
    CAP_SYS_ADMIN. MAC systems that implement security_syslog have unchanged
    behavior.

    Signed-off-by: Kees Cook
    Acked-by: Serge Hallyn
    Acked-by: John Johansen
    Signed-off-by: James Morris

    Kees Cook
     

15 Jan, 2010

1 commit

  • Currently, the getsecurity and setsecurity operations return zero for
    kernel private inodes, where xattrs are not available directly to
    userspace.

    This confuses some applications, and does not conform to the
    man page for getxattr(2) etc., which state that these syscalls
    should return ENOTSUP if xattrs are not supported or disabled.

    Note that in the listsecurity case, we still need to return zero
    as we don't know which other xattr handlers may be active.

    For discussion of userland confusion, see:
    http://www.mail-archive.com/bug-coreutils@gnu.org/msg17988.html

    This patch corrects the error returns so that ENOTSUP is reported
    to userspace as required.

    Signed-off-by: James Morris
    Acked-by: Stephen Smalley
    Acked-by: Serge Hallyn

    James Morris
     

08 Dec, 2009

1 commit


10 Nov, 2009

1 commit

  • For SELinux to do better filtering in userspace we send the name of the
    module along with the AVC denial when a program is denied module_request.

    Example output:

    type=SYSCALL msg=audit(11/03/2009 10:59:43.510:9) : arch=x86_64 syscall=write success=yes exit=2 a0=3 a1=7fc28c0d56c0 a2=2 a3=7fffca0d7440 items=0 ppid=1727 pid=1729 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=rpc.nfsd exe=/usr/sbin/rpc.nfsd subj=system_u:system_r:nfsd_t:s0 key=(null)
    type=AVC msg=audit(11/03/2009 10:59:43.510:9) : avc: denied { module_request } for pid=1729 comm=rpc.nfsd kmod="net-pf-10" scontext=system_u:system_r:nfsd_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=system

    Signed-off-by: Eric Paris
    Signed-off-by: James Morris

    Eric Paris
     

09 Nov, 2009

1 commit

  • The LSM currently requires setting a kernel parameter at boot to select
    a specific LSM. This adds a config option that allows specifying a default
    LSM that is used unless overridden with the security= kernel parameter.
    If the the config option is not set the current behavior of first LSM
    to register is used.

    Signed-off-by: John Johansen
    Acked-by: Serge Hallyn
    Signed-off-by: James Morris

    John Johansen
     

25 Oct, 2009

1 commit


12 Oct, 2009

2 commits


10 Sep, 2009

1 commit

  • This patch introduces three new hooks. The inode_getsecctx hook is used to get
    all relevant information from an LSM about an inode. The inode_setsecctx is
    used to set both the in-core and on-disk state for the inode based on a context
    derived from inode_getsecctx.The final hook inode_notifysecctx will notify the
    LSM of a change for the in-core state of the inode in question. These hooks are
    for use in the labeled NFS code and addresses concerns of how to set security
    on an inode in a multi-xattr LSM. For historical reasons Stephen Smalley's
    explanation of the reason for these hooks is pasted below.

    Quote Stephen Smalley

    inode_setsecctx: Change the security context of an inode. Updates the
    in core security context managed by the security module and invokes the
    fs code as needed (via __vfs_setxattr_noperm) to update any backing
    xattrs that represent the context. Example usage: NFS server invokes
    this hook to change the security context in its incore inode and on the
    backing file system to a value provided by the client on a SETATTR
    operation.

    inode_notifysecctx: Notify the security module of what the security
    context of an inode should be. Initializes the incore security context
    managed by the security module for this inode. Example usage: NFS
    client invokes this hook to initialize the security context in its
    incore inode to the value provided by the server for the file when the
    server returned the file's attributes to the client.

    Signed-off-by: David P. Quigley
    Acked-by: Serge Hallyn
    Signed-off-by: James Morris

    David P. Quigley
     

02 Sep, 2009

1 commit

  • Add a keyctl to install a process's session keyring onto its parent. This
    replaces the parent's session keyring. Because the COW credential code does
    not permit one process to change another process's credentials directly, the
    change is deferred until userspace next starts executing again. Normally this
    will be after a wait*() syscall.

    To support this, three new security hooks have been provided:
    cred_alloc_blank() to allocate unset security creds, cred_transfer() to fill in
    the blank security creds and key_session_to_parent() - which asks the LSM if
    the process may replace its parent's session keyring.

    The replacement may only happen if the process has the same ownership details
    as its parent, and the process has LINK permission on the session keyring, and
    the session keyring is owned by the process, and the LSM permits it.

    Note that this requires alteration to each architecture's notify_resume path.
    This has been done for all arches barring blackfin, m68k* and xtensa, all of
    which need assembly alteration to support TIF_NOTIFY_RESUME. This allows the
    replacement to be performed at the point the parent process resumes userspace
    execution.

    This allows the userspace AFS pioctl emulation to fully emulate newpag() and
    the VIOCSETTOK and VIOCSETTOK2 pioctls, all of which require the ability to
    alter the parent process's PAG membership. However, since kAFS doesn't use
    PAGs per se, but rather dumps the keys into the session keyring, the session
    keyring of the parent must be replaced if, for example, VIOCSETTOK is passed
    the newpag flag.

    This can be tested with the following program:

    #include
    #include
    #include

    #define KEYCTL_SESSION_TO_PARENT 18

    #define OSERROR(X, S) do { if ((long)(X) == -1) { perror(S); exit(1); } } while(0)

    int main(int argc, char **argv)
    {
    key_serial_t keyring, key;
    long ret;

    keyring = keyctl_join_session_keyring(argv[1]);
    OSERROR(keyring, "keyctl_join_session_keyring");

    key = add_key("user", "a", "b", 1, keyring);
    OSERROR(key, "add_key");

    ret = keyctl(KEYCTL_SESSION_TO_PARENT);
    OSERROR(ret, "KEYCTL_SESSION_TO_PARENT");

    return 0;
    }

    Compiled and linked with -lkeyutils, you should see something like:

    [dhowells@andromeda ~]$ keyctl show
    Session Keyring
    -3 --alswrv 4043 4043 keyring: _ses
    355907932 --alswrv 4043 -1 \_ keyring: _uid.4043
    [dhowells@andromeda ~]$ /tmp/newpag
    [dhowells@andromeda ~]$ keyctl show
    Session Keyring
    -3 --alswrv 4043 4043 keyring: _ses
    1055658746 --alswrv 4043 4043 \_ user: a
    [dhowells@andromeda ~]$ /tmp/newpag hello
    [dhowells@andromeda ~]$ keyctl show
    Session Keyring
    -3 --alswrv 4043 4043 keyring: hello
    340417692 --alswrv 4043 4043 \_ user: a

    Where the test program creates a new session keyring, sticks a user key named
    'a' into it and then installs it on its parent.

    Signed-off-by: David Howells
    Signed-off-by: James Morris

    David Howells
     

01 Sep, 2009

1 commit

  • The TUN driver lacks any LSM hooks which makes it difficult for LSM modules,
    such as SELinux, to enforce access controls on network traffic generated by
    TUN users; this is particularly problematic for virtualization apps such as
    QEMU and KVM. This patch adds three new LSM hooks designed to control the
    creation and attachment of TUN devices, the hooks are:

    * security_tun_dev_create()
    Provides access control for the creation of new TUN devices

    * security_tun_dev_post_create()
    Provides the ability to create the necessary socket LSM state for newly
    created TUN devices

    * security_tun_dev_attach()
    Provides access control for attaching to existing, persistent TUN devices
    and the ability to update the TUN device's socket LSM state as necessary

    Signed-off-by: Paul Moore
    Acked-by: Eric Paris
    Acked-by: Serge Hallyn
    Acked-by: David S. Miller
    Signed-off-by: James Morris

    Paul Moore
     

14 Aug, 2009

1 commit

  • Calling request_module() will trigger a userspace upcall which will load a
    new module into the kernel. This can be a dangerous event if the process
    able to trigger request_module() is able to control either the modprobe
    binary or the module binary. This patch adds a new security hook to
    request_module() which can be used by an LSM to control a processes ability
    to call request_module().

    Signed-off-by: Eric Paris
    Acked-by: Serge Hallyn
    Signed-off-by: James Morris

    Eric Paris
     

24 Jun, 2009

1 commit


04 Jun, 2009

1 commit


03 Apr, 2009

1 commit


28 Mar, 2009

1 commit

  • The socket_post_accept() hook is not currently used by any in-tree modules
    and its existence continues to cause problems by confusing people about
    what can be safely accomplished using this hook. If a legitimate need for
    this hook arises in the future it can always be reintroduced.

    Signed-off-by: Paul Moore
    Signed-off-by: James Morris

    Paul Moore
     

07 Jan, 2009

3 commits

  • James Morris
     
  • Fix a regression in cap_capable() due to:

    commit 3b11a1decef07c19443d24ae926982bc8ec9f4c0
    Author: David Howells
    Date: Fri Nov 14 10:39:26 2008 +1100

    CRED: Differentiate objective and effective subjective credentials on a task

    The problem is that the above patch allows a process to have two sets of
    credentials, and for the most part uses the subjective credentials when
    accessing current's creds.

    There is, however, one exception: cap_capable(), and thus capable(), uses the
    real/objective credentials of the target task, whether or not it is the current
    task.

    Ordinarily this doesn't matter, since usually the two cred pointers in current
    point to the same set of creds. However, sys_faccessat() makes use of this
    facility to override the credentials of the calling process to make its test,
    without affecting the creds as seen from other processes.

    One of the things sys_faccessat() does is to make an adjustment to the
    effective capabilities mask, which cap_capable(), as it stands, then ignores.

    The affected capability check is in generic_permission():

    if (!(mask & MAY_EXEC) || execute_ok(inode))
    if (capable(CAP_DAC_OVERRIDE))
    return 0;

    This change passes the set of credentials to be tested down into the commoncap
    and SELinux code. The security functions called by capable() and
    has_capability() select the appropriate set of credentials from the process
    being checked.

    This can be tested by compiling the following program from the XFS testsuite:

    /*
    * t_access_root.c - trivial test program to show permission bug.
    *
    * Written by Michael Kerrisk - copyright ownership not pursued.
    * Sourced from: http://linux.derkeiler.com/Mailing-Lists/Kernel/2003-10/6030.html
    */
    #include
    #include
    #include
    #include
    #include
    #include

    #define UID 500
    #define GID 100
    #define PERM 0
    #define TESTPATH "/tmp/t_access"

    static void
    errExit(char *msg)
    {
    perror(msg);
    exit(EXIT_FAILURE);
    } /* errExit */

    static void
    accessTest(char *file, int mask, char *mstr)
    {
    printf("access(%s, %s) returns %d\n", file, mstr, access(file, mask));
    } /* accessTest */

    int
    main(int argc, char *argv[])
    {
    int fd, perm, uid, gid;
    char *testpath;
    char cmd[PATH_MAX + 20];

    testpath = (argc > 1) ? argv[1] : TESTPATH;
    perm = (argc > 2) ? strtoul(argv[2], NULL, 8) : PERM;
    uid = (argc > 3) ? atoi(argv[3]) : UID;
    gid = (argc > 4) ? atoi(argv[4]) : GID;

    unlink(testpath);

    fd = open(testpath, O_RDWR | O_CREAT, 0);
    if (fd == -1) errExit("open");

    if (fchown(fd, uid, gid) == -1) errExit("fchown");
    if (fchmod(fd, perm) == -1) errExit("fchmod");
    close(fd);

    snprintf(cmd, sizeof(cmd), "ls -l %s", testpath);
    system(cmd);

    if (seteuid(uid) == -1) errExit("seteuid");

    accessTest(testpath, 0, "0");
    accessTest(testpath, R_OK, "R_OK");
    accessTest(testpath, W_OK, "W_OK");
    accessTest(testpath, X_OK, "X_OK");
    accessTest(testpath, R_OK | W_OK, "R_OK | W_OK");
    accessTest(testpath, R_OK | X_OK, "R_OK | X_OK");
    accessTest(testpath, W_OK | X_OK, "W_OK | X_OK");
    accessTest(testpath, R_OK | W_OK | X_OK, "R_OK | W_OK | X_OK");

    exit(EXIT_SUCCESS);
    } /* main */

    This can be run against an Ext3 filesystem as well as against an XFS
    filesystem. If successful, it will show:

    [root@andromeda src]# ./t_access_root /tmp/xxx 0 4043 4043
    ---------- 1 dhowells dhowells 0 2008-12-31 03:00 /tmp/xxx
    access(/tmp/xxx, 0) returns 0
    access(/tmp/xxx, R_OK) returns 0
    access(/tmp/xxx, W_OK) returns 0
    access(/tmp/xxx, X_OK) returns -1
    access(/tmp/xxx, R_OK | W_OK) returns 0
    access(/tmp/xxx, R_OK | X_OK) returns -1
    access(/tmp/xxx, W_OK | X_OK) returns -1
    access(/tmp/xxx, R_OK | W_OK | X_OK) returns -1

    If unsuccessful, it will show:

    [root@andromeda src]# ./t_access_root /tmp/xxx 0 4043 4043
    ---------- 1 dhowells dhowells 0 2008-12-31 02:56 /tmp/xxx
    access(/tmp/xxx, 0) returns 0
    access(/tmp/xxx, R_OK) returns -1
    access(/tmp/xxx, W_OK) returns -1
    access(/tmp/xxx, X_OK) returns -1
    access(/tmp/xxx, R_OK | W_OK) returns -1
    access(/tmp/xxx, R_OK | X_OK) returns -1
    access(/tmp/xxx, W_OK | X_OK) returns -1
    access(/tmp/xxx, R_OK | W_OK | X_OK) returns -1

    I've also tested the fix with the SELinux and syscalls LTP testsuites.

    Signed-off-by: David Howells
    Tested-by: J. Bruce Fields
    Acked-by: Serge Hallyn
    Signed-off-by: James Morris

    David Howells
     
  • This reverts commit 14eaddc967b16017d4a1a24d2be6c28ecbe06ed8.

    David has a better version to come.

    James Morris
     

05 Jan, 2009

1 commit

  • Fix a regression in cap_capable() due to:

    commit 5ff7711e635b32f0a1e558227d030c7e45b4a465
    Author: David Howells
    Date: Wed Dec 31 02:52:28 2008 +0000

    CRED: Differentiate objective and effective subjective credentials on a task

    The problem is that the above patch allows a process to have two sets of
    credentials, and for the most part uses the subjective credentials when
    accessing current's creds.

    There is, however, one exception: cap_capable(), and thus capable(), uses the
    real/objective credentials of the target task, whether or not it is the current
    task.

    Ordinarily this doesn't matter, since usually the two cred pointers in current
    point to the same set of creds. However, sys_faccessat() makes use of this
    facility to override the credentials of the calling process to make its test,
    without affecting the creds as seen from other processes.

    One of the things sys_faccessat() does is to make an adjustment to the
    effective capabilities mask, which cap_capable(), as it stands, then ignores.

    The affected capability check is in generic_permission():

    if (!(mask & MAY_EXEC) || execute_ok(inode))
    if (capable(CAP_DAC_OVERRIDE))
    return 0;

    This change splits capable() from has_capability() down into the commoncap and
    SELinux code. The capable() security op now only deals with the current
    process, and uses the current process's subjective creds. A new security op -
    task_capable() - is introduced that can check any task's objective creds.

    strictly the capable() security op is superfluous with the presence of the
    task_capable() op, however it should be faster to call the capable() op since
    two fewer arguments need be passed down through the various layers.

    This can be tested by compiling the following program from the XFS testsuite:

    /*
    * t_access_root.c - trivial test program to show permission bug.
    *
    * Written by Michael Kerrisk - copyright ownership not pursued.
    * Sourced from: http://linux.derkeiler.com/Mailing-Lists/Kernel/2003-10/6030.html
    */
    #include
    #include
    #include
    #include
    #include
    #include

    #define UID 500
    #define GID 100
    #define PERM 0
    #define TESTPATH "/tmp/t_access"

    static void
    errExit(char *msg)
    {
    perror(msg);
    exit(EXIT_FAILURE);
    } /* errExit */

    static void
    accessTest(char *file, int mask, char *mstr)
    {
    printf("access(%s, %s) returns %d\n", file, mstr, access(file, mask));
    } /* accessTest */

    int
    main(int argc, char *argv[])
    {
    int fd, perm, uid, gid;
    char *testpath;
    char cmd[PATH_MAX + 20];

    testpath = (argc > 1) ? argv[1] : TESTPATH;
    perm = (argc > 2) ? strtoul(argv[2], NULL, 8) : PERM;
    uid = (argc > 3) ? atoi(argv[3]) : UID;
    gid = (argc > 4) ? atoi(argv[4]) : GID;

    unlink(testpath);

    fd = open(testpath, O_RDWR | O_CREAT, 0);
    if (fd == -1) errExit("open");

    if (fchown(fd, uid, gid) == -1) errExit("fchown");
    if (fchmod(fd, perm) == -1) errExit("fchmod");
    close(fd);

    snprintf(cmd, sizeof(cmd), "ls -l %s", testpath);
    system(cmd);

    if (seteuid(uid) == -1) errExit("seteuid");

    accessTest(testpath, 0, "0");
    accessTest(testpath, R_OK, "R_OK");
    accessTest(testpath, W_OK, "W_OK");
    accessTest(testpath, X_OK, "X_OK");
    accessTest(testpath, R_OK | W_OK, "R_OK | W_OK");
    accessTest(testpath, R_OK | X_OK, "R_OK | X_OK");
    accessTest(testpath, W_OK | X_OK, "W_OK | X_OK");
    accessTest(testpath, R_OK | W_OK | X_OK, "R_OK | W_OK | X_OK");

    exit(EXIT_SUCCESS);
    } /* main */

    This can be run against an Ext3 filesystem as well as against an XFS
    filesystem. If successful, it will show:

    [root@andromeda src]# ./t_access_root /tmp/xxx 0 4043 4043
    ---------- 1 dhowells dhowells 0 2008-12-31 03:00 /tmp/xxx
    access(/tmp/xxx, 0) returns 0
    access(/tmp/xxx, R_OK) returns 0
    access(/tmp/xxx, W_OK) returns 0
    access(/tmp/xxx, X_OK) returns -1
    access(/tmp/xxx, R_OK | W_OK) returns 0
    access(/tmp/xxx, R_OK | X_OK) returns -1
    access(/tmp/xxx, W_OK | X_OK) returns -1
    access(/tmp/xxx, R_OK | W_OK | X_OK) returns -1

    If unsuccessful, it will show:

    [root@andromeda src]# ./t_access_root /tmp/xxx 0 4043 4043
    ---------- 1 dhowells dhowells 0 2008-12-31 02:56 /tmp/xxx
    access(/tmp/xxx, 0) returns 0
    access(/tmp/xxx, R_OK) returns -1
    access(/tmp/xxx, W_OK) returns -1
    access(/tmp/xxx, X_OK) returns -1
    access(/tmp/xxx, R_OK | W_OK) returns -1
    access(/tmp/xxx, R_OK | X_OK) returns -1
    access(/tmp/xxx, W_OK | X_OK) returns -1
    access(/tmp/xxx, R_OK | W_OK | X_OK) returns -1

    I've also tested the fix with the SELinux and syscalls LTP testsuites.

    Signed-off-by: David Howells
    Signed-off-by: James Morris

    David Howells
     

01 Jan, 2009

1 commit