From 6f3e65b6f53547a0f19f89728c7113f6de724b35 Mon Sep 17 00:00:00 2001 From: diego Date: Tue, 11 May 2010 11:10:28 +0000 Subject: libdvdcss: Fix potential format string crash; check RPC status on disc access. This merges upstream revisions 223 and 224 + 225. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31157 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libdvdcss/css.c | 58 +++++++++++++++++++++++++++++++++++++++++++++------ libdvdcss/libdvdcss.c | 15 ++++++++----- 2 files changed, 62 insertions(+), 11 deletions(-) (limited to 'libdvdcss') diff --git a/libdvdcss/css.c b/libdvdcss/css.c index 4ba4f66e43..2bb4f18833 100644 --- a/libdvdcss/css.c +++ b/libdvdcss/css.c @@ -89,10 +89,19 @@ static int AttackPadding ( uint8_t const[], int, uint8_t * ); /***************************************************************************** * _dvdcss_test: check if the disc is encrypted or not + ***************************************************************************** + * Return values: + * 1: DVD is scrambled but can be read + * 0: DVD is not scrambled and can be read + * -1: could not get "copyright" information + * -2: could not get RPC information (reading the disc might be possible) + * -3: drive is RPC-II, region is not set, and DVD is scrambled: the RPC + * scheme will prevent us from reading the scrambled data *****************************************************************************/ int _dvdcss_test( dvdcss_t dvdcss ) { - int i_ret, i_copyright; + char const *psz_type, *psz_rpc; + int i_ret, i_copyright, i_type, i_mask, i_rpc; i_ret = ioctl_ReadCopyright( dvdcss->i_fd, 0 /* i_layer */, &i_copyright ); @@ -115,14 +124,51 @@ int _dvdcss_test( dvdcss_t dvdcss ) if( i_ret < 0 ) { /* Since it's the first ioctl we try to issue, we add a notice */ - print_error( dvdcss, "css error: ioctl_ReadCopyright failed, " - "make sure there is a DVD in the drive, and that " - "you have used the correct device node." ); + print_error( dvdcss, "css error: could not get \"copyright\"" + " information, make sure there is a DVD in the drive," + " and that you have used the correct device node." ); + + return -1; + } + + print_debug( dvdcss, "disc reports copyright information 0x%x", + i_copyright ); + + i_ret = ioctl_ReportRPC( dvdcss->i_fd, &i_type, &i_mask, &i_rpc); + + if( i_ret < 0 ) + { + print_error( dvdcss, "css error: could not get RPC status" ); + return -2; + } - return i_ret; + switch( i_rpc ) + { + case 0: psz_rpc = "RPC-I"; break; + case 1: psz_rpc = "RPC-II"; break; + default: psz_rpc = "unknown RPC scheme"; break; + } + + switch( i_type ) + { + case 0: psz_type = "no region code set"; break; + case 1: psz_type = "region code set"; break; + case 2: psz_type = "one region change remaining"; break; + case 3: psz_type = "region code set permanently"; break; + default: psz_type = "unknown status"; break; + } + + print_debug( dvdcss, "drive region mask %x, %s, %s", + i_mask, psz_rpc, psz_type ); + + if( i_copyright && i_rpc == 1 && i_type == 0 ) + { + print_error( dvdcss, "css error: drive will prevent access to " + "scrambled data" ); + return -3; } - return i_copyright; + return i_copyright ? 1 : 0; } /***************************************************************************** diff --git a/libdvdcss/libdvdcss.c b/libdvdcss/libdvdcss.c index d189faddf2..f39d7025d4 100644 --- a/libdvdcss/libdvdcss.c +++ b/libdvdcss/libdvdcss.c @@ -367,7 +367,14 @@ LIBDVDCSS_EXPORT dvdcss_t dvdcss_open ( char *psz_target ) if( dvdcss->b_ioctls ) { i_ret = _dvdcss_test( dvdcss ); - if( i_ret < 0 ) + if( i_ret == -2 ) + { + /* Scrambled disk, RPC-II drive, no region set: bail out */ + free( dvdcss->psz_device ); + free( dvdcss ); + return NULL; + } + else if( i_ret < 0 ) { /* Disable the CSS ioctls and hope that it works? */ print_debug( dvdcss, @@ -420,7 +427,6 @@ LIBDVDCSS_EXPORT dvdcss_t dvdcss_open ( char *psz_target ) if( psz_cache ) { uint8_t p_sector[DVDCSS_BLOCK_SIZE]; - char psz_debug[PATH_MAX + 30]; char psz_key[1 + KEY_SIZE * 2 + 1]; char *psz_title; uint8_t *psz_serial; @@ -548,9 +554,8 @@ LIBDVDCSS_EXPORT dvdcss_t dvdcss_open ( char *psz_target ) /* Pointer to the filename we will use. */ dvdcss->psz_block = dvdcss->psz_cachefile + i; - sprintf( psz_debug, "using CSS key cache dir: %s", - dvdcss->psz_cachefile ); - print_debug( dvdcss, psz_debug ); + print_debug( dvdcss, "using CSS key cache dir: %s", + dvdcss->psz_cachefile ); } nocache: -- cgit v1.2.3