Skip to content

Commit

Permalink
Merge branch 'next' into for-linus
Browse files Browse the repository at this point in the history
  • Loading branch information
James Morris committed Jun 11, 2009
2 parents 769f3e8 + 35f2c2f commit 73fbad2
Show file tree
Hide file tree
Showing 58 changed files with 1,946 additions and 477 deletions.
20 changes: 18 additions & 2 deletions Documentation/Smack.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,9 @@ length. Single character labels using special characters, that being anything
other than a letter or digit, are reserved for use by the Smack development
team. Smack labels are unstructured, case sensitive, and the only operation
ever performed on them is comparison for equality. Smack labels cannot
contain unprintable characters or the "/" (slash) character. Smack labels
cannot begin with a '-', which is reserved for special options.
contain unprintable characters, the "/" (slash), the "\" (backslash), the "'"
(quote) and '"' (double-quote) characters.
Smack labels cannot begin with a '-', which is reserved for special options.

There are some predefined labels:

Expand Down Expand Up @@ -523,3 +524,18 @@ Smack supports some mount options:

These mount options apply to all file system types.

Smack auditing

If you want Smack auditing of security events, you need to set CONFIG_AUDIT
in your kernel configuration.
By default, all denied events will be audited. You can change this behavior by
writing a single character to the /smack/logging file :
0 : no logging
1 : log denied (default)
2 : log accepted
3 : log denied & accepted

Events are logged as 'key=value' pairs, for each event you at least will get
the subjet, the object, the rights requested, the action, the kernel function
that triggered the event, plus other pairs depending on the type of event
audited.
6 changes: 6 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,12 @@ and is between 256 and 4096 characters. It is defined in the file
Formt: { "sha1" | "md5" }
default: "sha1"

ima_tcb [IMA]
Load a policy which meets the needs of the Trusted
Computing Base. This means IMA will measure all
programs exec'd, files mmap'd for exec, and all files
opened for read by uid=0.

in2000= [HW,SCSI]
See header of drivers/scsi/in2000.c.

Expand Down
11 changes: 11 additions & 0 deletions Documentation/sysctl/kernel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ show up in /proc/sys/kernel:
- kstack_depth_to_print [ X86 only ]
- l2cr [ PPC only ]
- modprobe ==> Documentation/debugging-modules.txt
- modules_disabled
- msgmax
- msgmnb
- msgmni
Expand Down Expand Up @@ -184,6 +185,16 @@ kernel stack.

==============================================================

modules_disabled:

A toggle value indicating if modules are allowed to be loaded
in an otherwise modular kernel. This toggle defaults to off
(0), but can be set true (1). Once true, modules can be
neither loaded nor unloaded, and the toggle cannot be set back
to false.

==============================================================

osrelease, ostype & version:

