Archivo para la categoría ‘Software’

[VU#649219] Vulnerabilidad de Escalada de Privilegios en SO de 64 bits bajo CPU Intel con llamada SYSRET

Lunes, junio 25th, 2012

O algo así. Esta noticia es un poco vieja, pero me pareció bastante interesante como para escribirlo aquí.

Vamos, que el US-CERT (United States Computer Emergency Readiness Team) ha publicado información sobre una vulnerabilidad bastante curiosa: en máquinas Intel de 64 bits (vamos, vuestros flamantes Core i7) se puede realizar un ataque de escalada de privilegios acojonante.

Porque si sois lo suficientemente paranoicos, tendreis una máquina virtual para realizar pruebas de software o cualquier tontería que se os ocurra. Pero con un ataque como este, si alguien comprometiese vuestra máquina vritual, tendrían acceso en modo kernel a vuestro sistema operativo host!

El vector de ataque es bastante sencillo de explicar (aunque luego habría que ensamblarlo en el x86) pero la cosa es:

  1. Se produce un marco de la pila (stack frame) para que lo ejecute el Ring#0 (nivel más alto en la CPU) después de una excepción de protección (#GP).
  2. Se produce esa excepción.
  3. El fallo se manejará antes del cambio de contexto, con lo que el manejador para la excepción se ejecutará efectivamente en el Ring0 con las instrucciones que haya requerido el atacante, causando una escalada de privilegios.
Por supuesto, Intel dice que esta vulnerabilidad es un defecto de implementación en el software, pues sus chips funcionan exactamente tal y como está especificado. Esto es, software que no haya tenido en cuenta (o no haya tenido acceso) a la documentación concerniente al comportamiento específico de Intel de SYSRET, puede ser vulnerable.
Pero entonces Intel está reconociendo que SYSRET tiene un comportamiento distinto en su silicon de lo que dice simplemente el estándar x86.
AMD por su parte ha comunicado que sus chips no son vulnerables a este vector de ataque, pues el comportamiento de SYSRET es no generar un #GP mientras está en el Ring#0.
Xen, Citrix, Microsoft y demás ya han tomado o están tomando medidas. Xen ya tiene parches para su hipervisor, aunque a saber cuántas VPS a día de hoy funcionan con Xen y todavía no han sido parcheadas.
Por su parte VMware ha dicho como un campeón que ellos no están afectados: su hipervisor no usa la llamada SYSRET.

Fuente y más información: http://www.kb.cert.org/vuls/id/649219

Git y svn (Tutorial básico)

Sábado, enero 8th, 2011

He aquí un post bastante técnico. Para ver el “cómo hacerlo funcionar ya”, id hasta el final ;)

Ahora están bastante de moda los sistemas de control de versiones distribuidos, como Git, Mercurial y Bazaar.

No obstante, muchos de nosotros trabajamos en proyectos que, por unas circusntancias u otras utilizan sistemas de control de versiones centralizados.

En mi caso, en la Facultad de Informática de A Coruña tenemos montado un repositorio svn para algunas asignaturas.

SVN “está bien” (según sus defensores), pero según mi humilde opinión, Git lo supera por mucho en bastantes cosas. La primera, que es descentralizado.
He comenzado utilizando Git y por tanto no sé cómo podría hacerse lo que voy a decir con Mercurial o Bazaar; pero esto va a ser, a partir de aquí, un pequeño tutorial de como utilizar git, y como utilizar git con un repositorio svn. Esto está enfocado a sistemas POSIX, aunque la mayor parte es aplicable a la instalación de Git para Windows.

Aviso: Todos los comandos de git tienen entrada en el Manual, y muy buena; a diferencia de los comandos de Subversion, que solo te dicen que si quieres algo vayas a su web.

Para ver la documentación de un comando de git, se pueden hacer dos cosas:

  • o bien preguntárselo elegantemente a git: git init --help
  • o bien acceder directamente al manual, así: man git-init (con un guión en el medio)

La documentación de Git se encuentra en la sección 1 del manual.

Update: Vistas ciertas visitas desde Google, añado lo siguiente aquí como referencia rápida

En git es muy común estar haciendo commits continuamente. Porque como son locales, así se puede tener un control más fino de lo que se está cambiando.
Pero normalmente uno no quiere subir todos esos commits como tales a SVN, sino en su lugar, subir uno con el contenido ya hecho y funcional.

Esto puede lograrse del siguiente modo:

git branch miRamaDesarrollo
# Hacemos cambios al código..
git commit -m “Cambios triviales”
# Más cambios..
git commit -m “Mi gato me ha dado una idea genial para esto”
# Más cambios..
git commit -m “Seguro que ahora ya funciona”

