patch-2.4.25 linux-2.4.25/arch/ppc64/kernel/rtas-proc.c
Next file: linux-2.4.25/arch/ppc64/kernel/rtas.c
Previous file: linux-2.4.25/arch/ppc64/kernel/ras.c
Back to the patch index
Back to the overall index
- Lines: 678
- Date:
2004-02-18 05:36:30.000000000 -0800
- Orig file:
linux-2.4.24/arch/ppc64/kernel/rtas-proc.c
- Orig date:
2003-08-25 04:44:40.000000000 -0700
diff -urN linux-2.4.24/arch/ppc64/kernel/rtas-proc.c linux-2.4.25/arch/ppc64/kernel/rtas-proc.c
@@ -124,6 +124,11 @@
static unsigned long rtas_tone_volume = 0;
static unsigned int open_token = 0;
+static int set_time_for_power_on = RTAS_UNKNOWN_SERVICE;
+static int set_time_of_day = RTAS_UNKNOWN_SERVICE;
+static int get_sensor_state = RTAS_UNKNOWN_SERVICE;
+static int set_indicator = RTAS_UNKNOWN_SERVICE;
+
extern struct proc_dir_entry *proc_ppc64_root;
extern struct proc_dir_entry *rtas_proc_dir;
extern spinlock_t proc_ppc64_lock;
@@ -215,6 +220,8 @@
void proc_rtas_init(void)
{
struct proc_dir_entry *entry;
+ int display_character;
+ int errinjct_token;
rtas_node = find_devices("rtas");
if ((rtas_node == NULL) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) {
@@ -240,29 +247,51 @@
return;
}
- /* /proc/rtas entries */
+ /*
+ * /proc/rtas entries
+ * only create entries if rtas token exists for desired function
+ */
+
+ set_time_of_day = rtas_token("set-time-of-day");
+ if (set_time_of_day != RTAS_UNKNOWN_SERVICE) {
+ entry=create_proc_entry("clock",S_IRUGO|S_IWUSR,rtas_proc_dir);
+ if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
+ }
- entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, rtas_proc_dir);
- if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
+ set_time_for_power_on = rtas_token("set-time-for-power-on");
+ if (set_time_for_power_on != RTAS_UNKNOWN_SERVICE) {
+ entry=create_proc_entry("poweron",S_IWUSR|S_IRUGO,rtas_proc_dir);
+ if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
+ }
- entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, rtas_proc_dir);
- if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
+ get_sensor_state = rtas_token("get-sensor-state");
+ if (get_sensor_state != RTAS_UNKNOWN_SERVICE) {
+ create_proc_read_entry("sensors", S_IRUGO, rtas_proc_dir,
+ ppc_rtas_sensor_read, NULL);
+ }
- entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, rtas_proc_dir);
- if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
+ set_indicator = rtas_token("set-indicator");
+ if (set_indicator != RTAS_UNKNOWN_SERVICE) {
+ entry=create_proc_entry("frequency",S_IWUSR|S_IRUGO,rtas_proc_dir);
+ if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations;
- create_proc_read_entry("sensors", S_IRUGO, rtas_proc_dir,
- ppc_rtas_sensor_read, NULL);
-
- entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, rtas_proc_dir);
- if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations;
+ entry=create_proc_entry("volume",S_IWUSR|S_IRUGO,rtas_proc_dir);
+ if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations;
+ }
- entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, rtas_proc_dir);
- if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations;
+ display_character = rtas_token("display-character");
+ if ((display_character != RTAS_UNKNOWN_SERVICE) ||
+ (set_indicator != RTAS_UNKNOWN_SERVICE)) {
+ entry=create_proc_entry("progress",S_IRUGO|S_IWUSR,rtas_proc_dir);
+ if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
+ }
#ifdef CONFIG_RTAS_ERRINJCT
- entry = create_proc_entry("errinjct", S_IWUSR|S_IRUGO, rtas_proc_dir);
- if (entry) entry->proc_fops = &ppc_rtas_errinjct_operations;
+ errinjct_token = rtas_token("ibm,errinjct");
+ if (errinjct_token != RTAS_UNKNOWN_SERVICE) {
+ entry=create_proc_entry("errinjct",S_IWUSR|S_IRUGO,rtas_proc_dir);
+ if (entry) entry->proc_fops = &ppc_rtas_errinjct_operations;
+ }
#endif
}
@@ -273,12 +302,19 @@
static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
+ char stkbuf[40]; /* its small, its on stack */
struct rtc_time tm;
unsigned long nowtime;
char *dest;
int error;
- nowtime = simple_strtoul(buf, &dest, 10);
+ if (39 < count)
+ count = 39;
+ if (copy_from_user(stkbuf, buf, count))
+ return -EFAULT;
+
+ stkbuf[count] = 0;
+ nowtime = simple_strtoul(stkbuf, &dest, 10);
if (*dest != '\0' && *dest != '\n') {
printk("ppc_rtas_poweron_write: Invalid time\n");
return count;
@@ -287,11 +323,11 @@
to_tm(nowtime, &tm);
- error = rtas_call(rtas_token("set-time-for-power-on"), 7, 1, NULL,
- tm.tm_year, tm.tm_mon, tm.tm_mday,
+ error = rtas_call(set_time_for_power_on, 7, 1, NULL,
+ tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
if (error != 0)
- printk(KERN_WARNING "error: setting poweron time returned: %s\n",
+ printk(KERN_WARNING "error: setting poweron time returned: %s\n",
ppc_rtas_process_error(error));
return count;
}
@@ -299,18 +335,23 @@
static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
+ char stkbuf[40]; /* its small, its on stack */
int n;
+
if (power_on_time == 0)
- n = sprintf(buf, "Power on time not set\n");
+ n = snprintf(stkbuf, 40, "Power on time not set\n");
else
- n = sprintf(buf, "%lu\n", power_on_time);
+ n = snprintf(stkbuf, 40, "%lu\n", power_on_time);
- if (*ppos >= strlen(buf))
+ int sn = strlen(stkbuf) +1;
+ if (*ppos >= sn)
return 0;
- if (n > strlen(buf) - *ppos)
- n = strlen(buf) - *ppos;
+ if (n > sn - *ppos)
+ n = sn - *ppos;
if (n > count)
n = count;
+ if (copy_to_user(buf, stkbuf + (*ppos), n))
+ return -EFAULT;
*ppos += n;
return n;
}
@@ -323,11 +364,17 @@
{
unsigned long hex;
- strcpy(progress_led, buf); /* save the string */
+ if (count >= MAX_LINELENGTH)
+ count = MAX_LINELENGTH -1;
+ if (copy_from_user(progress_led, buf, count))
+ return -EFAULT;
+
+ progress_led[count] = 0;
+
/* Lets see if the user passed hexdigits */
- hex = simple_strtoul(buf, NULL, 10);
-
- ppc_md.progress ((char *)buf, hex);
+ hex = simple_strtoul(progress_led, NULL, 10);
+
+ ppc_md.progress((char *)progress_led, hex);
return count;
/* clear the line */ /* ppc_md.progress(" ", 0xffff);*/
@@ -336,15 +383,32 @@
static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
- int n = 0;
- if (progress_led != NULL)
- n = sprintf (buf, "%s\n", progress_led);
- if (*ppos >= strlen(buf))
+ int n = 0, sn;
+
+ if (progress_led == NULL)
+ return 0;
+
+ char * tmpbuf = kmalloc(MAX_LINELENGTH, GFP_KERNEL);
+ if (!tmpbuf) {
+ printk(KERN_ERR "error: kmalloc failed\n");
+ return -ENOMEM;
+ }
+ n = sprintf (tmpbuf, "%s\n", progress_led);
+
+ sn = strlen (tmpbuf) +1;
+ if (*ppos >= sn) {
+ kfree(tmpbuf);
return 0;
- if (n > strlen(buf) - *ppos)
- n = strlen(buf) - *ppos;
+ }
+ if (n > sn - *ppos)
+ n = sn - *ppos;
if (n > count)
n = count;
+ if (copy_to_user(buf, tmpbuf + (*ppos), n)) {
+ kfree(tmpbuf);
+ return -EFAULT;
+ }
+ kfree(tmpbuf);
*ppos += n;
return n;
}
@@ -355,12 +419,19 @@
static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
+ char stkbuf[40]; /* its small, its on stack */
struct rtc_time tm;
unsigned long nowtime;
char *dest;
int error;
- nowtime = simple_strtoul(buf, &dest, 10);
+ if (39 < count)
+ count = 39;
+ if (copy_from_user(stkbuf, buf, count))
+ return -EFAULT;
+
+ stkbuf[count] = 0;
+ nowtime = simple_strtoul(stkbuf, &dest, 10);
if (*dest != '\0' && *dest != '\n') {
printk("ppc_rtas_clock_write: Invalid time\n");
return count;
@@ -388,21 +459,27 @@
year = ret[0]; mon = ret[1]; day = ret[2];
hour = ret[3]; min = ret[4]; sec = ret[5];
+ char stkbuf[40]; /* its small, its on stack */
+
if (error != 0){
printk(KERN_WARNING "error: reading the clock returned: %s\n",
ppc_rtas_process_error(error));
- n = sprintf (buf, "0");
+ n = snprintf(stkbuf, 40, "0");
} else {
- n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec));
+ n = snprintf(stkbuf, 40, "%lu\n", mktime(year, mon, day, hour, min, sec));
}
kfree(ret);
- if (*ppos >= strlen(buf))
+ int sn = strlen(stkbuf) +1;
+ if (*ppos >= sn)
return 0;
- if (n > strlen(buf) - *ppos)
- n = strlen(buf) - *ppos;
+ if (n > sn - *ppos)
+ n = sn - *ppos;
if (n > count)
n = count;
+ if (copy_to_user(buf, stkbuf + (*ppos), n))
+ return -EFAULT;
+
*ppos += n;
return n;
}
@@ -417,7 +494,6 @@
unsigned long ret;
int state, error;
char *buffer;
- int get_sensor_state = rtas_token("get-sensor-state");
if (count < 0)
return -EINVAL;
@@ -431,8 +507,8 @@
memset(buffer, 0, MAX_LINELENGTH*MAX_SENSORS);
n = sprintf ( buffer , "RTAS (RunTime Abstraction Services) Sensor Information\n");
- n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n");
- n += sprintf ( buffer+n, "********************************************************\n");
+ n += sprintf ( buffer+n, "%-17s\t%-15s\t%-15s\tLocation\n", "Sensor", "Value", "Condition");
+ n += sprintf ( buffer+n, "***************************************************************************\n");
if (ppc_rtas_find_all_sensors() != 0) {
n += sprintf ( buffer+n, "\nNo sensors are available\n");
@@ -538,10 +614,10 @@
int error, char * buf)
{
/* Defined return vales */
- const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t", "Mainenance" };
+ const char * key_switch[] = { "Off", "Normal", "Secure", "Maintenance" };
const char * enclosure_switch[] = { "Closed", "Open" };
const char * lid_status[] = { " ", "Open", "Closed" };
- const char * power_source[] = { "AC\t", "Battery", "AC & Battery" };
+ const char * power_source[] = { "AC", "Battery", "AC & Battery" };
const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };
const char * epow_sensor[] = {
"EPOW Reset", "Cooling warning", "Power warning",
@@ -552,101 +628,108 @@
const char * ibm_drconnector[] = { "Empty", "Present" };
const char * ibm_intqueue[] = { "Disabled", "Enabled" };
- int have_strings = 0;
int temperature = 0;
int unknown = 0;
int n = 0;
+ char *label_string = NULL;
+ const char **value_arr = NULL;
+ int value_arrsize = 0;
/* What kind of sensor do we have here? */
switch (s.token) {
case KEY_SWITCH:
- n += sprintf(buf+n, "Key switch:\t");
- n += sprintf(buf+n, "%s\t", key_switch[state]);
- have_strings = 1;
+ label_string = "Key switch:";
+ value_arrsize = sizeof(key_switch)/sizeof(char *);
+ value_arr = key_switch;
break;
case ENCLOSURE_SWITCH:
- n += sprintf(buf+n, "Enclosure switch:\t");
- n += sprintf(buf+n, "%s\t", enclosure_switch[state]);
- have_strings = 1;
+ label_string = "Enclosure switch:";
+ value_arrsize = sizeof(enclosure_switch)/sizeof(char *);
+ value_arr = enclosure_switch;
break;
case THERMAL_SENSOR:
- n += sprintf(buf+n, "Temp. (°C/°F):\t");
+ label_string = "Temp. (°C/°F):";
temperature = 1;
break;
case LID_STATUS:
- n += sprintf(buf+n, "Lid status:\t");
- n += sprintf(buf+n, "%s\t", lid_status[state]);
- have_strings = 1;
+ label_string = "Lid status:";
+ value_arrsize = sizeof(lid_status)/sizeof(char *);
+ value_arr = lid_status;
break;
case POWER_SOURCE:
- n += sprintf(buf+n, "Power source:\t");
- n += sprintf(buf+n, "%s\t", power_source[state]);
- have_strings = 1;
+ label_string = "Power source:";
+ value_arrsize = sizeof(power_source)/sizeof(char *);
+ value_arr = power_source;
break;
case BATTERY_VOLTAGE:
- n += sprintf(buf+n, "Battery voltage:\t");
+ label_string = "Battery voltage:";
break;
case BATTERY_REMAINING:
- n += sprintf(buf+n, "Battery remaining:\t");
- n += sprintf(buf+n, "%s\t", battery_remaining[state]);
- have_strings = 1;
+ label_string = "Battery remaining:";
+ value_arrsize = sizeof(battery_remaining)/sizeof(char *);
+ value_arr = battery_remaining;
break;
case BATTERY_PERCENTAGE:
- n += sprintf(buf+n, "Battery percentage:\t");
+ label_string = "Battery percentage:";
break;
case EPOW_SENSOR:
- n += sprintf(buf+n, "EPOW Sensor:\t");
- n += sprintf(buf+n, "%s\t", epow_sensor[state]);
- have_strings = 1;
+ label_string = "EPOW Sensor:";
+ value_arrsize = sizeof(epow_sensor)/sizeof(char *);
+ value_arr = epow_sensor;
break;
case BATTERY_CYCLESTATE:
- n += sprintf(buf+n, "Battery cyclestate:\t");
- n += sprintf(buf+n, "%s\t", battery_cyclestate[state]);
- have_strings = 1;
+ label_string = "Battery cyclestate:";
+ value_arrsize = sizeof(battery_cyclestate)/sizeof(char *);
+ value_arr = battery_cyclestate;
break;
case BATTERY_CHARGING:
- n += sprintf(buf+n, "Battery Charging:\t");
- n += sprintf(buf+n, "%s\t", battery_charging[state]);
- have_strings = 1;
+ label_string = "Battery Charging:";
+ value_arrsize = sizeof(battery_charging)/sizeof(char *);
+ value_arr = battery_charging;
break;
case IBM_SURVEILLANCE:
- n += sprintf(buf+n, "Surveillance:\t");
+ label_string = "Surveillance:";
break;
case IBM_FANRPM:
- n += sprintf(buf+n, "Fan (rpm):\t");
+ label_string = "Fan (rpm):";
break;
case IBM_VOLTAGE:
- n += sprintf(buf+n, "Voltage (mv):\t");
+ label_string = "Voltage (mv):";
break;
case IBM_DRCONNECTOR:
- n += sprintf(buf+n, "DR connector:\t");
- n += sprintf(buf+n, "%s\t", ibm_drconnector[state]);
- have_strings = 1;
+ label_string = "DR connector:";
+ value_arrsize = sizeof(ibm_drconnector)/sizeof(char *);
+ value_arr = ibm_drconnector;
break;
case IBM_POWERSUPPLY:
- n += sprintf(buf+n, "Powersupply:\t");
+ label_string = "Powersupply:";
break;
case IBM_INTQUEUE:
- n += sprintf(buf+n, "Interrupt queue:\t");
- n += sprintf(buf+n, "%s\t", ibm_intqueue[state]);
- have_strings = 1;
+ label_string = "Interrupt queue:";
+ value_arrsize = sizeof(ibm_intqueue)/sizeof(char *);
+ value_arr = ibm_intqueue;
break;
default:
n += sprintf(buf+n, "Unkown sensor (type %d), ignoring it\n",
s.token);
unknown = 1;
- have_strings = 1;
break;
}
- if (have_strings == 0) {
+
+ if (label_string)
+ n += sprintf(buf+n, "%-17s\t", label_string);
+
+ if (value_arr && state >= 0 && state < value_arrsize) {
+ n += sprintf(buf+n, "%-15s\t", value_arr[state]);
+ } else {
if (temperature) {
- n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state));
+ n += sprintf(buf+n, "%2d / %2d \t", state, cel_to_fahr(state));
} else
- n += sprintf(buf+n, "%10d\t", state);
+ n += sprintf(buf+n, "%-10d\t", state);
}
if (unknown == 0) {
- n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error));
+ n += sprintf ( buf+n, "%-15s\t", ppc_rtas_process_error(error));
n += get_location_code(s, buf+n);
}
return n;
@@ -751,7 +834,7 @@
n += check_location_string(ret, buffer + n);
n += sprintf ( buffer+n, " ");
/* see how many characters we have printed */
- sprintf ( t, "%s ", ret);
+ snprintf( t, 50, "%s ", ret);
pos += strlen(t);
if (pos >= llen) pos=0;
@@ -764,17 +847,25 @@
static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
+ char stkbuf[40]; /* its small, its on stack */
unsigned long freq;
char *dest;
int error;
- freq = simple_strtoul(buf, &dest, 10);
+
+ if (39 < count)
+ count = 39;
+ if (copy_from_user(stkbuf, buf, count))
+ return -EFAULT;
+
+ stkbuf[count] = 0;
+ freq = simple_strtoul(stkbuf, &dest, 10);
if (*dest != '\0' && *dest != '\n') {
printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n");
return count;
}
if (freq < 0) freq = 0;
rtas_tone_frequency = freq; /* save it for later */
- error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL,
+ error = rtas_call(set_indicator, 3, 1, NULL,
TONE_FREQUENCY, 0, freq);
if (error != 0)
printk(KERN_WARNING "error: setting tone frequency returned: %s\n",
@@ -785,15 +876,21 @@
static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
- int n;
- n = sprintf(buf, "%lu\n", rtas_tone_frequency);
+ int n, sn;
+ char stkbuf[40]; /* its small, its on stack */
+
+ n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_frequency);
- if (*ppos >= strlen(buf))
+ sn = strlen(stkbuf) +1;
+ if (*ppos >= sn)
return 0;
- if (n > strlen(buf) - *ppos)
- n = strlen(buf) - *ppos;
+ if (n > sn - *ppos)
+ n = sn - *ppos;
if (n > count)
n = count;
+ if (copy_to_user(buf, stkbuf + (*ppos), n))
+ return -EFAULT;
+
*ppos += n;
return n;
}
@@ -803,10 +900,18 @@
static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
+ char stkbuf[40]; /* its small, its on stack */
unsigned long volume;
char *dest;
int error;
- volume = simple_strtoul(buf, &dest, 10);
+
+ if (39 < count)
+ count = 39;
+ if (copy_from_user(stkbuf, buf, count))
+ return -EFAULT;
+
+ stkbuf[count] = 0;
+ volume = simple_strtoul(stkbuf, &dest, 10);
if (*dest != '\0' && *dest != '\n') {
printk("ppc_rtas_tone_volume_write: Invalid tone volume\n");
return count;
@@ -815,7 +920,7 @@
if (volume > 100) volume = 100;
rtas_tone_volume = volume; /* save it for later */
- error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL,
+ error = rtas_call(set_indicator, 3, 1, NULL,
TONE_VOLUME, 0, volume);
if (error != 0)
printk(KERN_WARNING "error: setting tone volume returned: %s\n",
@@ -826,15 +931,20 @@
static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
- int n;
- n = sprintf(buf, "%lu\n", rtas_tone_volume);
+ int n, sn;
+ char stkbuf[40]; /* its small, its on stack */
- if (*ppos >= strlen(buf))
+ n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_volume);
+ sn = strlen(stkbuf) +1;
+ if (*ppos >= sn)
return 0;
- if (n > strlen(buf) - *ppos)
- n = strlen(buf) - *ppos;
+ if (n > sn - *ppos)
+ n = sn - *ppos;
if (n > count)
n = count;
+ if (copy_to_user(buf, stkbuf + (*ppos), n))
+ return -EFAULT;
+
*ppos += n;
return n;
}
@@ -864,7 +974,7 @@
static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
-
+ char * tmpbuf;
char * ei_token;
char * workspace = NULL;
size_t max_len;
@@ -878,16 +988,26 @@
max_len = ERRINJCT_TOKEN_LEN;
}
- token_len = strnlen(buf, max_len);
+ tmpbuf = (char *) kmalloc(max_len, GFP_KERNEL);
+ if (!tmpbuf) {
+ printk(KERN_WARNING "error: kmalloc failed\n");
+ return -ENOMEM;
+ }
+ if (copy_from_user (tmpbuf, buf, max_len)) {
+ kfree(tmpbuf);
+ return -EFAULT;
+ }
+ token_len = strnlen(tmpbuf, max_len);
token_len++; /* Add one for the null termination */
ei_token = (char *)kmalloc(token_len, GFP_KERNEL);
if (!ei_token) {
printk(KERN_WARNING "error: kmalloc failed\n");
+ kfree(tmpbuf);
return -ENOMEM;
}
- strncpy(ei_token, buf, token_len);
+ strncpy(ei_token, tmpbuf, token_len);
if (count > token_len + WORKSPACE_SIZE) {
count = token_len + WORKSPACE_SIZE;
@@ -907,11 +1027,12 @@
workspace = (char *)kmalloc(max_len, GFP_KERNEL);
if (!workspace) {
printk(KERN_WARNING "error: failed kmalloc\n");
+ kfree(tmpbuf);
kfree(ei_token);
return -ENOMEM;
}
- memcpy(workspace, buf, max_len);
+ memcpy(workspace, tmpbuf, max_len);
}
rc = rtas_errinjct(open_token, ei_token, workspace);
@@ -920,6 +1041,7 @@
kfree(workspace);
}
kfree(ei_token);
+ kfree(tmpbuf);
return rc < 0 ? rc : count;
}
@@ -940,32 +1062,36 @@
size_t count, loff_t *ppos)
{
char * buffer;
- int i;
+ int i, sn;
int n = 0;
- buffer = (char *)kmalloc(MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1),
- GFP_KERNEL);
+ int m = MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1);
+ buffer = (char *)kmalloc(m, GFP_KERNEL);
if (!buffer) {
printk(KERN_ERR "error: kmalloc failed\n");
return -ENOMEM;
}
for (i = 0; i < MAX_ERRINJCT_TOKENS && ei_token_list[i].value; i++) {
- n += sprintf(buffer+n, ei_token_list[i].name);
- n += sprintf(buffer+n, "\n");
+ n += snprintf(buffer+n, m-n, ei_token_list[i].name);
+ n += snprintf(buffer+n, m-n, "\n");
}
- if (*ppos >= strlen(buffer)) {
+ sn = strlen(buffer) +1;
+ if (*ppos >= sn) {
kfree(buffer);
return 0;
}
- if (n > strlen(buffer) - *ppos)
- n = strlen(buffer) - *ppos;
+ if (n > sn - *ppos)
+ n = sn - *ppos;
if (n > count)
n = count;
- memcpy(buf, buffer + *ppos, n);
+ if (copy_to_user(buf, buffer + *ppos, n)) {
+ kfree(buffer);
+ return -EFAULT;
+ }
*ppos += n;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)