# cat osrelease
Expand Down
6 changes: 3 additions & 3 deletions fs/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1488,7 +1488,7 @@ int compat_do_execve(char * filename,
if (!bprm)
goto out_files;

retval = mutex_lock_interruptible(&current->cred_exec_mutex);
retval = mutex_lock_interruptible(&current->cred_guard_mutex);
if (retval < 0)
goto out_free;
current->in_execve = 1;
Expand Down Expand Up @@ -1550,7 +1550,7 @@ int compat_do_execve(char * filename,
/* execve succeeded */
current->fs->in_exec = 0;
current->in_execve = 0;
mutex_unlock(&current->cred_exec_mutex);
mutex_unlock(&current->cred_guard_mutex);
acct_update_integrals(current);
free_bprm(bprm);
if (displaced)
Expand All @@ -1573,7 +1573,7 @@ int compat_do_execve(char * filename,

out_unlock:
current->in_execve = 0;
mutex_unlock(&current->cred_exec_mutex);
mutex_unlock(&current->cred_guard_mutex);

out_free:
free_bprm(bprm);
Expand Down
10 changes: 5 additions & 5 deletions fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,7 @@ void install_exec_creds(struct linux_binprm *bprm)
commit_creds(bprm->cred);
bprm->cred = NULL;

/* cred_exec_mutex must be held at least to this point to prevent
/* cred_guard_mutex must be held at least to this point to prevent
* ptrace_attach() from altering our determination of the task's
* credentials; any time after this it may be unlocked */

Expand All @@ -1026,7 +1026,7 @@ EXPORT_SYMBOL(install_exec_creds);

/*
* determine how safe it is to execute the proposed program
* - the caller must hold current->cred_exec_mutex to protect against
* - the caller must hold current->cred_guard_mutex to protect against
* PTRACE_ATTACH
*/
int check_unsafe_exec(struct linux_binprm *bprm)
Expand Down Expand Up @@ -1268,7 +1268,7 @@ int do_execve(char * filename,
if (!bprm)
goto out_files;

retval = mutex_lock_interruptible(&current->cred_exec_mutex);
retval = mutex_lock_interruptible(&current->cred_guard_mutex);
if (retval < 0)
goto out_free;
current->in_execve = 1;
Expand Down Expand Up @@ -1331,7 +1331,7 @@ int do_execve(char * filename,
/* execve succeeded */
current->fs->in_exec = 0;
current->in_execve = 0;
mutex_unlock(&current->cred_exec_mutex);
mutex_unlock(&current->cred_guard_mutex);
acct_update_integrals(current);
free_bprm(bprm);
if (displaced)
Expand All @@ -1354,7 +1354,7 @@ int do_execve(char * filename,

out_unlock:
current->in_execve = 0;
mutex_unlock(&current->cred_exec_mutex);
mutex_unlock(&current->cred_guard_mutex);

out_free:
free_bprm(bprm);
Expand Down
2 changes: 2 additions & 0 deletions fs/hugetlbfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <linux/dnotify.h>
#include <linux/statfs.h>
#include <linux/security.h>
#include <linux/ima.h>

#include <asm/uaccess.h>

Expand Down Expand Up @@ -986,6 +987,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag)
&hugetlbfs_file_operations);
if (!file)
goto out_dentry; /* inode is already attached */
ima_counts_get(file);

return file;

Expand Down
6 changes: 4 additions & 2 deletions fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
err = inode_permission(nd->path.dentry->d_inode,
MAY_EXEC);
if (!err)
err = ima_path_check(&nd->path, MAY_EXEC);
err = ima_path_check(&nd->path, MAY_EXEC,
IMA_COUNT_UPDATE);
if (err)
break;

Expand Down Expand Up @@ -1515,7 +1516,8 @@ int may_open(struct path *path, int acc_mode, int flag)
return error;

error = ima_path_check(path,
acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));
acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC),
IMA_COUNT_UPDATE);
if (error)
return error;
/*
Expand Down
14 changes: 14 additions & 0 deletions fs/nfsd/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include <linux/security.h>
#endif /* CONFIG_NFSD_V4 */
#include <linux/jhash.h>
#include <linux/ima.h>

#include <asm/uaccess.h>

Expand Down Expand Up @@ -735,6 +736,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
flags, cred);
if (IS_ERR(*filp))
host_err = PTR_ERR(*filp);
else
ima_counts_get(*filp);
out_nfserr:
err = nfserrno(host_err);
out:
Expand Down Expand Up @@ -2024,6 +2027,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
struct dentry *dentry, int acc)
{
struct inode *inode = dentry->d_inode;
struct path path;
int err;

if (acc == NFSD_MAY_NOP)
Expand Down Expand Up @@ -2096,7 +2100,17 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
if (err == -EACCES && S_ISREG(inode->i_mode) &&
acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE))
err = inode_permission(inode, MAY_EXEC);
if (err)
goto nfsd_out;

/* Do integrity (permission) checking now, but defer incrementing
* IMA counts to the actual file open.
*/
path.mnt = exp->ex_path.mnt;
path.dentry = dentry;
err = ima_path_check(&path, acc & (MAY_READ | MAY_WRITE | MAY_EXEC),
IMA_COUNT_LEAVE);
nfsd_out:
return err? nfserrno(err) : 0;
}

Expand Down
6 changes: 6 additions & 0 deletions fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2128,9 +2128,15 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
if (copy_from_user(page, buf, count))
goto out_free;

/* Guard against adverse ptrace interaction */
length = mutex_lock_interruptible(&task->cred_guard_mutex);
if (length < 0)
goto out_free;

length = security_setprocattr(task,
(char*)file->f_path.dentry->d_name.name,
(void*)page, count);
mutex_unlock(&task->cred_guard_mutex);
out_free:
free_page((unsigned long) page);
out:
Expand Down
11 changes: 7 additions & 4 deletions include/linux/ima.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@
#include <linux/fs.h>
struct linux_binprm;

#define IMA_COUNT_UPDATE 1
#define IMA_COUNT_LEAVE 0