Y cuando todo esté finalizado, para subirlo a SVN, cambiar a la rama master (o a donde lleves tus commits de SVN) y hacer:

git checkout master
git merge –squash miRamaDesarrollo

Esto crea un estado en el INDEX equivalente a hacer un merge de miRamaDesarrollo en master, pero sin hacer el merge, ni actualizar master. En este momento, se puede hacer un git commit para realmente generar un único commit con todos los cambios conjuntos de miRamaDesarrollo.
Luego, un git svn dcommit soluciona la tarea de enviar ese único commit.

Recordad, antes de volver a trabajar en la rama de desarrollo, hacer un git rebase master, para no generar un octopus.

Comandos básicos de Git

git init [-q] [--bare] [--shared=[<permissions>]] [directory]
Crea un repositorio vacío o reinicializa uno que ya exista. Lista de parámetros:

–bare
Crea un repositorio desnudo. Es decir, sin working tree.

Con SVN no vamos a utilizar este comando.

git add [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p] [--edit | -e] [--all | [--update | -u ]] [--intent-to-add | -N] [--refresh] [--ignore-erors] [--ignore-missing] [--] [<filepattern>...]
Este comando, con la cantidad de flags opcionales que tiene, actualiza el index utilizando el contenido actual del working tree para preparar el contenido en fase de ser versionado.Podeis ver todo lo que se añade y cómo funciona en la págian de manual (puede estar en inglés).

Generalmente se utilizará como git add <files>

git commit [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run] [(-c | -C) <commit>] [-F <file> | -m <msg>] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--status | --no-status] [--] [[-i | -o]<file>…]

Envía los contenidos del index a un nuevo commit, junto con un mensaje de log con el que el usuario describe los cambios.

El contenido a enviar puede especificarse de los siguientes modos:

  1. utilizando git add para añadir incrementalmente cambios al index antes de utilizar el comando commit (Nota: los archivos modificados deben ser añadidos explícitamente)
  2. utilizando git rm para eliminar archivos del working tree y del index, de nuevo, antes de utilizar el comando commit
  3. listando ficheros como argumentos al comando commit, en cuyo caso el commit ignorará los cambios del index y en su lugar grabará como contenido únicamente los cambios que ocurriesen en los ficheros pasados por parámetro y que ya deben ser conocidos para git (es decir, existían en el commit anterior)
  4. utilizando el switch -a con el comando commit para añadir automáticamente todos los cambios de los archivos ya conocidos (i.e., todos los archivos que están listados en el index) y para borrar automáticamente en el index todos los ficheros que hayan sido borrados del working tree, realizando inmediatamente el commit. (Este es el funcionamiento más parecido a svn commit)
  5. utilizando el switch --interactive con el comando commit para decidir uno a uno, qué archivos deberían ser parte del próximo commit, antes de finalizar la operación. Actualmente esto se implementa llamando primero a git add --interactive.

Si haces un commit y encuentras un error en lo que hiciste inmediatamente después, puedes recuperarlo utilizando git reset.

Podeis ver la lista de opciones en el manual, pero yo querría destacar --amend que nos permite editar el mensaje de log del último commit. Esto no debe hacerse jamás con un commit que haya sido subido (y posiblemente descargado por otra persona), o subido a un svn; pero mientras sean tus cambios privados, git te permite cambiar el log sin problema ninguno. Nota: Esto cambia el CommitID (un registro interno de Git que dice qué commit es padre de cuál).

git mv; git rm
Permiten mover y borrar ficheros. Lo mejor de utilizar esto en lugar de los comandos de las Coreutils, mv y rm es que el cambio se incluye automáticamente en el index. Además git rm permite opciones como [-f | --force] [-n] [-r] [--cached] [--ignore-unmatched] [--quiet]
git fetch
Probablemente no tengais que utilizar esta opción directamente. Se usa para bajarse objetos de un repositorio Git. Pero suele ser más útil que Git lo utilice dentro de comandos como git merge y git rebase
git rebase [-i | --interactive] [options] [--onto <newbase>] &lt:upstream> [<branch>]
git rebase –continue | –skip | –abort

git rebase <base> cambia el commit padre del conjunto de commits nuevos para que sea <base>. Se ve mejor en el ejemplo del manual; digamos que sirve para mantener la “raíz” de tu conjunto de cambios actualizada, si alguien hace un cambio por el medio.

