Skip to content

Commit ea81e27

Browse files
committed
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6: [S390] cio: allow offline processing for disconnected devices [S390] cio: handle ssch() return codes correctly. [S390] cio: Correct cleanup on error. [S390] CVE-2008-1514: prevent ptrace padding area read/write in 31-bit mode
2 parents 0b1fc33 + b301ea8 commit ea81e27

File tree

6 files changed

+61
-18
lines changed

6 files changed

+61
-18
lines changed

arch/s390/kernel/compat_ptrace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct user_regs_struct32
4242
u32 gprs[NUM_GPRS];
4343
u32 acrs[NUM_ACRS];
4444
u32 orig_gpr2;
45+
/* nb: there's a 4-byte hole here */
4546
s390_fp_regs fp_regs;
4647
/*
4748
* These per registers are in here so that gdb can modify them

arch/s390/kernel/ptrace.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
170170
*/
171171
tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
172172

173+
} else if (addr < (addr_t) &dummy->regs.fp_regs) {
174+
/*
175+
* prevent reads of padding hole between
176+
* orig_gpr2 and fp_regs on s390.
177+
*/
178+
tmp = 0;
179+
173180
} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
174181
/*
175182
* floating point regs. are stored in the thread structure
@@ -270,6 +277,13 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
270277
*/
271278
task_pt_regs(child)->orig_gpr2 = data;
272279

280+
} else if (addr < (addr_t) &dummy->regs.fp_regs) {
281+
/*
282+
* prevent writes of padding hole between
283+
* orig_gpr2 and fp_regs on s390.
284+
*/
285+
return 0;
286+
273287
} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
274288
/*
275289
* floating point regs. are stored in the thread structure
@@ -428,6 +442,13 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
428442
*/
429443
tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
430444

445+
} else if (addr < (addr_t) &dummy32->regs.fp_regs) {
446+
/*
447+
* prevent reads of padding hole between
448+
* orig_gpr2 and fp_regs on s390.
449+
*/
450+
tmp = 0;
451+
431452
} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
432453
/*
433454
* floating point regs. are stored in the thread structure
@@ -514,6 +535,13 @@ static int __poke_user_compat(struct task_struct *child,
514535
*/
515536
*(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
516537

538+
} else if (addr < (addr_t) &dummy32->regs.fp_regs) {
539+
/*
540+
* prevent writess of padding hole between
541+
* orig_gpr2 and fp_regs on s390.
542+
*/
543+
return 0;
544+
517545
} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
518546
/*
519547
* floating point regs. are stored in the thread structure

drivers/s390/cio/chp.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ int chp_new(struct chp_id chpid)
423423
ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group);
424424
if (ret) {
425425
device_unregister(&chp->dev);
426-
goto out_free;
426+
goto out;
427427
}
428428
mutex_lock(&channel_subsystems[chpid.cssid]->mutex);
429429
if (channel_subsystems[chpid.cssid]->cm_enabled) {
@@ -432,14 +432,15 @@ int chp_new(struct chp_id chpid)
432432
sysfs_remove_group(&chp->dev.kobj, &chp_attr_group);
433433
device_unregister(&chp->dev);
434434
mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
435-
goto out_free;
435+
goto out;
436436
}
437437
}
438438
channel_subsystems[chpid.cssid]->chps[chpid.id] = chp;
439439
mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
440-
return ret;
440+
goto out;
441441
out_free:
442442
kfree(chp);
443+
out:
443444
return ret;
444445
}
445446

drivers/s390/cio/cio.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,10 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
208208
case 1: /* status pending */
209209
case 2: /* busy */
210210
return -EBUSY;
211-
default: /* device/path not operational */
211+
case 3: /* device/path not operational */
212212
return cio_start_handle_notoper(sch, lpm);
213+
default:
214+
return ccode;
213215
}
214216
}
215217

drivers/s390/cio/css.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,11 @@ channel_subsystem_release(struct device *dev)
633633

634634
css = to_css(dev);
635635
mutex_destroy(&css->mutex);
636+
if (css->pseudo_subchannel) {
637+
/* Implies that it has been generated but never registered. */
638+
css_subchannel_release(&css->pseudo_subchannel->dev);
639+
css->pseudo_subchannel = NULL;
640+
}
636641
kfree(css);
637642
}
638643

@@ -785,11 +790,15 @@ init_channel_subsystem (void)
785790
}
786791
channel_subsystems[i] = css;
787792
ret = setup_css(i);
788-
if (ret)
789-
goto out_free;
793+
if (ret) {
794+
kfree(channel_subsystems[i]);
795+
goto out_unregister;
796+
}
790797
ret = device_register(&css->device);
791-
if (ret)
792-
goto out_free_all;
798+
if (ret) {
799+
put_device(&css->device);
800+
goto out_unregister;
801+
}
793802
if (css_chsc_characteristics.secm) {
794803
ret = device_create_file(&css->device,
795804
&dev_attr_cm_enable);
@@ -802,33 +811,28 @@ init_channel_subsystem (void)
802811
}
803812
ret = register_reboot_notifier(&css_reboot_notifier);
804813
if (ret)
805-
goto out_pseudo;
814+
goto out_unregister;
806815
css_init_done = 1;
807816

808817
/* Enable default isc for I/O subchannels. */
809818
isc_register(IO_SCH_ISC);
810819

811820
for_each_subchannel(__init_channel_subsystem, NULL);
812821
return 0;
813-
out_pseudo:
814-
device_unregister(&channel_subsystems[i]->pseudo_subchannel->dev);
815822
out_file:
816-
device_remove_file(&channel_subsystems[i]->device,
817-
&dev_attr_cm_enable);
823+
if (css_chsc_characteristics.secm)
824+
device_remove_file(&channel_subsystems[i]->device,
825+
&dev_attr_cm_enable);
818826
out_device:
819827
device_unregister(&channel_subsystems[i]->device);
820-
out_free_all:
821-
kfree(channel_subsystems[i]->pseudo_subchannel->lock);
822-
kfree(channel_subsystems[i]->pseudo_subchannel);
823-
out_free:
824-
kfree(channel_subsystems[i]);
825828
out_unregister:
826829
while (i > 0) {
827830
struct channel_subsystem *css;
828831

829832
i--;
830833
css = channel_subsystems[i];
831834
device_unregister(&css->pseudo_subchannel->dev);
835+
css->pseudo_subchannel = NULL;
832836
if (css_chsc_characteristics.secm)
833837
device_remove_file(&css->device,
834838
&dev_attr_cm_enable);

drivers/s390/cio/device_fsm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,13 @@ ccw_device_offline(struct ccw_device *cdev)
658658
{
659659
struct subchannel *sch;
660660

661+
/* Allow ccw_device_offline while disconnected. */
662+
if (cdev->private->state == DEV_STATE_DISCONNECTED ||
663+
cdev->private->state == DEV_STATE_NOT_OPER) {
664+
cdev->private->flags.donotify = 0;
665+
ccw_device_done(cdev, DEV_STATE_NOT_OPER);
666+
return 0;
667+
}
661668
if (ccw_device_is_orphan(cdev)) {
662669
ccw_device_done(cdev, DEV_STATE_OFFLINE);
663670
return 0;

0 commit comments

Comments
 (0)