#ifdef CONFIG_IMA
extern int ima_bprm_check(struct linux_binprm *bprm);
extern int ima_inode_alloc(struct inode *inode);
extern void ima_inode_free(struct inode *inode);
extern int ima_path_check(struct path *path, int mask);
extern int ima_path_check(struct path *path, int mask, int update_counts);
extern void ima_file_free(struct file *file);
extern int ima_file_mmap(struct file *file, unsigned long prot);
extern void ima_shm_check(struct file *file);
extern void ima_counts_get(struct file *file);

#else
static inline int ima_bprm_check(struct linux_binprm *bprm)
Expand All @@ -38,7 +41,7 @@ static inline void ima_inode_free(struct inode *inode)
return;
}

static inline int ima_path_check(struct path *path, int mask)
static inline int ima_path_check(struct path *path, int mask, int update_counts)
{
return 0;
}
Expand All @@ -53,7 +56,7 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
return 0;
}

static inline void ima_shm_check(struct file *file)
static inline void ima_counts_get(struct file *file)
{
return;
}
Expand Down
4 changes: 2 additions & 2 deletions include/linux/init_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ extern struct cred init_cred;
.group_leader = &tsk, \
.real_cred = &init_cred, \
.cred = &init_cred, \
.cred_exec_mutex = \
__MUTEX_INITIALIZER(tsk.cred_exec_mutex), \
.cred_guard_mutex = \
__MUTEX_INITIALIZER(tsk.cred_guard_mutex), \
.comm = "swapper", \
.thread = INIT_THREAD, \
.fs = &init_fs, \
Expand Down
111 changes: 111 additions & 0 deletions include/linux/lsm_audit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Common LSM logging functions
* Heavily borrowed from selinux/avc.h
*
* Author : Etienne BASSET <etienne.basset@ensta.org>
*
* All credits to : Stephen Smalley, <sds@epoch.ncsc.mil>
* All BUGS to : Etienne BASSET <etienne.basset@ensta.org>
*/
#ifndef _LSM_COMMON_LOGGING_
#define _LSM_COMMON_LOGGING_

#include <linux/stddef.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/kdev_t.h>
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/audit.h>
#include <linux/in6.h>
#include <linux/path.h>
#include <linux/key.h>
#include <linux/skbuff.h>
#include <asm/system.h>


/* Auxiliary data to use in generating the audit record. */
struct common_audit_data {
char type;
#define LSM_AUDIT_DATA_FS 1
#define LSM_AUDIT_DATA_NET 2
#define LSM_AUDIT_DATA_CAP 3
#define LSM_AUDIT_DATA_IPC 4
#define LSM_AUDIT_DATA_TASK 5
#define LSM_AUDIT_DATA_KEY 6
struct task_struct *tsk;
union {
struct {
struct path path;
struct inode *inode;
} fs;
struct {
int netif;
struct sock *sk;
u16 family;
__be16 dport;
__be16 sport;
union {
struct {
__be32 daddr;
__be32 saddr;
} v4;
struct {
struct in6_addr daddr;
struct in6_addr saddr;
} v6;
} fam;
} net;
int cap;
int ipc_id;
struct task_struct *tsk;
#ifdef CONFIG_KEYS
struct {
key_serial_t key;
char *key_desc;
} key_struct;
#endif
} u;
const char *function;
/* this union contains LSM specific data */
union {
/* SMACK data */
struct smack_audit_data {
char *subject;
char *object;
char *request;
int result;
} smack_audit_data;
/* SELinux data */
struct {
u32 ssid;
u32 tsid;
u16 tclass;
u32 requested;
u32 audited;
struct av_decision *avd;
int result;
} selinux_audit_data;
} lsm_priv;
/* these callback will be implemented by a specific LSM */
void (*lsm_pre_audit)(struct audit_buffer *, void *);
void (*lsm_post_audit)(struct audit_buffer *, void *);
};

#define v4info fam.v4
#define v6info fam.v6

int ipv4_skb_to_auditdata(struct sk_buff *skb,
struct common_audit_data *ad, u8 *proto);

int ipv6_skb_to_auditdata(struct sk_buff *skb,
struct common_audit_data *ad, u8 *proto);

/* Initialize an LSM audit data structure. */
#define COMMON_AUDIT_DATA_INIT(_d, _t) \
{ memset((_d), 0, sizeof(struct common_audit_data)); \
(_d)->type = LSM_AUDIT_DATA_##_t; (_d)->function = __func__; }

void common_lsm_audit(struct common_audit_data *a);

#endif
Loading

0 comments on commit 73fbad2

Please sign in to comment.