Si la nueva base incluye cambios en ficheros que tú también has modificado habrá que resolver los conflictos antes de terminar. Hay un ejemplo de cómo en el manual. Cuando se haya resuelto un conflicto, git rebase --continue permite seguir con el proceso de rebase. Si uno no quiere tener que resolver conflictos, puede abortar el proceso con git rebase --abort

git merge [-n] [--stat] [--no-commit] [--squash] [-s &t;strategy>] [-X <strategy-option>] [--[no-]-rererere-autoupdate] [-m <msg>] <commit>…
git merge <msg> HAD <commit>…
Incorpora los cambios de un commit con nombre (generalmente una rama) en la rama actual. Se puede crear lo que se llama un “metacommit de mezcla” (merge commit) indicando cuáles eran los padres del commit mezclado
Son intersantes las siguientes opciones:

–commit, –no-commit
Hacer o no, directamente el commit cuando acabe de mezclar las ramas.
–ff, –no-ff
No genera un commit de mezcla si esta puede resolverse como un fast-forward (avance simple en la historia), solo actualiza el puntero de rama para que apunte al último commit. Este es el comportamiento por defecto.
Con –no–ff se genera un commit de mezcla aunque se pudiese resolver como un fast-forward.
–squash
Recrea el working tree y el estado del index como si hubiese ocurrido un merge real, pero no hace el commit, ni mueve HEAD, ni hace que el siguiente comando de git commit cree un commit de mezcla. Esto permite crear un único commit sobre la rama actual cuyo efecto es equivalente a mezclar la otra rama.
–ff-only
Evita mezclas a menos que HEAD esté actualizado o el merge se pueda resolver como un fast-forward.

Comprobaciones anteriores a la mezcla

Antes de aplicar cambios externios, deberías de comprobar que tu trabajo es correcto y se le ha hecho un commit, para que así no ocurran cosas extrañas si hay conflictos.

git log [<options>] [<since>..<until>] [[--] <path>…]
Muestra los logs de uno o más commits. Por ejemplo, git log HEAD~4 muestra todos los cambios desde hace cuatro commits hasta los cambios locales que aún no se han enviado. git log HEAD~4..HEAD muestra los cambios desde hace cuatro commits hasta el último, desechando lo que haya ocurrido ahora en el working tree.
git status [<options>...] [--] [<pathspec>...]
Muestra las rutas que tengan cambios entr el index y el HEAD, rutas que tengan cambios entre el working tree y el index, y rutas en el working tree que no están siendo seguidas por git y tampoco siendo ignoradas por gitignore.
git checkout
Actualiza los ficheros del working tree para que coincidan con la versión del index o del árbol especificado. Típicamente, git checkout actualizará HEAD para poner la rama especificada como rama actual. Tip: Utilizar git checkout -b <rama> crea una rama nueva y la especifica como rama actual. Es equivalente a hacer git branch <rama> && git checkout <rama>
git branch
Lista, crea y borra ramas.
Sin argumentos, lista las ramas del repositorio, siendo la actual la que tiene un asterisco.
Especificando un nombre de rama (que no exista) creará la rama pero no la pondrá como rama actual. Para ello hay que utilizar git checkout.
-m y -M sirven para modificar el nombre de una rama, y -d para borrarla (si ha sido integrada completamente en la rama de la que se creó, o si no hay rama upstream).
-D permite borrar una rama que no haya sido integrada (úsese con precaución!)

Comandos básicos, más o menos ya están. Ahora faltan aquellos que permiten interactuar con SVN.
Si ya habeis utilizado Git en un pasado, no podreis utilizar git push y git pull, pues estos trabajan con repositorios Git, y no está recomendado pasar datos entre repositorios git descentralizadamente, según el manual. El modo recomendado de trabajar es o bien enviar los cambios al svn centralizado o bien utilizando git format-patch y git am.

Comandos para la integración con svn

git svn init [--stdlayout] [--trunk=<trunk_subdir>] [--tags=<tags_subdir>] [--branches=<branches-subdir>] <svn-repo>
Inicializa un repositorio Git a partir de un svn remoto. –stdlayout indica que el repositorio está estructurado con la estructura típica (branches/, tags/, trunk/). Se pueden especificar varias –branches y git las seguirá a todas.
git svn fetch [--localtime] [--parent]
Se baja revisiones nuevas del Subversion remoto que estemos siguiendo.
–localtime guarda los tiempos de los commits de Git en la timezone local en lugar de UTC. Esto hace que git log muestre las mismas fechas que haría svn log para la timezone actual. Esto no interfiere con el repositorio del que has clonado, pero si quieres que tu repositorio pueda interactuar con otro repositorio Git, no deberías utilizar esta opción, o estar ambos en la misma timezone.
git svn rebase
Esto coge revisiones contra el SVN que corresponda con el HEAD actual y hace rebase sobre el contenido del trabajo actual (que aún no se haya subido al SVN) contra las revisiones nuevas.

Esto funciona como svn update o como git pull, si ya has usado git, a excepción de que preserva el historial lineal con git rebase en lugar de git merge para que sea más fácil hacer dcommit con git svn.
al igual que git rebase esto requirere que el working tree esté limpio y no haya cambios sin subir
git svn dcommit
Envía cada cambio directamente al repositorio SVN, y luego hace rebase o reset (según haya un diff entre SVN y la cabeza o no). Esto crea efectivamente una revisión en SVN por cada commit en git. Se puede especificar una revisión o rama, y esto hará que se realice el trabajo como si la cabeza fuese el argumento especificado, en lugar de HEAD.
git reset -r <n> || –revision=<n> [-p | --parent]
Deshace los efectos de fetch hasta la revisión que se especifique. Esto permite volver a hacer fetch de una revisión SVN. Generalmente los contenidos de una revisión de SVN no cambian jamás, y reset no debería ser necesario. Pero si por alguna razón es necesario reparar tu repositorio, el único modo es usar reset.

Todavía tengo que probarlo en profundidad, pero la forma de trabajar debería de ser algo así:

mkdir proyecto
cd proyecto && git svn init https://svn.fic.udc.es/… –stdlayout # tenemos una estructura tags/, branches/, trunk/
git svn fetch –all # cogemos todas las versiones para que git las conozca
git svn rebase # ponemos ‘master’ a la última revisión del svn

git checkout -b mitrabajo # creamos una rama distinta para trabajar en ella
### Trabajamos…
# hacemos incluso algún git commit en la rama mitrabajo para ir versionando cosas…

git checkout master # volvemos a la rama ‘master’ (que por defecto contiene el trunk/)
git svn rebase # comprobamos que no haya más cambios
# mezclamos los nuestros en master

git merge –ff-only –squash mitrabajo # squash mezcla todo el trabajo que hayamos hecho en un único commit
git commit # actualizamos nuestro ‘master’
git svn dcommit # subir los cambios de master al svn

#opcionalmente,
# o bien:

git branch -d mitrabajo # borramos la rama
# o bien la actualizamos con lo que tiene master
git checkout mitrabajo && git merge master
# o bien le hacemos rebase, así
git checkout mitrabajo
git reset –hard master # reseteamos la rama mitrabajo al último commit que hay en master

# Actualizamos el Trac del proyecto
bash sync.sh

LudusParty 2010

Martes, noviembre 30th, 2010

Con una página web que mea sobre la de la Arroutada, por ejemplo (y probablemente muchas más), y con una gente que son mucho más genial que la Asociación AMIGA; la LudusParty 2010 es un evento cultural y de ocio a una escala… en otro orden de magnitud respecto a eventos como la Arroutada (de la que hablo en el post anterior).

Después de un año sabático, por falta de presupuesto por parte del Concello de Lugo (en cuyo blog hubo censurados muchos comentarios), vuelve la LudusParty a hacerse realidad. Este año en la Casa do Deporte, un lugar algo más pequeño, y con una organización un poco diferente.
Por motivos que este bloguero solo sabe en parte, está la Asociación AMIGA (los de la Arroutada) manteniendo la Red, supervisados en todo momento por los organizadores reales del asunto: la compañía Inteligencia Visual.
Estos últimos son unos chicos que trabajan muy bien, aunque si estuviesen mejor rodeados podría dar todavía más de si la Party (véase hace dos años, cuando fueron los de la Euskal los que se contrataron).

Hubo un par de cosas que tal vez habría que mejorar, como que hubiese siempre una máquina de café con café cargado y cafeinado, pero un evento destacable.

La red la proporcionó Telefónica, no se cayó nunca, la LAN tampoco, no llovió, hizo una temperatura bastante agradable (la primera noche 17ºC en el interior, y desde que los cañones de calor caldearon el ambiente siempre entre 20 y 21ºC) (cosa que en la Arroutada no pasó: y que además estaba la puerta abierta para que hiciese frío).

Conocí a Sahib en persona, a quien ya seguía en Twitter, y vi a mucha gente que apenas veo habitualmente…

En resumen, fue una experiencia grata de nuevo, casi como en 2008 que, para mi, hasta ahora fue la mejor edición.

Os dejo un enlace al hilo del foro oficial de “Opinión de la Ludus 2010″, lo mejor y peor, y a la foto de familia: