diff options
Diffstat (limited to 'security/security.c')
| -rw-r--r-- | security/security.c | 71 | 
1 files changed, 61 insertions, 10 deletions
diff --git a/security/security.c b/security/security.c index 5ac96b16f8fa..b38155b2de83 100644 --- a/security/security.c +++ b/security/security.c @@ -203,6 +203,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)  	lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode);  	lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc);  	lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); +	lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);  	lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);  } @@ -333,12 +334,13 @@ static void __init ordered_lsm_init(void)  	for (lsm = ordered_lsms; *lsm; lsm++)  		prepare_lsm(*lsm); -	init_debug("cred blob size     = %d\n", blob_sizes.lbs_cred); -	init_debug("file blob size     = %d\n", blob_sizes.lbs_file); -	init_debug("inode blob size    = %d\n", blob_sizes.lbs_inode); -	init_debug("ipc blob size      = %d\n", blob_sizes.lbs_ipc); -	init_debug("msg_msg blob size  = %d\n", blob_sizes.lbs_msg_msg); -	init_debug("task blob size     = %d\n", blob_sizes.lbs_task); +	init_debug("cred blob size       = %d\n", blob_sizes.lbs_cred); +	init_debug("file blob size       = %d\n", blob_sizes.lbs_file); +	init_debug("inode blob size      = %d\n", blob_sizes.lbs_inode); +	init_debug("ipc blob size        = %d\n", blob_sizes.lbs_ipc); +	init_debug("msg_msg blob size    = %d\n", blob_sizes.lbs_msg_msg); +	init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock); +	init_debug("task blob size       = %d\n", blob_sizes.lbs_task);  	/*  	 * Create any kmem_caches needed for blobs @@ -670,6 +672,27 @@ static void __init lsm_early_task(struct task_struct *task)  		panic("%s: Early task alloc failed.\n", __func__);  } +/** + * lsm_superblock_alloc - allocate a composite superblock blob + * @sb: the superblock that needs a blob + * + * Allocate the superblock blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +static int lsm_superblock_alloc(struct super_block *sb) +{ +	if (blob_sizes.lbs_superblock == 0) { +		sb->s_security = NULL; +		return 0; +	} + +	sb->s_security = kzalloc(blob_sizes.lbs_superblock, GFP_KERNEL); +	if (sb->s_security == NULL) +		return -ENOMEM; +	return 0; +} +  /*   * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and   * can be accessed with: @@ -867,12 +890,26 @@ int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *  int security_sb_alloc(struct super_block *sb)  { -	return call_int_hook(sb_alloc_security, 0, sb); +	int rc = lsm_superblock_alloc(sb); + +	if (unlikely(rc)) +		return rc; +	rc = call_int_hook(sb_alloc_security, 0, sb); +	if (unlikely(rc)) +		security_sb_free(sb); +	return rc; +} + +void security_sb_delete(struct super_block *sb) +{ +	call_void_hook(sb_delete, sb);  }  void security_sb_free(struct super_block *sb)  {  	call_void_hook(sb_free_security, sb); +	kfree(sb->s_security); +	sb->s_security = NULL;  }  void security_free_mnt_opts(void **mnt_opts) @@ -890,6 +927,13 @@ int security_sb_eat_lsm_opts(char *options, void **mnt_opts)  }  EXPORT_SYMBOL(security_sb_eat_lsm_opts); +int security_sb_mnt_opts_compat(struct super_block *sb, +				void *mnt_opts) +{ +	return call_int_hook(sb_mnt_opts_compat, 0, sb, mnt_opts); +} +EXPORT_SYMBOL(security_sb_mnt_opts_compat); +  int security_sb_remount(struct super_block *sb,  			void *mnt_opts)  { @@ -1762,12 +1806,19 @@ int security_task_getsid(struct task_struct *p)  	return call_int_hook(task_getsid, 0, p);  } -void security_task_getsecid(struct task_struct *p, u32 *secid) +void security_task_getsecid_subj(struct task_struct *p, u32 *secid) +{ +	*secid = 0; +	call_void_hook(task_getsecid_subj, p, secid); +} +EXPORT_SYMBOL(security_task_getsecid_subj); + +void security_task_getsecid_obj(struct task_struct *p, u32 *secid)  {  	*secid = 0; -	call_void_hook(task_getsecid, p, secid); +	call_void_hook(task_getsecid_obj, p, secid);  } -EXPORT_SYMBOL(security_task_getsecid); +EXPORT_SYMBOL(security_task_getsecid_obj);  int security_task_setnice(struct task_struct *p, int nice)  {  |