Commit d488d3a4 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull security subsystem updates from James Morris:
 "Highlights for this window:

   - improved AVC hashing for SELinux by John Brooks and Stephen Smalley

   - addition of an unconfined label to Smack

   - Smack documentation update

   - TPM driver updates"

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (28 commits)
  lsm: copy comm before calling audit_log to avoid race in string printing
  tomoyo: Do not generate empty policy files
  tomoyo: Use if_changed when generating builtin-policy.h
  tomoyo: Use bin2c to generate builtin-policy.h
  selinux: increase avtab max buckets
  selinux: Use a better hash function for avtab
  selinux: convert avtab hash table to flex_array
  selinux: reconcile security_netlbl_secattr_to_sid() and mls_import_netlbl_cat()
  selinux: remove unnecessary pointer reassignment
  Smack: Updates for Smack documentation
  tpm/st33zp24/spi: Add missing device table for spi phy.
  tpm/st33zp24: Add proper wait for ordinal duration in case of irq mode
  smack: Fix gcc warning from unused smack_syslog_lock mutex in smackfs.c
  Smack: Allow an unconfined label in bringup mode
  Smack: getting the Smack security context of keys
  Smack: Assign smack_known_web as default smk_in label for kernel thread's socket
  tpm/tpm_infineon: Use struct dev_pm_ops for power management
  MAINTAINERS: Add Jason as designated reviewer for TPM
  tpm: Update KConfig text to include TPM2.0 FIFO chips
  tpm/st33zp24/dts/st33zp24-spi: Add dts documentation for st33zp24 spi phy
  ...
parents cb906953 5deeb5ce
* STMicroelectronics SAS. ST33ZP24 TPM SoC
Required properties:
- compatible: Should be "st,st33zp24-spi".
- spi-max-frequency: Maximum SPI frequency (<= 10000000).
Optional ST33ZP24 Properties:
- interrupt-parent: phandle for the interrupt gpio controller
- interrupts: GPIO interrupt to which the chip is connected
- lpcpd-gpios: Output GPIO pin used for ST33ZP24 power management D1/D2 state.
If set, power must be present when the platform is going into sleep/hibernate mode.
Optional SoC Specific Properties:
- pinctrl-names: Contains only one value - "default".
- pintctrl-0: Specifies the pin control groups used for this controller.
Example (for ARM-based BeagleBoard xM with ST33ZP24 on SPI4):
&mcspi4 {
status = "okay";
st33zp24@0 {
compatible = "st,st33zp24-spi";
spi-max-frequency = <10000000>;
interrupt-parent = <&gpio5>;
interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
lpcpd-gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>;
};
};
This diff is collapsed.
......@@ -9968,6 +9968,7 @@ F: drivers/media/pci/tw68/
TPM DEVICE DRIVER
M: Peter Huewe <peterhuewe@gmx.de>
M: Marcel Selhorst <tpmdd@selhorst.net>
R: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
W: http://tpmdd.sourceforge.net
L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
Q: git git://github.com/PeterHuewe/linux-tpmdd.git
......
......@@ -25,13 +25,14 @@ menuconfig TCG_TPM
if TCG_TPM
config TCG_TIS
tristate "TPM Interface Specification 1.2 Interface"
tristate "TPM Interface Specification 1.2 Interface / TPM 2.0 FIFO Interface"
depends on X86
---help---
If you have a TPM security chip that is compliant with the
TCG TIS 1.2 TPM specification say Yes and it will be accessible
from within Linux. To compile this driver as a module, choose
M here; the module will be called tpm_tis.
TCG TIS 1.2 TPM specification (TPM1.2) or the TCG PTP FIFO
specification (TPM2.0) say Yes and it will be accessible from
within Linux. To compile this driver as a module, choose M here;
the module will be called tpm_tis.
config TCG_TIS_I2C_ATMEL
tristate "TPM Interface Specification 1.2 Interface (I2C - Atmel)"
......@@ -100,16 +101,6 @@ config TCG_IBMVTPM
will be accessible from within Linux. To compile this driver
as a module, choose M here; the module will be called tpm_ibmvtpm.
config TCG_TIS_I2C_ST33
tristate "TPM Interface Specification 1.2 Interface (I2C - STMicroelectronics)"
depends on I2C
depends on GPIOLIB
---help---
If you have a TPM security chip from STMicroelectronics working with
an I2C bus say Yes and it will be accessible from within Linux.
To compile this driver as a module, choose M here; the module will be
called tpm_i2c_stm_st33.
config TCG_XEN
tristate "XEN TPM Interface"
depends on TCG_TPM && XEN
......@@ -131,4 +122,5 @@ config TCG_CRB
from within Linux. To compile this driver as a module, choose
M here; the module will be called tpm_crb.
source "drivers/char/tpm/st33zp24/Kconfig"
endif # TCG_TPM
......@@ -20,6 +20,6 @@ obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
obj-$(CONFIG_TCG_IBMVTPM) += tpm_ibmvtpm.o
obj-$(CONFIG_TCG_TIS_I2C_ST33) += tpm_i2c_stm_st33.o
obj-$(CONFIG_TCG_TIS_ST33ZP24) += st33zp24/
obj-$(CONFIG_TCG_XEN) += xen-tpmfront.o
obj-$(CONFIG_TCG_CRB) += tpm_crb.o
config TCG_TIS_ST33ZP24
tristate "STMicroelectronics TPM Interface Specification 1.2 Interface"
depends on GPIOLIB
---help---
STMicroelectronics ST33ZP24 core driver. It implements the core
TPM1.2 logic and hooks into the TPM kernel APIs. Physical layers will
register against it.
To compile this driver as a module, choose m here. The module will be called
tpm_st33zp24.
config TCG_TIS_ST33ZP24_I2C
tristate "TPM 1.2 ST33ZP24 I2C support"
depends on TCG_TIS_ST33ZP24
depends on I2C
---help---
This module adds support for the STMicroelectronics TPM security chip
ST33ZP24 with i2c interface.
To compile this driver as a module, choose M here; the module will be
called tpm_st33zp24_i2c.
config TCG_TIS_ST33ZP24_SPI
tristate "TPM 1.2 ST33ZP24 SPI support"
depends on TCG_TIS_ST33ZP24
depends on SPI
---help---
This module adds support for the STMicroelectronics TPM security chip
ST33ZP24 with spi interface.
To compile this driver as a module, choose M here; the module will be
called tpm_st33zp24_spi.
#
# Makefile for ST33ZP24 TPM 1.2 driver
#
tpm_st33zp24-objs = st33zp24.o
obj-$(CONFIG_TCG_TIS_ST33ZP24) += tpm_st33zp24.o
tpm_st33zp24_i2c-objs = i2c.o
obj-$(CONFIG_TCG_TIS_ST33ZP24_I2C) += tpm_st33zp24_i2c.o
tpm_st33zp24_spi-objs = spi.o
obj-$(CONFIG_TCG_TIS_ST33ZP24_SPI) += tpm_st33zp24_spi.o
/*
* STMicroelectronics TPM I2C Linux driver for TPM ST33ZP24
* Copyright (C) 2009 - 2015 STMicroelectronics
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/tpm.h>
#include <linux/platform_data/st33zp24.h>
#include "st33zp24.h"
#define TPM_DUMMY_BYTE 0xAA
struct st33zp24_i2c_phy {
struct i2c_client *client;
u8 buf[TPM_BUFSIZE + 1];
int io_lpcpd;
};
/*
* write8_reg
* Send byte to the TIS register according to the ST33ZP24 I2C protocol.
* @param: tpm_register, the tpm tis register where the data should be written
* @param: tpm_data, the tpm_data to write inside the tpm_register
* @param: tpm_size, The length of the data
* @return: Returns negative errno, or else the number of bytes written.
*/
static int write8_reg(void *phy_id, u8 tpm_register, u8 *tpm_data, int tpm_size)
{
struct st33zp24_i2c_phy *phy = phy_id;
phy->buf[0] = tpm_register;
memcpy(phy->buf + 1, tpm_data, tpm_size);
return i2c_master_send(phy->client, phy->buf, tpm_size + 1);
} /* write8_reg() */
/*
* read8_reg
* Recv byte from the TIS register according to the ST33ZP24 I2C protocol.
* @param: tpm_register, the tpm tis register where the data should be read
* @param: tpm_data, the TPM response
* @param: tpm_size, tpm TPM response size to read.
* @return: number of byte read successfully: should be one if success.
*/
static int read8_reg(void *phy_id, u8 tpm_register, u8 *tpm_data, int tpm_size)
{
struct st33zp24_i2c_phy *phy = phy_id;
u8 status = 0;
u8 data;
data = TPM_DUMMY_BYTE;
status = write8_reg(phy, tpm_register, &data, 1);
if (status == 2)
status = i2c_master_recv(phy->client, tpm_data, tpm_size);
return status;
} /* read8_reg() */
/*
* st33zp24_i2c_send
* Send byte to the TIS register according to the ST33ZP24 I2C protocol.
* @param: phy_id, the phy description
* @param: tpm_register, the tpm tis register where the data should be written
* @param: tpm_data, the tpm_data to write inside the tpm_register
* @param: tpm_size, the length of the data
* @return: number of byte written successfully: should be one if success.
*/
static int st33zp24_i2c_send(void *phy_id, u8 tpm_register, u8 *tpm_data,
int tpm_size)
{
return write8_reg(phy_id, tpm_register | TPM_WRITE_DIRECTION, tpm_data,
tpm_size);
}
/*
* st33zp24_i2c_recv
* Recv byte from the TIS register according to the ST33ZP24 I2C protocol.
* @param: phy_id, the phy description
* @param: tpm_register, the tpm tis register where the data should be read
* @param: tpm_data, the TPM response
* @param: tpm_size, tpm TPM response size to read.
* @return: number of byte read successfully: should be one if success.
*/
static int st33zp24_i2c_recv(void *phy_id, u8 tpm_register, u8 *tpm_data,
int tpm_size)
{
return read8_reg(phy_id, tpm_register, tpm_data, tpm_size);
}
static const struct st33zp24_phy_ops i2c_phy_ops = {
.send = st33zp24_i2c_send,
.recv = st33zp24_i2c_recv,
};
#ifdef CONFIG_OF
static int st33zp24_i2c_of_request_resources(struct st33zp24_i2c_phy *phy)
{
struct device_node *pp;
struct i2c_client *client = phy->client;
int gpio;
int ret;
pp = client->dev.of_node;
if (!pp) {
dev_err(&client->dev, "No platform data\n");
return -ENODEV;
}
/* Get GPIO from device tree */
gpio = of_get_named_gpio(pp, "lpcpd-gpios", 0);
if (gpio < 0) {
dev_err(&client->dev,
"Failed to retrieve lpcpd-gpios from dts.\n");
phy->io_lpcpd = -1;
/*
* lpcpd pin is not specified. This is not an issue as
* power management can be also managed by TPM specific
* commands. So leave with a success status code.
*/
return 0;
}
/* GPIO request and configuration */
ret = devm_gpio_request_one(&client->dev, gpio,
GPIOF_OUT_INIT_HIGH, "TPM IO LPCPD");
if (ret) {
dev_err(&client->dev, "Failed to request lpcpd pin\n");
return -ENODEV;
}
phy->io_lpcpd = gpio;
return 0;
}
#else
static int st33zp24_i2c_of_request_resources(struct st33zp24_i2c_phy *phy)
{
return -ENODEV;
}
#endif
static int st33zp24_i2c_request_resources(struct i2c_client *client,
struct st33zp24_i2c_phy *phy)
{
struct st33zp24_platform_data *pdata;
int ret;
pdata = client->dev.platform_data;
if (!pdata) {
dev_err(&client->dev, "No platform data\n");
return -ENODEV;
}
/* store for late use */
phy->io_lpcpd = pdata->io_lpcpd;
if (gpio_is_valid(pdata->io_lpcpd)) {
ret = devm_gpio_request_one(&client->dev,
pdata->io_lpcpd, GPIOF_OUT_INIT_HIGH,
"TPM IO_LPCPD");
if (ret) {
dev_err(&client->dev, "Failed to request lpcpd pin\n");
return ret;
}
}
return 0;
}
/*
* st33zp24_i2c_probe initialize the TPM device
* @param: client, the i2c_client drescription (TPM I2C description).
* @param: id, the i2c_device_id struct.
* @return: 0 in case of success.
* -1 in other case.
*/
static int st33zp24_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
struct st33zp24_platform_data *pdata;
struct st33zp24_i2c_phy *phy;
if (!client) {
pr_info("%s: i2c client is NULL. Device not accessible.\n",
__func__);
return -ENODEV;
}
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_info(&client->dev, "client not i2c capable\n");
return -ENODEV;
}
phy = devm_kzalloc(&client->dev, sizeof(struct st33zp24_i2c_phy),
GFP_KERNEL);
if (!phy)
return -ENOMEM;
phy->client = client;
pdata = client->dev.platform_data;
if (!pdata && client->dev.of_node) {
ret = st33zp24_i2c_of_request_resources(phy);
if (ret)
return ret;
} else if (pdata) {
ret = st33zp24_i2c_request_resources(client, phy);
if (ret)
return ret;
}
return st33zp24_probe(phy, &i2c_phy_ops, &client->dev, client->irq,
phy->io_lpcpd);
}
/*
* st33zp24_i2c_remove remove the TPM device
* @param: client, the i2c_client description (TPM I2C description).
* @return: 0 in case of success.
*/
static int st33zp24_i2c_remove(struct i2c_client *client)
{
struct tpm_chip *chip = i2c_get_clientdata(client);
return st33zp24_remove(chip);
}
static const struct i2c_device_id st33zp24_i2c_id[] = {
{TPM_ST33_I2C, 0},
{}
};
MODULE_DEVICE_TABLE(i2c, st33zp24_i2c_id);
#ifdef CONFIG_OF
static const struct of_device_id of_st33zp24_i2c_match[] = {
{ .compatible = "st,st33zp24-i2c", },
{}
};
MODULE_DEVICE_TABLE(of, of_st33zp24_i2c_match);
#endif
static SIMPLE_DEV_PM_OPS(st33zp24_i2c_ops, st33zp24_pm_suspend,
st33zp24_pm_resume);
static struct i2c_driver st33zp24_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = TPM_ST33_I2C,
.pm = &st33zp24_i2c_ops,
.of_match_table = of_match_ptr(of_st33zp24_i2c_match),
},
.probe = st33zp24_i2c_probe,
.remove = st33zp24_i2c_remove,
.id_table = st33zp24_i2c_id
};
module_i2c_driver(st33zp24_i2c_driver);
MODULE_AUTHOR("TPM support (TPMsupport@list.st.com)");
MODULE_DESCRIPTION("STM TPM 1.2 I2C ST33 Driver");
MODULE_VERSION("1.3.0");
MODULE_LICENSE("GPL");
This diff is collapsed.
/*
* STMicroelectronics TPM Linux driver for TPM ST33ZP24
* Copyright (C) 2009 - 2015 STMicroelectronics
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __LOCAL_ST33ZP24_H__
#define __LOCAL_ST33ZP24_H__
#define TPM_WRITE_DIRECTION 0x80
#define TPM_BUFSIZE 2048
struct st33zp24_phy_ops {
int (*send)(void *phy_id, u8 tpm_register, u8 *tpm_data, int tpm_size);
int (*recv)(void *phy_id, u8 tpm_register, u8 *tpm_data, int tpm_size);
};
#ifdef CONFIG_PM_SLEEP
int st33zp24_pm_suspend(struct device *dev);
int st33zp24_pm_resume(struct device *dev);
#endif
int st33zp24_probe(void *phy_id, const struct st33zp24_phy_ops *ops,
struct device *dev, int irq, int io_lpcpd);
int st33zp24_remove(struct tpm_chip *chip);
#endif /* __LOCAL_ST33ZP24_H__ */
......@@ -170,6 +170,41 @@ static void tpm_dev_del_device(struct tpm_chip *chip)
device_unregister(&chip->dev);
}
static int tpm1_chip_register(struct tpm_chip *chip)
{
int rc;
if (chip->flags & TPM_CHIP_FLAG_TPM2)
return 0;
rc = tpm_sysfs_add_device(chip);
if (rc)
return rc;
rc = tpm_add_ppi(chip);
if (rc) {
tpm_sysfs_del_device(chip);
return rc;
}
chip->bios_dir = tpm_bios_log_setup(chip->devname);
return 0;
}
static void tpm1_chip_unregister(struct tpm_chip *chip)
{
if (chip->flags & TPM_CHIP_FLAG_TPM2)
return;
if (chip->bios_dir)
tpm_bios_log_teardown(chip->bios_dir);
tpm_remove_ppi(chip);
tpm_sysfs_del_device(chip);
}
/*
* tpm_chip_register() - create a character device for the TPM chip
* @chip: TPM chip to use.
......@@ -185,22 +220,13 @@ int tpm_chip_register(struct tpm_chip *chip)
{
int rc;
/* Populate sysfs for TPM1 devices. */
if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
rc = tpm_sysfs_add_device(chip);
if (rc)
goto del_misc;
rc = tpm_add_ppi(chip);
if (rc)
goto del_sysfs;
chip->bios_dir = tpm_bios_log_setup(chip->devname);
}
rc = tpm1_chip_register(chip);
if (rc)
return rc;
rc = tpm_dev_add_device(chip);
if (rc)
return rc;
goto out_err;
/* Make the chip available. */
spin_lock(&driver_lock);
......@@ -210,10 +236,8 @@ int tpm_chip_register(struct tpm_chip *chip)
chip->flags |= TPM_CHIP_FLAG_REGISTERED;
return 0;
del_sysfs:
tpm_sysfs_del_device(chip);
del_misc:
tpm_dev_del_device(chip);
out_err:
tpm1_chip_unregister(chip);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_chip_register);
......@@ -238,13 +262,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
spin_unlock(&driver_lock);
synchronize_rcu();
if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
if (chip->bios_dir)
tpm_bios_log_teardown(chip->bios_dir);
tpm_remove_ppi(chip);
tpm_sysfs_del_device(chip);
}
tpm1_chip_unregister(chip);
tpm_dev_del_device(chip);
}
EXPORT_SYMBOL_GPL(tpm_chip_unregister);
......@@ -591,27 +591,8 @@ static void tpm_inf_pnp_remove(struct pnp_dev *dev)
}
}
static int tpm_inf_pnp_suspend(struct pnp_dev *dev, pm_message_t pm_state)
{
struct tpm_chip *chip = pnp_get_drvdata(dev);
int rc;
if (chip) {
u8 savestate[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 10, /* blob length (in bytes) */
0, 0, 0, 152 /* TPM_ORD_SaveState */
};
dev_info(&dev->dev, "saving TPM state\n");
rc = tpm_inf_send(chip, savestate, sizeof(savestate));
if (rc < 0) {
dev_err(&dev->dev, "error while saving TPM state\n");
return rc;
}
}
return 0;
}
static int tpm_inf_pnp_resume(struct pnp_dev *dev)
#ifdef CONFIG_PM_SLEEP
static int tpm_inf_resume(struct device *dev)
{
/* Re-configure TPM after suspending */
tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
......@@ -625,16 +606,19 @@ static int tpm_inf_pnp_resume(struct pnp_dev *dev)
tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
/* disable RESET, LP and IRQC */
tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
return tpm_pm_resume(&dev->dev);
return tpm_pm_resume(dev);
}
#endif
static SIMPLE_DEV_PM_OPS(tpm_inf_pm, tpm_pm_suspend, tpm_inf_resume);
static struct pnp_driver tpm_inf_pnp_driver = {
.name = "tpm_inf_pnp",
.id_table = tpm_inf_pnp_tbl,
.probe = tpm_inf_pnp_probe,
.suspend = tpm_inf_pnp_suspend,
.resume = tpm_inf_pnp_resume,
.remove = tpm_inf_pnp_remove
.remove = tpm_inf_pnp_remove,
.driver = {
.pm = &tpm_inf_pm,
}
};
module_pnp_driver(tpm_inf_pnp_driver);
......
/*
* STMicroelectronics TPM I2C Linux driver for TPM ST33ZP24
* Copyright (C) 2009, 2010 STMicroelectronics
* STMicroelectronics TPM Linux driver for TPM 1.2 ST33ZP24
* Copyright (C) 2009 - 2015 STMicroelectronics
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -14,20 +14,9 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* STMicroelectronics version 1.2.0, Copyright (C) 2010
* STMicroelectronics comes with ABSOLUTELY NO WARRANTY.
* This is free software, and you are welcome to redistribute it
* under certain conditions.
*
* @Author: Christophe RICARD tpmsupport@st.com
*
* @File: stm_st33_tpm.h
*
* @Date: 09/15/2010
*/
#ifndef __STM_ST33_TPM_H__
#define __STM_ST33_TPM_H__
#ifndef __ST33ZP24_H__
#define __ST33ZP24_H__
#define TPM_ST33_I2C "st33zp24-i2c"
#define TPM_ST33_SPI "st33zp24-spi"
......@@ -36,4 +25,4 @@ struct st33zp24_platform_data {
int io_lpcpd;
};
#endif /* __STM_ST33_TPM_H__ */
#endif /* __ST33ZP24_H__ */
......@@ -211,7 +211,7 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
static void dump_common_audit_data(struct audit_buffer *ab,
struct common_audit_data *a)
{
struct task_struct *tsk = current;
char comm[sizeof(current->comm)];
/*
* To keep stack sizes in check force programers to notice if they
......@@ -220,8 +220,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
*/
BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
audit_log_format(ab, " pid=%d comm=", task_pid_nr(tsk));
audit_log_untrustedstring(ab, tsk->comm);
audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm)));
switch (a->type) {
case LSM_AUDIT_DATA_NONE:
......@@ -276,16 +276,19 @@ static void dump_common_audit_data(struct audit_buffer *ab,
audit_log_format(ab, " ino=%lu", inode->i_ino);
break;
}
case LSM_AUDIT_DATA_TASK:
tsk = a->u.tsk;
case LSM_AUDIT_DATA_TASK: {
struct task_struct *tsk = a->u.tsk;
if (tsk) {
pid_t pid = task_pid_nr(tsk);
if (pid) {
char comm[sizeof(tsk->comm)];
audit_log_format(ab, " pid=%d comm=", pid);
audit_log_untrustedstring(ab, tsk->comm);
audit_log_untrustedstring(ab,
memcpy(comm, tsk->comm, sizeof(comm)));
}
}
break;
}
case LSM_AUDIT_DATA_NET:
if (a->u.net->sk) {
struct sock *sk = a->u.net->sk;
......
......@@ -724,12 +724,10 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
rcu_read_lock();
node = avc_lookup(ssid, tsid, tclass);
if (unlikely(!node)) {
if (unlikely(!node))
node = avc_compute_av(ssid, tsid, tclass, avd);
} else {
else
memcpy(avd, &node->ae.avd, sizeof(*avd));
avd = &node->ae.avd;
}
denied = requested & ~(avd->allowed);
if (unlikely(denied))
......
......@@ -25,10 +25,43 @@
static struct kmem_cache *avtab_node_cachep;
static inline int avtab_hash(struct avtab_key *keyp, u16 mask)
/* Based on MurmurHash3, written by Austin Appleby and placed in the
* public domain.
*/
static inline int avtab_hash(struct avtab_key *keyp, u32 mask)
{
return ((keyp->target_class + (keyp->target_type << 2) +
(keyp->source_type << 9)) & mask);
static const u32 c1 = 0xcc9e2d51;
static const u32 c2 = 0x1b873593;
static const u32 r1 = 15;
static const u32 r2 = 13;
static const u32 m = 5;
static const u32 n = 0xe6546b64;
u32 hash = 0;
#define mix(input) { \
u32 v = input; \
v *= c1; \
v = (v << r1) | (v >> (32 - r1)); \
v *= c2; \
hash ^= v; \
hash = (hash << r2) | (hash >> (32 - r2)); \
hash = hash * m + n; \
}
mix(keyp->target_class);
mix(keyp->target_type);
mix(keyp->source_type);
#undef mix
hash ^= hash >> 16;
hash *= 0x85ebca6b;
hash ^= hash >> 13;
hash *= 0xc2b2ae35;
hash ^= hash >> 16;
return hash & mask;
}
static struct avtab_node*
......@@ -46,8 +79,12 @@ avtab_insert_node(struct avtab *h, int hvalue,
newnode->next = prev->next;
prev->next = newnode;
} else {
newnode->next = h->htable[hvalue];
h->htable[hvalue] = newnode;
newnode->next = flex_array_get_ptr(h->htable, hvalue);
if (flex_array_put_ptr(h->htable, hvalue, newnode,
GFP_KERNEL|__GFP_ZERO)) {
kmem_cache_free(avtab_node_cachep, newnode);
return NULL;
}
}
h->nel++;
......@@ -64,7 +101,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
return -EINVAL;
hvalue = avtab_hash(key, h->mask);
for (prev = NULL, cur = h->htable[hvalue];
for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue);
cur;
prev = cur, cur = cur->next) {
if (key->source_type == cur->key.source_type &&
......@@ -104,7 +141,7 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu
if (!h || !h->htable)
return NULL;
hvalue = avtab_hash(key, h->mask);
for (prev = NULL, cur = h->htable[hvalue];
for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue);
cur;
prev = cur, cur = cur->next) {
if (key->source_type == cur->key.source_type &&
......@@ -135,7 +172,8 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
return NULL;
hvalue = avtab_hash(key, h->mask);
for (cur = h->htable[hvalue]; cur; cur = cur->next) {
for (cur = flex_array_get_ptr(h->htable, hvalue); cur;
cur = cur->next) {
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
key->target_class == cur->key.target_class &&
......@@ -170,7 +208,8 @@ avtab_search_node(struct avtab *h, struct avtab_key *key)
return NULL;
hvalue = avtab_hash(key, h->mask);
for (cur = h->htable[hvalue]; cur; cur = cur->next) {
for (cur = flex_array_get_ptr(h->htable, hvalue); cur;
cur = cur->next) {
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
key->target_class == cur->key.target_class &&
......@@ -228,15 +267,14 @@ void avtab_destroy(struct avtab *h)
return;
for (i = 0; i < h->nslot; i++) {
cur = h->htable[i];
cur = flex_array_get_ptr(h->htable, i);
while (cur) {
temp = cur;
cur = cur->next;
kmem_cache_free(avtab_node_cachep, temp);
}
h->htable[i] = NULL;
}
kfree(h->htable);
flex_array_free(h->htable);
h->htable = NULL;
h->nslot = 0;
h->mask = 0;
......@@ -251,7 +289,7 @@ int avtab_init(struct avtab *h)
int avtab_alloc(struct avtab *h, u32 nrules)
{
u16 mask = 0;
u32 mask = 0;
u32 shift = 0;
u32 work = nrules;
u32 nslot = 0;
......@@ -270,7 +308,8 @@ int avtab_alloc(struct avtab *h, u32 nrules)
nslot = MAX_AVTAB_HASH_BUCKETS;
mask = nslot - 1;
h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL);
h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot,
GFP_KERNEL | __GFP_ZERO);
if (!h->htable)
return -ENOMEM;
......@@ -293,7 +332,7 @@ void avtab_hash_eval(struct avtab *h, char *tag)
max_chain_len = 0;
chain2_len_sum = 0;
for (i = 0; i < h->nslot; i++) {
cur = h->htable[i];
cur = flex_array_get_ptr(h->htable, i);
if (cur) {
slots_used++;
chain_len = 0;
......@@ -534,7 +573,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)
return rc;
for (i = 0; i < a->nslot; i++) {
for (cur = a->htable[i]; cur; cur = cur->next) {
for (cur = flex_array_get_ptr(a->htable, i); cur;
cur = cur->next) {
rc = avtab_write_item(p, cur, fp);
if (rc)
return rc;
......
......@@ -23,6 +23,8 @@
#ifndef _SS_AVTAB_H_
#define _SS_AVTAB_H_
#include <linux/flex_array.h>
struct avtab_key {
u16 source_type; /* source type */
u16 target_type; /* target type */
......@@ -51,10 +53,10 @@ struct avtab_node {
};
struct avtab {
struct avtab_node **htable;
struct flex_array *htable;
u32 nel; /* number of elements */
u32 nslot; /* number of hash slots */
u16 mask; /* mask to compute hash func */
u32 mask; /* mask to compute hash func */
};
......@@ -84,7 +86,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
void avtab_cache_init(void);
void avtab_cache_destroy(void);
#define MAX_AVTAB_HASH_BITS 11
#define MAX_AVTAB_HASH_BITS 16
#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
#endif /* _SS_AVTAB_H_ */
......
......@@ -654,19 +654,15 @@ int mls_import_netlbl_cat(struct context *context,
rc = ebitmap_netlbl_import(&context->range.level[0].cat,
secattr->attr.mls.cat);
if (rc != 0)
goto import_netlbl_cat_failure;
rc = ebitmap_cpy(&context->range.level[1].cat,
&context->range.level[0].cat);
if (rc != 0)
if (rc)
goto import_netlbl_cat_failure;
memcpy(&context->range.level[1].cat, &context->range.level[0].cat,
sizeof(context->range.level[0].cat));
return 0;
import_netlbl_cat_failure:
ebitmap_destroy(&context->range.level[0].cat);
ebitmap_destroy(&context->range.level[1].cat);
return rc;
}
#endif /* CONFIG_NETLABEL */
......@@ -3179,13 +3179,9 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
ctx_new.type = ctx->type;
mls_import_netlbl_lvl(&ctx_new, secattr);
if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat,
secattr->attr.mls.cat);
rc = mls_import_netlbl_cat(&ctx_new, secattr);
if (rc)
goto out;
memcpy(&ctx_new.range.level[1].cat,
&ctx_new.range.level[0].cat,
sizeof(ctx_new.range.level[0].cat));
}
rc = -EIDRM;
if (!mls_context_isvalid(&policydb, &ctx_new))
......
......@@ -105,6 +105,7 @@ struct task_smack {
#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */
#define SMK_INODE_CHANGED 0x04 /* smack was transmuted */
#define SMK_INODE_IMPURE 0x08 /* involved in an impure transaction */
/*
* A label access rule.
......@@ -193,6 +194,10 @@ struct smk_port_label {
#define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */
#define MAY_BRINGUP 0x00004000 /* Report use of this rule */
#define SMACK_BRINGUP_ALLOW 1 /* Allow bringup mode */
#define SMACK_UNCONFINED_SUBJECT 2 /* Allow unconfined label */
#define SMACK_UNCONFINED_OBJECT 3 /* Allow unconfined label */
/*
* Just to make the common cases easier to deal with
*/
......@@ -254,6 +259,9 @@ extern int smack_cipso_mapped;
extern struct smack_known *smack_net_ambient;
extern struct smack_known *smack_onlycap;
extern struct smack_known *smack_syslog_label;
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
extern struct smack_known *smack_unconfined;
#endif
extern struct smack_known smack_cipso_option;
extern int smack_ptrace_rule;
......
......@@ -130,7 +130,8 @@ int smk_access(struct smack_known *subject, struct smack_known *object,
/*
* Hardcoded comparisons.
*
*/
/*
* A star subject can't access any object.
*/
if (subject == &smack_known_star) {
......@@ -189,10 +190,20 @@ int smk_access(struct smack_known *subject, struct smack_known *object,
* succeed because of "b" rules.
*/
if (may & MAY_BRINGUP)
rc = MAY_BRINGUP;
rc = SMACK_BRINGUP_ALLOW;
#endif
out_audit:
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
if (rc < 0) {
if (object == smack_unconfined)
rc = SMACK_UNCONFINED_OBJECT;
if (subject == smack_unconfined)
rc = SMACK_UNCONFINED_SUBJECT;
}
#endif
#ifdef CONFIG_AUDIT
if (a)
smack_log(subject->smk_known, object->smk_known,
......@@ -338,19 +349,16 @@ static void smack_log_callback(struct audit_buffer *ab, void *a)
void smack_log(char *subject_label, char *object_label, int request,
int result, struct smk_audit_info *ad)
{
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
char request_buffer[SMK_NUM_ACCESS_TYPE + 5];
#else
char request_buffer[SMK_NUM_ACCESS_TYPE + 1];
#endif
struct smack_audit_data *sad;
struct common_audit_data *a = &ad->a;
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
/*
* The result may be positive in bringup mode.
*/
if (result > 0)
result = 0;
#endif
/* check if we have to log the current event */
if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
if (result < 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
return;
if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
return;
......@@ -364,6 +372,21 @@ void smack_log(char *subject_label, char *object_label, int request,
smack_str_from_perm(request_buffer, request);
sad->subject = subject_label;
sad->object = object_label;
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
/*
* The result may be positive in bringup mode.
* A positive result is an allow, but not for normal reasons.
* Mark it as successful, but don't filter it out even if
* the logging policy says to do so.
*/
if (result == SMACK_UNCONFINED_SUBJECT)
strcat(request_buffer, "(US)");
else if (result == SMACK_UNCONFINED_OBJECT)
strcat(request_buffer, "(UO)");
if (result > 0)
result = 0;
#endif
sad->request = request_buffer;
sad->result = result;
......
......@@ -57,6 +57,13 @@ static struct kmem_cache *smack_inode_cache;
int smack_enabled;
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static char *smk_bu_mess[] = {
"Bringup Error", /* Unused */
"Bringup", /* SMACK_BRINGUP_ALLOW */
"Unconfined Subject", /* SMACK_UNCONFINED_SUBJECT */
"Unconfined Object", /* SMACK_UNCONFINED_OBJECT */
};
static void smk_bu_mode(int mode, char *s)
{
int i = 0;
......@@ -87,9 +94,11 @@ static int smk_bu_note(char *note, struct smack_known *sskp,
if (rc <= 0)
return rc;
if (rc > SMACK_UNCONFINED_OBJECT)
rc = 0;
smk_bu_mode(mode, acc);
pr_info("Smack Bringup: (%s %s %s) %s\n",
pr_info("Smack %s: (%s %s %s) %s\n", smk_bu_mess[rc],
sskp->smk_known, oskp->smk_known, acc, note);
return 0;
}
......@@ -106,9 +115,11 @@ static int smk_bu_current(char *note, struct smack_known *oskp,
if (rc <= 0)
return rc;
if (rc > SMACK_UNCONFINED_OBJECT)
rc = 0;
smk_bu_mode(mode, acc);
pr_info("Smack Bringup: (%s %s %s) %s %s\n",
pr_info("Smack %s: (%s %s %s) %s %s\n", smk_bu_mess[rc],
tsp->smk_task->smk_known, oskp->smk_known,
acc, current->comm, note);
return 0;
......@@ -126,9 +137,11 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc)
if (rc <= 0)
return rc;
if (rc > SMACK_UNCONFINED_OBJECT)
rc = 0;
smk_bu_mode(mode, acc);
pr_info("Smack Bringup: (%s %s %s) %s to %s\n",
pr_info("Smack %s: (%s %s %s) %s to %s\n", smk_bu_mess[rc],
tsp->smk_task->smk_known, smk_task->smk_known, acc,
current->comm, otp->comm);
return 0;
......@@ -141,14 +154,25 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc)
static int smk_bu_inode(struct inode *inode, int mode, int rc)
{
struct task_smack *tsp = current_security();
struct inode_smack *isp = inode->i_security;
char acc[SMK_NUM_ACCESS_TYPE + 1];
if (isp->smk_flags & SMK_INODE_IMPURE)
pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
inode->i_sb->s_id, inode->i_ino, current->comm);
if (rc <= 0)
return rc;
if (rc > SMACK_UNCONFINED_OBJECT)
rc = 0;
if (rc == SMACK_UNCONFINED_SUBJECT &&
(mode & (MAY_WRITE | MAY_APPEND)))
isp->smk_flags |= SMK_INODE_IMPURE;
smk_bu_mode(mode, acc);
pr_info("Smack Bringup: (%s %s %s) inode=(%s %ld) %s\n",
tsp->smk_task->smk_known, smk_of_inode(inode)->smk_known, acc,
pr_info("Smack %s: (%s %s %s) inode=(%s %ld) %s\n", smk_bu_mess[rc],
tsp->smk_task->smk_known, isp->smk_inode->smk_known, acc,
inode->i_sb->s_id, inode->i_ino, current->comm);
return 0;
}
......@@ -162,13 +186,20 @@ static int smk_bu_file(struct file *file, int mode, int rc)
struct task_smack *tsp = current_security();
struct smack_known *sskp = tsp->smk_task;
struct inode *inode = file_inode(file);
struct inode_smack *isp = inode->i_security;
char acc[SMK_NUM_ACCESS_TYPE + 1];
if (isp->smk_flags & SMK_INODE_IMPURE)
pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
inode->i_sb->s_id, inode->i_ino, current->comm);
if (rc <= 0)
return rc;
if (rc > SMACK_UNCONFINED_OBJECT)
rc = 0;
smk_bu_mode(mode, acc);
pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n",
pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
inode->i_sb->s_id, inode->i_ino, file,
current->comm);
......@@ -185,13 +216,20 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file,
struct task_smack *tsp = cred->security;
struct smack_known *sskp = tsp->smk_task;
struct inode *inode = file->f_inode;
struct inode_smack *isp = inode->i_security;
char acc[SMK_NUM_ACCESS_TYPE + 1];
if (isp->smk_flags & SMK_INODE_IMPURE)
pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
inode->i_sb->s_id, inode->i_ino, current->comm);
if (rc <= 0)
return rc;
if (rc > SMACK_UNCONFINED_OBJECT)
rc = 0;
smk_bu_mode(mode, acc);
pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n",
pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
inode->i_sb->s_id, inode->i_ino, file,
current->comm);
......@@ -2449,7 +2487,21 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
static int smack_socket_post_create(struct socket *sock, int family,
int type, int protocol, int kern)
{
if (family != PF_INET || sock->sk == NULL)
struct socket_smack *ssp;
if (sock->sk == NULL)
return 0;
/*
* Sockets created by kernel threads receive web label.
*/
if (unlikely(current->flags & PF_KTHREAD)) {
ssp = sock->sk->sk_security;
ssp->smk_in = &smack_known_web;
ssp->smk_out = &smack_known_web;
}
if (family != PF_INET)
return 0;
/*
* Set the outbound netlbl.
......@@ -3983,6 +4035,36 @@ static int smack_key_permission(key_ref_t key_ref,
rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
return rc;
}
/*
* smack_key_getsecurity - Smack label tagging the key
* @key points to the key to be queried
* @_buffer points to a pointer that should be set to point to the
* resulting string (if no label or an error occurs).
* Return the length of the string (including terminating NUL) or -ve if
* an error.
* May also return 0 (and a NULL buffer pointer) if there is no label.
*/
static int smack_key_getsecurity(struct key *key, char **_buffer)
{
struct smack_known *skp = key->security;
size_t length;
char *copy;
if (key->security == NULL) {
*_buffer = NULL;
return 0;
}
copy = kstrdup(skp->smk_known, GFP_KERNEL);
if (copy == NULL)
return -ENOMEM;
length = strlen(copy) + 1;
*_buffer = copy;
return length;
}
#endif /* CONFIG_KEYS */
/*
......@@ -4307,6 +4389,7 @@ struct security_operations smack_ops = {
.key_alloc = smack_key_alloc,
.key_free = smack_key_free,
.key_permission = smack_key_permission,
.key_getsecurity = smack_key_getsecurity,
#endif /* CONFIG_KEYS */
/* Audit hooks */
......
......@@ -54,6 +54,9 @@ enum smk_inos {
SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
SMK_SYSLOG = 20, /* change syslog label) */
SMK_PTRACE = 21, /* set ptrace rule */
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
SMK_UNCONFINED = 22, /* define an unconfined label */
#endif
};
/*
......@@ -61,7 +64,6 @@ enum smk_inos {
*/
static DEFINE_MUTEX(smack_cipso_lock);
static DEFINE_MUTEX(smack_ambient_lock);
static DEFINE_MUTEX(smack_syslog_lock);
static DEFINE_MUTEX(smk_netlbladdr_lock);
/*
......@@ -95,6 +97,16 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
*/
struct smack_known *smack_onlycap;
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
/*
* Allow one label to be unconfined. This is for
* debugging and application bring-up purposes only.
* It is bad and wrong, but everyone seems to expect
* to have it.
*/
struct smack_known *smack_unconfined;
#endif
/*
* If this value is set restrict syslog use to the label specified.
* It can be reset via smackfs/syslog
......@@ -1717,6 +1729,85 @@ static const struct file_operations smk_onlycap_ops = {
.llseek = default_llseek,
};
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
/**
* smk_read_unconfined - read() for smackfs/unconfined
* @filp: file pointer, not actually used
* @buf: where to put the result
* @cn: maximum to send along
* @ppos: where to start
*
* Returns number of bytes read or error code, as appropriate
*/
static ssize_t smk_read_unconfined(struct file *filp, char __user *buf,
size_t cn, loff_t *ppos)
{
char *smack = "";
ssize_t rc = -EINVAL;
int asize;
if (*ppos != 0)
return 0;
if (smack_unconfined != NULL)
smack = smack_unconfined->smk_known;
asize = strlen(smack) + 1;
if (cn >= asize)
rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
return rc;
}
/**
* smk_write_unconfined - write() for smackfs/unconfined
* @file: file pointer, not actually used
* @buf: where to get the data from
* @count: bytes sent
* @ppos: where to start
*
* Returns number of bytes written or error code, as appropriate
*/
static ssize_t smk_write_unconfined(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
char *data;
int rc = count;
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
data = kzalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
/*
* Should the null string be passed in unset the unconfined value.
* This seems like something to be careful with as usually
* smk_import only expects to return NULL for errors. It
* is usually the case that a nullstring or "\n" would be
* bad to pass to smk_import but in fact this is useful here.
*
* smk_import will also reject a label beginning with '-',
* so "-confine" will also work.
*/
if (copy_from_user(data, buf, count) != 0)
rc = -EFAULT;
else
smack_unconfined = smk_import_entry(data, count);
kfree(data);
return rc;
}
static const struct file_operations smk_unconfined_ops = {
.read = smk_read_unconfined,
.write = smk_write_unconfined,
.llseek = default_llseek,
};
#endif /* CONFIG_SECURITY_SMACK_BRINGUP */
/**
* smk_read_logging - read() for /smack/logging
* @filp: file pointer, not actually used
......@@ -2384,6 +2475,10 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
"syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
[SMK_PTRACE] = {
"ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR},
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
[SMK_UNCONFINED] = {
"unconfined", &smk_unconfined_ops, S_IRUGO|S_IWUSR},
#endif
/* last one */
{""}
};
......
builtin-policy.h
policy/
policy/*.conf
......@@ -6,6 +6,7 @@ config SECURITY_TOMOYO
select SECURITY_PATH
select SECURITY_NETWORK
select SRCU
select BUILD_BIN2C
default n
help
This selects TOMOYO Linux, pathname-based access control.
......
obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o
$(obj)/policy/profile.conf:
@mkdir -p $(obj)/policy/
@echo Creating an empty policy/profile.conf
@touch $@
$(obj)/policy/exception_policy.conf:
@mkdir -p $(obj)/policy/
@echo Creating a default policy/exception_policy.conf
@echo initialize_domain /sbin/modprobe from any >> $@
@echo initialize_domain /sbin/hotplug from any >> $@
$(obj)/policy/domain_policy.conf:
@mkdir -p $(obj)/policy/
@echo Creating an empty policy/domain_policy.conf
@touch $@
$(obj)/policy/manager.conf:
@mkdir -p $(obj)/policy/
@echo Creating an empty policy/manager.conf
@touch $@
$(obj)/policy/stat.conf:
@mkdir -p $(obj)/policy/
@echo Creating an empty policy/stat.conf
@touch $@
$(obj)/builtin-policy.h: $(obj)/policy/profile.conf $(obj)/policy/exception_policy.conf $(obj)/policy/domain_policy.conf $(obj)/policy/manager.conf $(obj)/policy/stat.conf
@echo Generating built-in policy for TOMOYO 2.5.x.
@echo "static char tomoyo_builtin_profile[] __initdata =" > $@.tmp
@sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/profile.conf >> $@.tmp
@echo "\"\";" >> $@.tmp
@echo "static char tomoyo_builtin_exception_policy[] __initdata =" >> $@.tmp
@sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/exception_policy.conf >> $@.tmp
@echo "\"\";" >> $@.tmp
@echo "static char tomoyo_builtin_domain_policy[] __initdata =" >> $@.tmp
@sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/domain_policy.conf >> $@.tmp
@echo "\"\";" >> $@.tmp
@echo "static char tomoyo_builtin_manager[] __initdata =" >> $@.tmp
@sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/manager.conf >> $@.tmp
@echo "\"\";" >> $@.tmp
@echo "static char tomoyo_builtin_stat[] __initdata =" >> $@.tmp
@sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/stat.conf >> $@.tmp
@echo "\"\";" >> $@.tmp
@mv $@.tmp $@
targets += builtin-policy.h
define do_policy
echo "static char tomoyo_builtin_$(1)[] __initdata ="; \
$(objtree)/scripts/basic/bin2c <$(firstword $(wildcard $(obj)/policy/$(1).conf $(srctree)/$(src)/policy/$(1).conf.default) /dev/null); \
echo ";"
endef
quiet_cmd_policy = POLICY $@
cmd_policy = ($(call do_policy,profile); $(call do_policy,exception_policy); $(call do_policy,domain_policy); $(call do_policy,manager); $(call do_policy,stat)) >$@
$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(src)/policy/*.conf.default) FORCE
$(call if_changed,policy)
$(obj)/common.o: $(obj)/builtin-policy.h
initialize_domain /sbin/modprobe from any
initialize_domain /sbin/hotplug from any
config SECURITY_YAMA
bool "Yama support"
depends on SECURITY
select SECURITYFS
select SECURITY_PATH
default n
help
This selects Yama, which extends DAC support with additional
......
......@@ -379,20 +379,17 @@ static struct security_operations yama_ops = {
static int yama_dointvec_minmax(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int rc;
struct ctl_table table_copy;
if (write && !capable(CAP_SYS_PTRACE))
return -EPERM;
rc = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
if (rc)
return rc;
/* Lock the max value if it ever gets set. */
if (write && *(int *)table->data == *(int *)table->extra2)
table->extra1 = table->extra2;
table_copy = *table;
if (*(int *)table_copy.data == *(int *)table_copy.extra2)
table_copy.extra1 = table_copy.extra2;
return rc;
return proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos);
}
static int zero;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment